summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h3
-rw-r--r--src/video_core/shader/decode/conversion.cpp20
2 files changed, 17 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index aaa1acea9..35201c8be 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -1006,7 +1006,7 @@ union Instruction {
1006 } iset; 1006 } iset;
1007 1007
1008 union { 1008 union {
1009 BitField<41, 2, u64> selector; // i2i and i2f only 1009 BitField<41, 2, u64> selector;
1010 BitField<45, 1, u64> negate_a; 1010 BitField<45, 1, u64> negate_a;
1011 BitField<49, 1, u64> abs_a; 1011 BitField<49, 1, u64> abs_a;
1012 BitField<10, 2, Register::Size> src_size; 1012 BitField<10, 2, Register::Size> src_size;
@@ -1031,7 +1031,6 @@ union Instruction {
1031 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask); 1031 return static_cast<F2fRoundingOp>(rounding.Value() & rounding_mask);
1032 } 1032 }
1033 } f2f; 1033 } f2f;
1034
1035 } conversion; 1034 } conversion;
1036 1035
1037 union { 1036 union {
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index 8973fbefa..cf328aff8 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -22,7 +22,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
22 case OpCode::Id::I2I_R: 22 case OpCode::Id::I2I_R:
23 case OpCode::Id::I2I_C: 23 case OpCode::Id::I2I_C:
24 case OpCode::Id::I2I_IMM: { 24 case OpCode::Id::I2I_IMM: {
25 UNIMPLEMENTED_IF(instr.conversion.selector); 25 UNIMPLEMENTED_IF(instr.conversion.selector.Value());
26 UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word); 26 UNIMPLEMENTED_IF(instr.conversion.dst_size != Register::Size::Word);
27 UNIMPLEMENTED_IF(instr.alu.saturate_d); 27 UNIMPLEMENTED_IF(instr.alu.saturate_d);
28 28
@@ -57,8 +57,8 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
57 case OpCode::Id::I2F_R: 57 case OpCode::Id::I2F_R:
58 case OpCode::Id::I2F_C: 58 case OpCode::Id::I2F_C:
59 case OpCode::Id::I2F_IMM: { 59 case OpCode::Id::I2F_IMM: {
60 UNIMPLEMENTED_IF(instr.conversion.selector.Value());
60 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 61 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
61 UNIMPLEMENTED_IF(instr.conversion.selector);
62 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 62 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
63 "Condition codes generation in I2F is not implemented"); 63 "Condition codes generation in I2F is not implemented");
64 64
@@ -93,6 +93,7 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
93 case OpCode::Id::F2F_R: 93 case OpCode::Id::F2F_R:
94 case OpCode::Id::F2F_C: 94 case OpCode::Id::F2F_C:
95 case OpCode::Id::F2F_IMM: { 95 case OpCode::Id::F2F_IMM: {
96 UNIMPLEMENTED_IF(instr.conversion.selector.Value());
96 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long); 97 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
97 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long); 98 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
98 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 99 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
@@ -169,8 +170,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
169 }(); 170 }();
170 171
171 if (instr.conversion.src_size == Register::Size::Short) { 172 if (instr.conversion.src_size == Register::Size::Short) {
172 // TODO: figure where extract is sey in the encoding 173 const OperationCode cast = [instr] {
173 value = Operation(OperationCode::FCastHalf0, PRECISE, value); 174 switch (instr.conversion.selector) {
175 case 0:
176 return OperationCode::FCastHalf0;
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));
174 } 186 }
175 187
176 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 188 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);