summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp10
-rw-r--r--src/video_core/shader/glsl_decompiler.cpp7
-rw-r--r--src/video_core/shader/shader_ir.cpp2
-rw-r--r--src/video_core/shader/shader_ir.h4
4 files changed, 22 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index b12dc5ba8..271ce205b 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/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: {
diff --git a/src/video_core/shader/glsl_decompiler.cpp b/src/video_core/shader/glsl_decompiler.cpp
index b93ea9ec6..1aff62882 100644
--- a/src/video_core/shader/glsl_decompiler.cpp
+++ b/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>,
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 1f39dc6d0..1fc838d15 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/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:
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 231f58f6a..ccdf316ac 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/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