Procházet zdrojové kódy

shader_decode: Implement POPC

ReinUsesLisp před 7 roky
rodič
revize
027f443e69

+ 10 - 0
src/video_core/shader/decode/arithmetic_integer.cpp

@@ -119,6 +119,16 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) {
         SetRegister(bb, instr.gpr0, value);
         break;
     }
+    case OpCode::Id::POPC_C:
+    case OpCode::Id::POPC_R:
+    case OpCode::Id::POPC_IMM: {
+        if (instr.popc.invert) {
+            op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b);
+        }
+        const Node value = Operation(OperationCode::IBitCount, PRECISE, op_b);
+        SetRegister(bb, instr.gpr0, value);
+        break;
+    }
     case OpCode::Id::SEL_C:
     case OpCode::Id::SEL_R:
     case OpCode::Id::SEL_IMM: {

+ 7 - 0
src/video_core/shader/glsl_decompiler.cpp

@@ -908,6 +908,11 @@ private:
                                   Type::Int);
     }
 
+    template <Type type>
+    std::string BitCount(Operation operation) {
+        return GenerateUnary(operation, "bitCount", type, type, false);
+    }
+
     std::string HNegate(Operation operation) {
         const auto GetNegate = [&](std::size_t index) -> std::string {
             if (const auto pred = std::get_if<PredicateNode>(operation[index])) {
@@ -1273,6 +1278,7 @@ private:
         &BitwiseXor<Type::Int>,
         &BitwiseNot<Type::Int>,
         &BitfieldInsert<Type::Int>,
+        &BitCount<Type::Int>,
 
         &Add<Type::Uint>,
         &Mul<Type::Uint>,
@@ -1289,6 +1295,7 @@ private:
         &BitwiseXor<Type::Uint>,
         &BitwiseNot<Type::Uint>,
         &BitfieldInsert<Type::Uint>,
+        &BitCount<Type::Uint>,
 
         &Add<Type::HalfFloat>,
         &Mul<Type::HalfFloat>,

+ 2 - 0
src/video_core/shader/shader_ir.cpp

@@ -386,6 +386,8 @@ void ShaderIR::SetLocalMemory(BasicBlock& bb, Node address, Node value) {
         return OperationCode::UBitwiseNot;
     case OperationCode::IBitfieldInsert:
         return OperationCode::UBitfieldInsert;
+    case OperationCode::IBitCount:
+        return OperationCode::UBitCount;
     case OperationCode::LogicalILessThan:
         return OperationCode::LogicalULessThan;
     case OperationCode::LogicalIEqual:

+ 3 - 1
src/video_core/shader/shader_ir.h

@@ -89,6 +89,7 @@ enum class OperationCode {
     IBitwiseXor,           /// (MetaArithmetic, int a, int b) -> int
     IBitwiseNot,           /// (MetaArithmetic, int a) -> int
     IBitfieldInsert,       /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
+    IBitCount,             /// (MetaArithmetic, int) -> int
 
     UAdd,                  /// (MetaArithmetic, uint a, uint b) -> uint
     UMul,                  /// (MetaArithmetic, uint a, uint b) -> uint
@@ -103,8 +104,9 @@ enum class OperationCode {
     UBitwiseAnd,           /// (MetaArithmetic, uint a, uint b) -> uint
     UBitwiseOr,            /// (MetaArithmetic, uint a, uint b) -> uint
     UBitwiseXor,           /// (MetaArithmetic, uint a, uint b) -> uint
-    UBitwiseNot,           /// (MetaArithmetic, uint a) -> int
+    UBitwiseNot,           /// (MetaArithmetic, uint a) -> uint
     UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
+    UBitCount,       /// (MetaArithmetic, uint) -> uint
 
     HAdd,      /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
     HMul,      /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2