summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar bunnei2019-08-21 10:27:57 -0400
committerGravatar GitHub2019-08-21 10:27:57 -0400
commitcedc1aab4a9973590678fa1e094bb032c51c5959 (patch)
tree7fafb56c7d53c20a60dc835f258875ccc0cd1859 /src/video_core/shader/decode
parentMerge pull request #2773 from lioncash/test-unused (diff)
parentShader_Ir: Implement F16 Variants of F2F, F2I, I2F. (diff)
downloadyuzu-cedc1aab4a9973590678fa1e094bb032c51c5959.tar.gz
yuzu-cedc1aab4a9973590678fa1e094bb032c51c5959.tar.xz
yuzu-cedc1aab4a9973590678fa1e094bb032c51c5959.zip
Merge pull request #2753 from FernandoS27/float-convert
Shader_Ir: Implement F16 Variants of F2F, F2I, I2F.
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/conversion.cpp30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp
index 4221f0c58..8973fbefa 100644
--- a/src/video_core/shader/decode/conversion.cpp
+++ b/src/video_core/shader/decode/conversion.cpp
@@ -57,7 +57,7 @@ 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.dst_size != Register::Size::Word); 60 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
61 UNIMPLEMENTED_IF(instr.conversion.selector); 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");
@@ -82,14 +82,19 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
82 value = GetOperandAbsNegFloat(value, false, instr.conversion.negate_a); 82 value = GetOperandAbsNegFloat(value, false, instr.conversion.negate_a);
83 83
84 SetInternalFlagsFromFloat(bb, value, instr.generates_cc); 84 SetInternalFlagsFromFloat(bb, value, instr.generates_cc);
85
86 if (instr.conversion.dst_size == Register::Size::Short) {
87 value = Operation(OperationCode::HCastFloat, PRECISE, value);
88 }
89
85 SetRegister(bb, instr.gpr0, value); 90 SetRegister(bb, instr.gpr0, value);
86 break; 91 break;
87 } 92 }
88 case OpCode::Id::F2F_R: 93 case OpCode::Id::F2F_R:
89 case OpCode::Id::F2F_C: 94 case OpCode::Id::F2F_C:
90 case OpCode::Id::F2F_IMM: { 95 case OpCode::Id::F2F_IMM: {
91 UNIMPLEMENTED_IF(instr.conversion.f2f.dst_size != Register::Size::Word); 96 UNIMPLEMENTED_IF(instr.conversion.dst_size == Register::Size::Long);
92 UNIMPLEMENTED_IF(instr.conversion.f2f.src_size != Register::Size::Word); 97 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
93 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 98 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
94 "Condition codes generation in F2F is not implemented"); 99 "Condition codes generation in F2F is not implemented");
95 100
@@ -107,6 +112,11 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
107 } 112 }
108 }(); 113 }();
109 114
115 if (instr.conversion.src_size == Register::Size::Short) {
116 // TODO: figure where extract is sey in the encoding
117 value = Operation(OperationCode::FCastHalf0, PRECISE, value);
118 }
119
110 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 120 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
111 121
112 value = [&]() { 122 value = [&]() {
@@ -124,19 +134,24 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
124 default: 134 default:
125 UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}", 135 UNIMPLEMENTED_MSG("Unimplemented F2F rounding mode {}",
126 static_cast<u32>(instr.conversion.f2f.rounding.Value())); 136 static_cast<u32>(instr.conversion.f2f.rounding.Value()));
127 return Immediate(0); 137 return value;
128 } 138 }
129 }(); 139 }();
130 value = GetSaturatedFloat(value, instr.alu.saturate_d); 140 value = GetSaturatedFloat(value, instr.alu.saturate_d);
131 141
132 SetInternalFlagsFromFloat(bb, value, instr.generates_cc); 142 SetInternalFlagsFromFloat(bb, value, instr.generates_cc);
143
144 if (instr.conversion.dst_size == Register::Size::Short) {
145 value = Operation(OperationCode::HCastFloat, PRECISE, value);
146 }
147
133 SetRegister(bb, instr.gpr0, value); 148 SetRegister(bb, instr.gpr0, value);
134 break; 149 break;
135 } 150 }
136 case OpCode::Id::F2I_R: 151 case OpCode::Id::F2I_R:
137 case OpCode::Id::F2I_C: 152 case OpCode::Id::F2I_C:
138 case OpCode::Id::F2I_IMM: { 153 case OpCode::Id::F2I_IMM: {
139 UNIMPLEMENTED_IF(instr.conversion.src_size != Register::Size::Word); 154 UNIMPLEMENTED_IF(instr.conversion.src_size == Register::Size::Long);
140 UNIMPLEMENTED_IF_MSG(instr.generates_cc, 155 UNIMPLEMENTED_IF_MSG(instr.generates_cc,
141 "Condition codes generation in F2I is not implemented"); 156 "Condition codes generation in F2I is not implemented");
142 Node value = [&]() { 157 Node value = [&]() {
@@ -153,6 +168,11 @@ u32 ShaderIR::DecodeConversion(NodeBlock& bb, u32 pc) {
153 } 168 }
154 }(); 169 }();
155 170
171 if (instr.conversion.src_size == Register::Size::Short) {
172 // TODO: figure where extract is sey in the encoding
173 value = Operation(OperationCode::FCastHalf0, PRECISE, value);
174 }
175
156 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a); 176 value = GetOperandAbsNegFloat(value, instr.conversion.abs_a, instr.conversion.negate_a);
157 177
158 value = [&]() { 178 value = [&]() {