summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h9
-rw-r--r--src/video_core/shader/decode/conversion.cpp34
2 files changed, 24 insertions, 19 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 35201c8be..747284700 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1006,7 +1006,6 @@ union Instruction {
1006 } iset; 1006 } iset;
1007 1007
1008 union { 1008 union {
1009 BitField<41, 2, u64> selector;
1010 BitField<45, 1, u64> negate_a; 1009 BitField<45, 1, u64> negate_a;
1011 BitField<49, 1, u64> abs_a; 1010 BitField<49, 1, u64> abs_a;
1012 BitField<10, 2, Register::Size> src_size; 1011 BitField<10, 2, Register::Size> src_size;
@@ -1031,6 +1030,14 @@ union Instruction {
1031 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); 1030 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask);
1032 } 1031 }
1033 } f2f; 1032 } f2f;
1033
1034 union {
1035 BitField<41, 2, u64> selector;
1036 } int_src;
1037
1038 union {
1039 BitField<41, 1, u64> selector;
1040 } float_src;
1034 } conversion; 1041 } conversion;
1035 1042
1036 union { 1043 union {
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index cf328aff8..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.Value()); 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,7 +63,7 @@ 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: {
60 UNIMPLEMENTED_IF(instr.conversion.selector.Value()); 66 UNIMPLEMENTED_IF(instr.conversion.int_src.selector != 0);
61 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 67 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
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");
@@ -93,7 +99,6 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
93 case OpCode::Id::F2F_R: 99 case OpCode::Id::F2F_R:
94 case OpCode::Id::F2F_C: 100 case OpCode::Id::F2F_C:
95 case OpCode::Id::F2F_IMM: { 101 case OpCode::Id::F2F_IMM: {
96 UNIMPLEMENTED_IF(instr.conversion.selector.Value());
97 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 102 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
98 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); 103 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
99 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 104 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
@@ -114,8 +119,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
114 }(); 119 }();
115 120
116 if (instr.conversion.src_size == Register::Size::Short) { 121 if (instr.conversion.src_size == Register::Size::Short) {
117 // TODO: figure where extract is sey in the encoding 122 value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
118 value = Operation(OperationCode::FCastHalf0, PRECISE, value); 123 std::move(value));
124 } else {
125 ASSERT(instr.conversion.float_src.selector == 0);
119 } 126 }
120 127
121 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 128 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
@@ -170,19 +177,10 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
170 }(); 177 }();
171 178
172 if (instr.conversion.src_size == Register::Size::Short) { 179 if (instr.conversion.src_size == Register::Size::Short) {
173 const OperationCode cast = [instr] { 180 value = Operation(GetFloatSelector(instr.conversion.float_src.selector), NO_PRECISE,
174 switch (instr.conversion.selector) { 181 std::move(value));
175 case 0: 182 } else {
176 return OperationCode::FCastHalf0; 183 ASSERT(instr.conversion.float_src.selector == 0);
177 case 1:
178 return OperationCode::FCastHalf1;
179 default:
180 UNREACHABLE_MSG("Invalid selector={}",
181 static_cast<u32>(instr.conversion.selector));
182 return OperationCode::FCastHalf0;
183 }
184 }();
185 value = Operation(cast, NO_PRECISE, std::move(value));
186 } 184 }
187 185
188 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 186 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);