diff options
| author | 2018-12-26 02:58:47 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:53 -0300 | |
| commit | 2faad9bf23dbcedc80dca7ed9ad4b81c0416dd5e (patch) | |
| tree | 3faa264db225f2ae09ccf417fd962eddb40c2235 /src | |
| parent | shader_ir: Remove Ipa primitive (diff) | |
| download | yuzu-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.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/shader/decode/bfi.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/shader/decode/register_set_predicate.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/shader/decode/video.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/shader/decode/xmad.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 9 |
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) { | |||
| 88 | Node ShaderIR::GetVideoOperand(Node op, bool is_chunk, bool is_signed, | 88 | Node 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 | ||
| 351 | Node 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); |