diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 2 | 
5 files changed, 35 insertions, 0 deletions
| diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index f8d67e227..16f410538 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -800,6 +800,12 @@ union Instruction {      } popc;      union { +        BitField<41, 1, u64> sh; +        BitField<40, 1, u64> invert; +        BitField<48, 1, u64> is_signed; +    } flo; + +    union {          BitField<39, 3, u64> pred;          BitField<42, 1, u64> neg_pred;      } sel; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index e56ed51de..b87ee2ae8 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1472,6 +1472,11 @@ private:          return GenerateUnary(operation, "bitCount", type, type);      } +    template <Type type> +    Expression BitMSB(Operation operation) { +        return GenerateUnary(operation, "findMSB", type, type); +    } +      Expression HNegate(Operation operation) {          const auto GetNegate = [&](std::size_t index) {              return VisitOperand(operation, index).AsBool() + " ? -1 : 1"; @@ -2043,6 +2048,7 @@ private:          &GLSLDecompiler::BitfieldInsert<Type::Int>,          &GLSLDecompiler::BitfieldExtract<Type::Int>,          &GLSLDecompiler::BitCount<Type::Int>, +        &GLSLDecompiler::BitMSB<Type::Int>,          &GLSLDecompiler::Add<Type::Uint>,          &GLSLDecompiler::Mul<Type::Uint>, @@ -2061,6 +2067,7 @@ private:          &GLSLDecompiler::BitfieldInsert<Type::Uint>,          &GLSLDecompiler::BitfieldExtract<Type::Uint>,          &GLSLDecompiler::BitCount<Type::Uint>, +        &GLSLDecompiler::BitMSB<Type::Uint>,          &GLSLDecompiler::Add<Type::HalfFloat>,          &GLSLDecompiler::Mul<Type::HalfFloat>, diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 2850d5b59..8378b35ac 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -1390,6 +1390,7 @@ private:          &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Int>,          &SPIRVDecompiler::Ternary<&Module::OpBitFieldSExtract, Type::Int>,          &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Int>, +        &SPIRVDecompiler::Unary<&Module::OpFindSMsb, Type::Int>,          &SPIRVDecompiler::Binary<&Module::OpIAdd, Type::Uint>,          &SPIRVDecompiler::Binary<&Module::OpIMul, Type::Uint>, @@ -1408,6 +1409,7 @@ private:          &SPIRVDecompiler::Quaternary<&Module::OpBitFieldInsert, Type::Uint>,          &SPIRVDecompiler::Ternary<&Module::OpBitFieldUExtract, Type::Uint>,          &SPIRVDecompiler::Unary<&Module::OpBitCount, Type::Uint>, +        &SPIRVDecompiler::Unary<&Module::OpFindUMsb, Type::Uint>,          &SPIRVDecompiler::Binary<&Module::OpFAdd, Type::HalfFloat>,          &SPIRVDecompiler::Binary<&Module::OpFMul, Type::HalfFloat>, diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index a33d242e9..9208b7bef 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp @@ -130,6 +130,24 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {          SetRegister(bb, instr.gpr0, value);          break;      } +    case OpCode::Id::FLO_R: +    case OpCode::Id::FLO_C: +    case OpCode::Id::FLO_IMM: { +        Node value; +        if (instr.flo.invert) { +            op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b); +        } +        if (instr.flo.is_signed) { +            value = Operation(OperationCode::IBitMSB, NO_PRECISE, op_b); +        } else { +            value = Operation(OperationCode::UBitMSB, NO_PRECISE, op_b); +        } +        if (instr.flo.sh) { +            value = Operation(OperationCode::UBitwiseXor, NO_PRECISE, value, Immediate(31)); +        } +        SetRegister(bb, instr.gpr0, value); +        break; +    }      case OpCode::Id::SEL_C:      case OpCode::Id::SEL_R:      case OpCode::Id::SEL_IMM: { diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 54217e6a4..2d11facaf 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -68,6 +68,7 @@ enum class OperationCode {      IBitfieldInsert,       /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int      IBitfieldExtract,      /// (MetaArithmetic, int value, int offset, int offset) -> int      IBitCount,             /// (MetaArithmetic, int) -> int +    IBitMSB,               /// (MetaArithmetic, int) -> int      UAdd,                  /// (MetaArithmetic, uint a, uint b) -> uint      UMul,                  /// (MetaArithmetic, uint a, uint b) -> uint @@ -86,6 +87,7 @@ enum class OperationCode {      UBitfieldInsert,  /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint      UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint      UBitCount,        /// (MetaArithmetic, uint) -> uint +    UBitMSB,          /// (MetaArithmetic, uint) -> uint      HAdd,       /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2      HMul,       /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 | 
