summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-08-26 13:58:45 -0700
committerPokechu22 <Pokechu022@gmail.com>2021-11-17 20:04:33 -0800
commitd2041b4c2a8562073ab905e2aea3b05c678aa962 (patch)
treeceaf1bbc79e519a3b45dd24172d3aeda08eea218 /Source/Core
parent555a93057c07f045cc71c4652c54eebb990021b7 (diff)
VideoCommon: Add signed version of BitfieldExtract
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/BitField.h2
-rw-r--r--Source/Core/VideoCommon/ShaderGenCommon.cpp6
-rw-r--r--Source/Core/VideoCommon/ShaderGenCommon.h3
3 files changed, 10 insertions, 1 deletions
diff --git a/Source/Core/Common/BitField.h b/Source/Core/Common/BitField.h
index 26b3c5e0a4..2f5eba092f 100644
--- a/Source/Core/Common/BitField.h
+++ b/Source/Core/Common/BitField.h
@@ -149,6 +149,7 @@ public:
constexpr T Value() const { return Value(std::is_signed<T>()); }
constexpr operator T() const { return Value(); }
+ static constexpr bool IsSigned() { return std::is_signed<T>(); }
static constexpr std::size_t StartBit() { return position; }
static constexpr std::size_t NumBits() { return bits; }
@@ -244,6 +245,7 @@ public:
BitFieldArray& operator=(const BitFieldArray&) = delete;
public:
+ constexpr bool IsSigned() const { return std::is_signed<T>(); }
constexpr std::size_t StartBit() const { return position; }
constexpr std::size_t NumBits() const { return bits; }
constexpr std::size_t Size() const { return size; }
diff --git a/Source/Core/VideoCommon/ShaderGenCommon.cpp b/Source/Core/VideoCommon/ShaderGenCommon.cpp
index cbc17f0772..72a7e0d14f 100644
--- a/Source/Core/VideoCommon/ShaderGenCommon.cpp
+++ b/Source/Core/VideoCommon/ShaderGenCommon.cpp
@@ -120,6 +120,12 @@ void WriteBitfieldExtractHeader(ShaderCode& out, APIType api_type,
" uint mask = uint((1 << size) - 1);\n"
" return uint(val >> off) & mask;\n"
"}}\n\n");
+ out.Write("int bitfieldExtract(int val, int off, int size) {{\n"
+ " // This built-in function is only supported in OpenGL 4.0+ and ES 3.1+\n"
+ " // Microsoft's HLSL compiler automatically optimises this to a bitfield extract "
+ "instruction.\n"
+ " return ((val << (32 - size - off)) >> (32 - size));\n"
+ "}}\n\n");
}
}
diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h
index f7f27b3073..ebdcda262b 100644
--- a/Source/Core/VideoCommon/ShaderGenCommon.h
+++ b/Source/Core/VideoCommon/ShaderGenCommon.h
@@ -203,7 +203,8 @@ template <auto ptr_to_bitfield_member>
std::string BitfieldExtract(std::string_view source)
{
using BitFieldT = Common::MemberType<ptr_to_bitfield_member>;
- return fmt::format("bitfieldExtract({}, {}, {})", source, static_cast<u32>(BitFieldT::StartBit()),
+ return fmt::format("bitfieldExtract({}({}), {}, {})", BitFieldT::IsSigned() ? "int" : "uint",
+ source, static_cast<u32>(BitFieldT::StartBit()),
static_cast<u32>(BitFieldT::NumBits()));
}