VideoCommon: Add signed version of BitfieldExtract

This commit is contained in:
Pokechu22 2021-08-26 13:58:45 -07:00
parent 555a93057c
commit d2041b4c2a
3 changed files with 10 additions and 1 deletions

View File

@ -149,6 +149,7 @@ public:
constexpr T Value() const { return Value(std::is_signed<T>()); } constexpr T Value() const { return Value(std::is_signed<T>()); }
constexpr operator T() const { return Value(); } 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 StartBit() { return position; }
static constexpr std::size_t NumBits() { return bits; } static constexpr std::size_t NumBits() { return bits; }
@ -244,6 +245,7 @@ public:
BitFieldArray& operator=(const BitFieldArray&) = delete; BitFieldArray& operator=(const BitFieldArray&) = delete;
public: public:
constexpr bool IsSigned() const { return std::is_signed<T>(); }
constexpr std::size_t StartBit() const { return position; } constexpr std::size_t StartBit() const { return position; }
constexpr std::size_t NumBits() const { return bits; } constexpr std::size_t NumBits() const { return bits; }
constexpr std::size_t Size() const { return size; } constexpr std::size_t Size() const { return size; }

View File

@ -120,6 +120,12 @@ void WriteBitfieldExtractHeader(ShaderCode& out, APIType api_type,
" uint mask = uint((1 << size) - 1);\n" " uint mask = uint((1 << size) - 1);\n"
" return uint(val >> off) & mask;\n" " return uint(val >> off) & mask;\n"
"}}\n\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");
} }
} }

View File

@ -203,7 +203,8 @@ template <auto ptr_to_bitfield_member>
std::string BitfieldExtract(std::string_view source) std::string BitfieldExtract(std::string_view source)
{ {
using BitFieldT = Common::MemberType<ptr_to_bitfield_member>; 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())); static_cast<u32>(BitFieldT::NumBits()));
} }