summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-12-20 23:01:03 -0300
committerGravatar ReinUsesLisp2019-01-15 17:54:49 -0300
commitbf07272695b718d09f8ef532539ba625dab01d3c (patch)
tree756b0848eb8b0e94b4e650a2b3371a32e46b63a4 /src
parentshader_ir: Add half float helpers (diff)
downloadyuzu-bf07272695b718d09f8ef532539ba625dab01d3c.tar.gz
yuzu-bf07272695b718d09f8ef532539ba625dab01d3c.tar.xz
yuzu-bf07272695b718d09f8ef532539ba625dab01d3c.zip
shader_ir: Add comparison helpers
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/shader_ir.cpp97
-rw-r--r--src/video_core/shader/shader_ir.h9
2 files changed, 106 insertions, 0 deletions
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 5951bdc7b..20a1a50ef 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -212,6 +212,103 @@ Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
212 return value; 212 return value;
213} 213}
214 214
215Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
216 static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
217 {PredCondition::LessThan, OperationCode::LogicalFLessThan},
218 {PredCondition::Equal, OperationCode::LogicalFEqual},
219 {PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
220 {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
221 {PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
222 {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
223 {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
224 {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
225 {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
226 {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
227 {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}};
228
229 const auto comparison{PredicateComparisonTable.find(condition)};
230 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
231 "Unknown predicate comparison operation");
232
233 Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
234
235 if (condition == PredCondition::LessThanWithNan ||
236 condition == PredCondition::NotEqualWithNan ||
237 condition == PredCondition::LessEqualWithNan ||
238 condition == PredCondition::GreaterThanWithNan ||
239 condition == PredCondition::GreaterEqualWithNan) {
240
241 predicate = Operation(OperationCode::LogicalOr, predicate,
242 Operation(OperationCode::LogicalFIsNan, op_a));
243 predicate = Operation(OperationCode::LogicalOr, predicate,
244 Operation(OperationCode::LogicalFIsNan, op_b));
245 }
246
247 return predicate;
248}
249
250Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
251 Node op_b) {
252 static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
253 {PredCondition::LessThan, OperationCode::LogicalILessThan},
254 {PredCondition::Equal, OperationCode::LogicalIEqual},
255 {PredCondition::LessEqual, OperationCode::LogicalILessEqual},
256 {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
257 {PredCondition::NotEqual, OperationCode::LogicalINotEqual},
258 {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
259 {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
260 {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
261 {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
262 {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
263 {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}};
264
265 const auto comparison{PredicateComparisonTable.find(condition)};
266 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
267 "Unknown predicate comparison operation");
268
269 Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b);
270
271 UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
272 condition == PredCondition::NotEqualWithNan ||
273 condition == PredCondition::LessEqualWithNan ||
274 condition == PredCondition::GreaterThanWithNan ||
275 condition == PredCondition::GreaterEqualWithNan,
276 "NaN comparisons for integers are not implemented");
277 return predicate;
278}
279
280Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
281 const MetaHalfArithmetic& meta, Node op_a, Node op_b) {
282
283 UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
284 condition == PredCondition::NotEqualWithNan ||
285 condition == PredCondition::LessEqualWithNan ||
286 condition == PredCondition::GreaterThanWithNan ||
287 condition == PredCondition::GreaterEqualWithNan,
288 "Unimplemented NaN comparison for half floats");
289
290 static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
291 {PredCondition::LessThan, OperationCode::LogicalHLessThan},
292 {PredCondition::Equal, OperationCode::LogicalHEqual},
293 {PredCondition::LessEqual, OperationCode::LogicalHLessEqual},
294 {PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan},
295 {PredCondition::NotEqual, OperationCode::LogicalHNotEqual},
296 {PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual},
297 {PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan},
298 {PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual},
299 {PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual},
300 {PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan},
301 {PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}};
302
303 const auto comparison{PredicateComparisonTable.find(condition)};
304 UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
305 "Unknown predicate comparison operation");
306
307 const Node predicate = Operation(comparison->second, meta, op_a, op_b);
308
309 return predicate;
310}
311
215void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) { 312void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
216 bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); 313 bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
217} 314}
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index f3b17d2eb..372ed10da 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -660,6 +660,15 @@ private:
660 /// Conditionally absolute/negated half float pair. Absolute is applied first 660 /// Conditionally absolute/negated half float pair. Absolute is applied first
661 Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate); 661 Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate);
662 662
663 /// Returns a predicate comparing two floats
664 Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b);
665 /// Returns a predicate comparing two integers
666 Node GetPredicateComparisonInteger(Tegra::Shader::PredCondition condition, bool is_signed,
667 Node op_a, Node op_b);
668 /// Returns a predicate comparing two half floats. meta consumes how both pairs will be compared
669 Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
670 const MetaHalfArithmetic& meta, Node op_a, Node op_b);
671
663 template <typename... T> 672 template <typename... T>
664 inline Node Operation(OperationCode code, const T*... operands) { 673 inline Node Operation(OperationCode code, const T*... operands) {
665 return StoreNode(OperationNode(code, operands...)); 674 return StoreNode(OperationNode(code, operands...));