summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h8
-rw-r--r--src/video_core/shader/decode/conversion.cpp22
2 files changed, 23 insertions, 7 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index ba28ff51c..c3678b9ea 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1020,7 +1020,6 @@ union Instruction {
1020 } iset; 1020 } iset;
1021 1021
1022 union { 1022 union {
1023 BitField<41, 2, u64> selector; // i2i and i2f only
1024 BitField<45, 1, u64> negate_a; 1023 BitField<45, 1, u64> negate_a;
1025 BitField<49, 1, u64> abs_a; 1024 BitField<49, 1, u64> abs_a;
1026 BitField<10, 2, Register::Size> src_size; 1025 BitField<10, 2, Register::Size> src_size;
@@ -1046,6 +1045,13 @@ union Instruction {
1046 } 1045 }
1047 } f2f; 1046 } f2f;
1048 1047
1048 union {
1049 BitField<41, 2, u64> selector;
1050 } int_src;
1051
1052 union {
1053 BitField<41, 1, u64> selector;
1054 } float_src;
1049 } conversion; 1055 } conversion;
1050 1056
1051 union { 1057 union {
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index 8973fbefa..32facd6ba 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -14,6 +14,12 @@ using Tegra::Shader::Instruction;
14using Tegra::Shader::OpCode; 14using Tegra::Shader::OpCode;
15using Tegra::Shader::Register; 15using Tegra::Shader::Register;
16 16
17namespace {
18constexpr OperationCode GetFloatSelector(u64 selector) {
19 return selector == 0 ? OperationCode::FCastHalf0 : OperationCode::FCastHalf1;
20}
21} // Anonymous namespace
22
17u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) { 23u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
18 const Instruction instr = {program_code[pc]}; 24 const Instruction instr = {program_code[pc]};
19 const auto opcode = OpCode::Decode(instr); 25 const auto opcode = OpCode::Decode(instr);
@@ -22,7 +28,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
22 case OpCode::Id::I2I_R: 28 case OpCode::Id::I2I_R:
23 case OpCode::Id::I2I_C: 29 case OpCode::Id::I2I_C:
24 case OpCode::Id::I2I_IMM: { 30 case OpCode::Id::I2I_IMM: {
25 UNIMPLEMENTED_IF(instr.conversion.selector); 31 UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
26 UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); 32 UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word);
27 UNIMPLEMENTED_IF(instr.alu.saturate_d); 33 UNIMPLEMENTED_IF(instr.alu.saturate_d);
28 34
@@ -57,8 +63,8 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
57 case OpCode::Id::I2F_R: 63 case OpCode::Id::I2F_R:
58 case OpCode::Id::I2F_C: 64 case OpCode::Id::I2F_C:
59 case OpCode::Id::I2F_IMM: { 65 case OpCode::Id::I2F_IMM: {
66 UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
60 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 67 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
61 UNIMPLEMENTED_IF(instr.conversion.selector);
62 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 68 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
63 "Condition codes generation in I2F is not implemented"); 69 "Condition codes generation in I2F is not implemented");
64 70
@@ -113,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
113 }(); 119 }();
114 120
115 if (instr.conversion.src_size == Register::Size::Short) { 121 if (instr.conversion.src_size == Register::Size::Short) {
116 // TODO: figure where extract is sey in the encoding 122 value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
117 value = Operation(OperationCode::FCastHalf0, PRECISE, value); 123 std::move(value));
124 } else {
125 ASSERT(instr.conversion.float_src.selector == 0);
118 } 126 }
119 127
120 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 128 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
@@ -169,8 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
169 }(); 177 }();
170 178
171 if (instr.conversion.src_size == Register::Size::Short) { 179 if (instr.conversion.src_size == Register::Size::Short) {
172 // TODO: figure where extract is sey in the encoding 180 value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
173 value = Operation(OperationCode::FCastHalf0, PRECISE, value); 181 std::move(value));
182 } else {
183 ASSERT(instr.conversion.float_src.selector == 0);
174 } 184 }
175 185
176 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 186 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);