summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-12-26 02:58:47 -0300
committerGravatar ReinUsesLisp2019-01-15 17:54:53 -0300
commit2faad9bf23dbcedc80dca7ed9ad4b81c0416dd5e (patch)
tree3faa264db225f2ae09ccf417fd962eddb40c2235 /src
parentshader_ir: Remove Ipa primitive (diff)
downloadyuzu-2faad9bf23dbcedc80dca7ed9ad4b81c0416dd5e.tar.gz
yuzu-2faad9bf23dbcedc80dca7ed9ad4b81c0416dd5e.tar.xz
yuzu-2faad9bf23dbcedc80dca7ed9ad4b81c0416dd5e.zip
shader_decode: Use BitfieldExtract instead of shift + and
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp7
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp5
-rw-r--r--src/video_core/shader/decode/bfi.cpp9
-rw-r--r--src/video_core/shader/decode/register_set_predicate.cpp12
-rw-r--r--src/video_core/shader/decode/video.cpp12
-rw-r--r--src/video_core/shader/decode/xmad.cpp26
-rw-r--r--src/video_core/shader/shader_ir.cpp5
-rw-r--r--src/video_core/shader/shader_ir.h9
8 files changed, 37 insertions, 48 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index ecd27db07..60b11df51 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -986,6 +986,11 @@ private:
986 } 986 }
987 987
988 template <Type type> 988 template <Type type>
989 std::string BitfieldExtract(Operation operation) {
990 return GenerateTernary(operation, "bitfieldExtract", type, type, Type::Int, Type::Int);
991 }
992
993 template <Type type>
989 std::string BitCount(Operation operation) { 994 std::string BitCount(Operation operation) {
990 return GenerateUnary(operation, "bitCount", type, type, false); 995 return GenerateUnary(operation, "bitCount", type, type, false);
991 } 996 }
@@ -1369,6 +1374,7 @@ private:
1369 &GLSLDecompiler::BitwiseXor<Type::Int>, 1374 &GLSLDecompiler::BitwiseXor<Type::Int>,
1370 &GLSLDecompiler::BitwiseNot<Type::Int>, 1375 &GLSLDecompiler::BitwiseNot<Type::Int>,
1371 &GLSLDecompiler::BitfieldInsert<Type::Int>, 1376 &GLSLDecompiler::BitfieldInsert<Type::Int>,
1377 &GLSLDecompiler::BitfieldExtract<Type::Int>,
1372 &GLSLDecompiler::BitCount<Type::Int>, 1378 &GLSLDecompiler::BitCount<Type::Int>,
1373 1379
1374 &GLSLDecompiler::Add<Type::Uint>, 1380 &GLSLDecompiler::Add<Type::Uint>,
@@ -1386,6 +1392,7 @@ private:
1386 &GLSLDecompiler::BitwiseXor<Type::Uint>, 1392 &GLSLDecompiler::BitwiseXor<Type::Uint>,
1387 &GLSLDecompiler::BitwiseNot<Type::Uint>, 1393 &GLSLDecompiler::BitwiseNot<Type::Uint>,
1388 &GLSLDecompiler::BitfieldInsert<Type::Uint>, 1394 &GLSLDecompiler::BitfieldInsert<Type::Uint>,
1395 &GLSLDecompiler::BitfieldExtract<Type::Uint>,
1389 &GLSLDecompiler::BitCount<Type::Uint>, 1396 &GLSLDecompiler::BitCount<Type::Uint>,
1390 1397
1391 &GLSLDecompiler::Add<Type::HalfFloat>, 1398 &GLSLDecompiler::Add<Type::HalfFloat>,
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 271ce205b..931e0fa1d 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -57,10 +57,9 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) {
57 case IAdd3Height::None: 57 case IAdd3Height::None:
58 return value; 58 return value;
59 case IAdd3Height::LowerHalfWord: 59 case IAdd3Height::LowerHalfWord:
60 return Operation(OperationCode::IBitwiseAnd, NO_PRECISE, value, Immediate(0xffff)); 60 return BitfieldExtract(value, 0, 16);
61 case IAdd3Height::UpperHalfWord: 61 case IAdd3Height::UpperHalfWord:
62 return Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, value, 62 return BitfieldExtract(value, 16, 16);
63 Immediate(16));
64 default: 63 default:
65 UNIMPLEMENTED_MSG("Unhandled IADD3 height: {}", static_cast<u32>(height)); 64 UNIMPLEMENTED_MSG("Unhandled IADD3 height: {}", static_cast<u32>(height));
66 return Immediate(0); 65 return Immediate(0);
diff --git a/src/video_core/shader/decode/bfi.cpp b/src/video_core/shader/decode/bfi.cpp
index a750aca30..b0d8d9eba 100644
--- a/src/video_core/shader/decode/bfi.cpp
+++ b/src/video_core/shader/decode/bfi.cpp
@@ -28,13 +28,8 @@ u32 ShaderIR::DecodeBfi(BasicBlock& bb, u32 pc) {
28 } 28 }
29 }(); 29 }();
30 const Node insert = GetRegister(instr.gpr8); 30 const Node insert = GetRegister(instr.gpr8);
31 31 const Node offset = BitfieldExtract(packed_shift, 0, 8);
32 const Node offset = 32 const Node bits = BitfieldExtract(packed_shift, 8, 8);
33 Operation(OperationCode::UBitwiseAnd, NO_PRECISE, packed_shift, Immediate(0xff));
34
35 Node bits =
36 Operation(OperationCode::ULogicalShiftRight, NO_PRECISE, packed_shift, Immediate(8));
37 bits = Operation(OperationCode::UBitwiseAnd, NO_PRECISE, bits, Immediate(0xff));
38 33
39 const Node value = 34 const Node value =
40 Operation(OperationCode::UBitfieldInsert, PRECISE, base, insert, offset, bits); 35 Operation(OperationCode::UBitfieldInsert, PRECISE, base, insert, offset, bits);
diff --git a/src/video_core/shader/decode/register_set_predicate.cpp b/src/video_core/shader/decode/register_set_predicate.cpp
index 06a3c7539..14bce9fa4 100644
--- a/src/video_core/shader/decode/register_set_predicate.cpp
+++ b/src/video_core/shader/decode/register_set_predicate.cpp
@@ -27,20 +27,18 @@ u32 ShaderIR::DecodeRegisterSetPredicate(BasicBlock& bb, u32 pc) {
27 return Immediate(static_cast<u32>(instr.r2p.immediate_mask)); 27 return Immediate(static_cast<u32>(instr.r2p.immediate_mask));
28 } 28 }
29 }(); 29 }();
30 const Node mask = 30 const Node mask = GetRegister(instr.gpr8);
31 Operation(OperationCode::ULogicalShiftRight, NO_PRECISE, GetRegister(instr.gpr8), 31 const auto offset = static_cast<u32>(instr.r2p.byte) * 8;
32 Immediate(static_cast<u32>(instr.r2p.byte)));
33 32
34 constexpr u32 programmable_preds = 7; 33 constexpr u32 programmable_preds = 7;
35 for (u64 pred = 0; pred < programmable_preds; ++pred) { 34 for (u64 pred = 0; pred < programmable_preds; ++pred) {
36 const Node shift = Immediate(1u << static_cast<u32>(pred)); 35 const auto shift = static_cast<u32>(pred);
37 36
38 const Node apply_compare = 37 const Node apply_compare = BitfieldExtract(apply_mask, shift, 1);
39 Operation(OperationCode::UBitwiseAnd, NO_PRECISE, apply_mask, shift);
40 const Node condition = 38 const Node condition =
41 Operation(OperationCode::LogicalUNotEqual, apply_compare, Immediate(0)); 39 Operation(OperationCode::LogicalUNotEqual, apply_compare, Immediate(0));
42 40
43 const Node value_compare = Operation(OperationCode::UBitwiseAnd, NO_PRECISE, mask, shift); 41 const Node value_compare = BitfieldExtract(mask, offset + shift, 1);
44 const Node value = Operation(OperationCode::LogicalUNotEqual, value_compare, Immediate(0)); 42 const Node value = Operation(OperationCode::LogicalUNotEqual, value_compare, Immediate(0));
45 43
46 const Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), value); 44 const Node code = Operation(OperationCode::LogicalAssign, GetPredicate(pred), value);
diff --git a/src/video_core/shader/decode/video.cpp b/src/video_core/shader/decode/video.cpp
index 9510896e4..b491fbadb 100644
--- a/src/video_core/shader/decode/video.cpp
+++ b/src/video_core/shader/decode/video.cpp
@@ -88,21 +88,15 @@ u32 ShaderIR::DecodeVideo(BasicBlock& bb, u32 pc) {
88Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed, 88Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed,
89 Tegra::Shader::VideoType type, u64 byte_height) { 89 Tegra::Shader::VideoType type, u64 byte_height) {
90 if (!is_chunk) { 90 if (!is_chunk) {
91 const auto offset = static_cast<u32>(byte_height * 8); 91 return BitfieldExtract(op, static_cast<u32>(byte_height * 8), 8);
92 const Node shift = SignedOperation(OperationCode::ILogicalShiftRight, is_signed, NO_PRECISE,
93 op, Immediate(offset));
94 return SignedOperation(OperationCode::IBitwiseAnd, is_signed, NO_PRECISE, shift,
95 Immediate(0xff));
96 } 92 }
97 const Node zero = Immediate(0); 93 const Node zero = Immediate(0);
98 94
99 switch (type) { 95 switch (type) {
100 case Tegra::Shader::VideoType::Size16_Low: 96 case Tegra::Shader::VideoType::Size16_Low:
101 return SignedOperation(OperationCode::IBitwiseAnd, is_signed, NO_PRECISE, op, 97 return BitfieldExtract(op, 0, 16);
102 Immediate(0xffff));
103 case Tegra::Shader::VideoType::Size16_High: 98 case Tegra::Shader::VideoType::Size16_High:
104 return SignedOperation(OperationCode::ILogicalShiftRight, is_signed, NO_PRECISE, op, 99 return BitfieldExtract(op, 16, 16);
105 Immediate(16));
106 case Tegra::Shader::VideoType::Size32: 100 case Tegra::Shader::VideoType::Size32:
107 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when this type is used 101 // TODO(Rodrigo): From my hardware tests it becomes a bit "mad" when this type is used
108 // (1 * 1 + 0 == 0x5b800000). Until a better explanation is found: abort. 102 // (1 * 1 + 0 == 0x5b800000). Until a better explanation is found: abort.
diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp
index 0466069ae..3e37aee4a 100644
--- a/src/video_core/shader/decode/xmad.cpp
+++ b/src/video_core/shader/decode/xmad.cpp
@@ -47,22 +47,10 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, u32 pc) {
47 return {false, Immediate(0), Immediate(0)}; 47 return {false, Immediate(0), Immediate(0)};
48 }(); 48 }();
49 49
50 if (instr.xmad.high_a) { 50 op_a = BitfieldExtract(op_a, instr.xmad.high_a ? 16 : 0, 16);
51 op_a = SignedOperation(OperationCode::ILogicalShiftRight, is_signed_a, NO_PRECISE, op_a,
52 Immediate(16));
53 } else {
54 op_a = SignedOperation(OperationCode::IBitwiseAnd, is_signed_a, NO_PRECISE, op_a,
55 Immediate(0xffff));
56 }
57 51
58 const Node original_b = op_b; 52 const Node original_b = op_b;
59 if (instr.xmad.high_b) { 53 op_b = BitfieldExtract(op_b, instr.xmad.high_b ? 16 : 0, 16);
60 op_b = SignedOperation(OperationCode::ILogicalShiftRight, is_signed_b, NO_PRECISE, op_a,
61 Immediate(16));
62 } else {
63 op_b = SignedOperation(OperationCode::IBitwiseAnd, is_signed_b, NO_PRECISE, op_b,
64 Immediate(0xffff));
65 }
66 54
67 // TODO(Rodrigo): Use an appropiate sign for this operation 55 // TODO(Rodrigo): Use an appropiate sign for this operation
68 Node product = Operation(OperationCode::IMul, NO_PRECISE, op_a, op_b); 56 Node product = Operation(OperationCode::IMul, NO_PRECISE, op_a, op_b);
@@ -75,11 +63,9 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, u32 pc) {
75 case Tegra::Shader::XmadMode::None: 63 case Tegra::Shader::XmadMode::None:
76 return op_c; 64 return op_c;
77 case Tegra::Shader::XmadMode::CLo: 65 case Tegra::Shader::XmadMode::CLo:
78 return SignedOperation(OperationCode::IBitwiseAnd, is_signed_c, NO_PRECISE, op_c, 66 return BitfieldExtract(op_c, 0, 16);
79 Immediate(0xffff));
80 case Tegra::Shader::XmadMode::CHi: 67 case Tegra::Shader::XmadMode::CHi:
81 return SignedOperation(OperationCode::ILogicalShiftRight, is_signed_c, NO_PRECISE, op_c, 68 return BitfieldExtract(op_c, 16, 16);
82 Immediate(16));
83 case Tegra::Shader::XmadMode::CBcc: { 69 case Tegra::Shader::XmadMode::CBcc: {
84 const Node shifted_b = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed_b, 70 const Node shifted_b = SignedOperation(OperationCode::ILogicalShiftLeft, is_signed_b,
85 NO_PRECISE, original_b, Immediate(16)); 71 NO_PRECISE, original_b, Immediate(16));
@@ -94,9 +80,9 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, u32 pc) {
94 // TODO(Rodrigo): Use an appropiate sign for this operation 80 // TODO(Rodrigo): Use an appropiate sign for this operation
95 Node sum = Operation(OperationCode::IAdd, product, op_c); 81 Node sum = Operation(OperationCode::IAdd, product, op_c);
96 if (is_merge) { 82 if (is_merge) {
97 const Node a = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, sum, Immediate(0xffff)); 83 const Node a = BitfieldExtract(sum, 0, 16);
98 const Node b = 84 const Node b =
99 Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, original_b, Immediate(0xffff)); 85 Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, original_b, Immediate(16));
100 sum = Operation(OperationCode::IBitwiseOr, NO_PRECISE, a, b); 86 sum = Operation(OperationCode::IBitwiseOr, NO_PRECISE, a, b);
101 } 87 }
102 88
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index b07642517..d4e304b4e 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -348,6 +348,11 @@ void ShaderIR::SetLocalMemory(BasicBlock& bb, Node address, Node value) {
348 bb.push_back(Operation(OperationCode::Assign, GetLocalMemory(address), value)); 348 bb.push_back(Operation(OperationCode::Assign, GetLocalMemory(address), value));
349} 349}
350 350
351Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
352 return Operation(OperationCode::UBitfieldExtract, NO_PRECISE, value, Immediate(offset),
353 Immediate(bits));
354}
355
351/*static*/ OperationCode ShaderIR::SignedToUnsignedCode(OperationCode operation_code, 356/*static*/ OperationCode ShaderIR::SignedToUnsignedCode(OperationCode operation_code,
352 bool is_signed) { 357 bool is_signed) {
353 if (is_signed) { 358 if (is_signed) {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 52c7c3180..75d13fa4d 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -88,6 +88,7 @@ enum class OperationCode {
88 IBitwiseXor, /// (MetaArithmetic, int a, int b) -> int 88 IBitwiseXor, /// (MetaArithmetic, int a, int b) -> int
89 IBitwiseNot, /// (MetaArithmetic, int a) -> int 89 IBitwiseNot, /// (MetaArithmetic, int a) -> int
90 IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int 90 IBitfieldInsert, /// (MetaArithmetic, int base, int insert, int offset, int bits) -> int
91 IBitfieldExtract, /// (MetaArithmetic, int value, int offset, int offset) -> int
91 IBitCount, /// (MetaArithmetic, int) -> int 92 IBitCount, /// (MetaArithmetic, int) -> int
92 93
93 UAdd, /// (MetaArithmetic, uint a, uint b) -> uint 94 UAdd, /// (MetaArithmetic, uint a, uint b) -> uint
@@ -104,8 +105,9 @@ enum class OperationCode {
104 UBitwiseOr, /// (MetaArithmetic, uint a, uint b) -> uint 105 UBitwiseOr, /// (MetaArithmetic, uint a, uint b) -> uint
105 UBitwiseXor, /// (MetaArithmetic, uint a, uint b) -> uint 106 UBitwiseXor, /// (MetaArithmetic, uint a, uint b) -> uint
106 UBitwiseNot, /// (MetaArithmetic, uint a) -> uint 107 UBitwiseNot, /// (MetaArithmetic, uint a) -> uint
107 UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint 108 UBitfieldInsert, /// (MetaArithmetic, uint base, uint insert, int offset, int bits) -> uint
108 UBitCount, /// (MetaArithmetic, uint) -> uint 109 UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
110 UBitCount, /// (MetaArithmetic, uint) -> uint
109 111
110 HAdd, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 112 HAdd, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
111 HMul, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2 113 HMul, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
@@ -689,6 +691,9 @@ private:
689 const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler, 691 const Sampler& GetSampler(const Tegra::Shader::Sampler& sampler,
690 Tegra::Shader::TextureType type, bool is_array, bool is_shadow); 692 Tegra::Shader::TextureType type, bool is_array, bool is_shadow);
691 693
694 /// Extracts a sequence of bits from a node
695 Node BitfieldExtract(Node value, u32 offset, u32 bits);
696
692 void WriteTexsInstructionFloat(BasicBlock& bb, Tegra::Shader::Instruction instr, Node texture); 697 void WriteTexsInstructionFloat(BasicBlock& bb, Tegra::Shader::Instruction instr, Node texture);
693 void WriteTexsInstructionHalfFloat(BasicBlock& bb, Tegra::Shader::Instruction instr, 698 void WriteTexsInstructionHalfFloat(BasicBlock& bb, Tegra::Shader::Instruction instr,
694 Node texture); 699 Node texture);