diff options
| author | 2019-04-09 17:33:48 -0300 | |
|---|---|---|
| committer | 2019-04-15 21:13:26 -0300 | |
| commit | acf618afbc834ccfd05a33205c035ecb9737b5db (patch) | |
| tree | 25825a01fefaec8c2c29309da7598efa2825fbae /src | |
| parent | shader_ir: Avoid using static on heap-allocated objects (diff) | |
| download | yuzu-acf618afbc834ccfd05a33205c035ecb9737b5db.tar.gz yuzu-acf618afbc834ccfd05a33205c035ecb9737b5db.tar.xz yuzu-acf618afbc834ccfd05a33205c035ecb9737b5db.zip | |
renderer_opengl: Implement half float NaN comparisons
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 60 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 18 |
3 files changed, 59 insertions, 36 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 28e490b3c..cbaa4dceb 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1173,34 +1173,46 @@ private: | |||
| 1173 | return GenerateUnary(operation, "any", Type::Bool, Type::Bool2); | 1173 | return GenerateUnary(operation, "any", Type::Bool, Type::Bool2); |
| 1174 | } | 1174 | } |
| 1175 | 1175 | ||
| 1176 | template <bool with_nan> | ||
| 1177 | std::string GenerateHalfComparison(Operation operation, std::string compare_op) { | ||
| 1178 | std::string comparison{GenerateBinaryCall(operation, compare_op, Type::Bool2, | ||
| 1179 | Type::HalfFloat, Type::HalfFloat)}; | ||
| 1180 | if constexpr (!with_nan) { | ||
| 1181 | return comparison; | ||
| 1182 | } | ||
| 1183 | return "halfFloatNanComparison(" + comparison + ", " + | ||
| 1184 | VisitOperand(operation, 0, Type::HalfFloat) + ", " + | ||
| 1185 | VisitOperand(operation, 1, Type::HalfFloat) + ')'; | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | template <bool with_nan> | ||
| 1176 | std::string Logical2HLessThan(Operation operation) { | 1189 | std::string Logical2HLessThan(Operation operation) { |
| 1177 | return GenerateBinaryCall(operation, "lessThan", Type::Bool2, Type::HalfFloat, | 1190 | return GenerateHalfComparison<with_nan>(operation, "lessThan"); |
| 1178 | Type::HalfFloat); | ||
| 1179 | } | 1191 | } |
| 1180 | 1192 | ||
| 1193 | template <bool with_nan> | ||
| 1181 | std::string Logical2HEqual(Operation operation) { | 1194 | std::string Logical2HEqual(Operation operation) { |
| 1182 | return GenerateBinaryCall(operation, "equal", Type::Bool2, Type::HalfFloat, | 1195 | return GenerateHalfComparison<with_nan>(operation, "equal"); |
| 1183 | Type::HalfFloat); | ||
| 1184 | } | 1196 | } |
| 1185 | 1197 | ||
| 1198 | template <bool with_nan> | ||
| 1186 | std::string Logical2HLessEqual(Operation operation) { | 1199 | std::string Logical2HLessEqual(Operation operation) { |
| 1187 | return GenerateBinaryCall(operation, "lessThanEqual", Type::Bool2, Type::HalfFloat, | 1200 | return GenerateHalfComparison<with_nan>(operation, "lessThanEqual"); |
| 1188 | Type::HalfFloat); | ||
| 1189 | } | 1201 | } |
| 1190 | 1202 | ||
| 1203 | template <bool with_nan> | ||
| 1191 | std::string Logical2HGreaterThan(Operation operation) { | 1204 | std::string Logical2HGreaterThan(Operation operation) { |
| 1192 | return GenerateBinaryCall(operation, "greaterThan", Type::Bool2, Type::HalfFloat, | 1205 | return GenerateHalfComparison<with_nan>(operation, "greaterThan"); |
| 1193 | Type::HalfFloat); | ||
| 1194 | } | 1206 | } |
| 1195 | 1207 | ||
| 1208 | template <bool with_nan> | ||
| 1196 | std::string Logical2HNotEqual(Operation operation) { | 1209 | std::string Logical2HNotEqual(Operation operation) { |
| 1197 | return GenerateBinaryCall(operation, "notEqual", Type::Bool2, Type::HalfFloat, | 1210 | return GenerateHalfComparison<with_nan>(operation, "notEqual"); |
| 1198 | Type::HalfFloat); | ||
| 1199 | } | 1211 | } |
| 1200 | 1212 | ||
| 1213 | template <bool with_nan> | ||
| 1201 | std::string Logical2HGreaterEqual(Operation operation) { | 1214 | std::string Logical2HGreaterEqual(Operation operation) { |
| 1202 | return GenerateBinaryCall(operation, "greaterThanEqual", Type::Bool2, Type::HalfFloat, | 1215 | return GenerateHalfComparison<with_nan>(operation, "greaterThanEqual"); |
| 1203 | Type::HalfFloat); | ||
| 1204 | } | 1216 | } |
| 1205 | 1217 | ||
| 1206 | std::string Texture(Operation operation) { | 1218 | std::string Texture(Operation operation) { |
| @@ -1525,12 +1537,18 @@ private: | |||
| 1525 | &GLSLDecompiler::LogicalNotEqual<Type::Uint>, | 1537 | &GLSLDecompiler::LogicalNotEqual<Type::Uint>, |
| 1526 | &GLSLDecompiler::LogicalGreaterEqual<Type::Uint>, | 1538 | &GLSLDecompiler::LogicalGreaterEqual<Type::Uint>, |
| 1527 | 1539 | ||
| 1528 | &GLSLDecompiler::Logical2HLessThan, | 1540 | &GLSLDecompiler::Logical2HLessThan<false>, |
| 1529 | &GLSLDecompiler::Logical2HEqual, | 1541 | &GLSLDecompiler::Logical2HEqual<false>, |
| 1530 | &GLSLDecompiler::Logical2HLessEqual, | 1542 | &GLSLDecompiler::Logical2HLessEqual<false>, |
| 1531 | &GLSLDecompiler::Logical2HGreaterThan, | 1543 | &GLSLDecompiler::Logical2HGreaterThan<false>, |
| 1532 | &GLSLDecompiler::Logical2HNotEqual, | 1544 | &GLSLDecompiler::Logical2HNotEqual<false>, |
| 1533 | &GLSLDecompiler::Logical2HGreaterEqual, | 1545 | &GLSLDecompiler::Logical2HGreaterEqual<false>, |
| 1546 | &GLSLDecompiler::Logical2HLessThan<true>, | ||
| 1547 | &GLSLDecompiler::Logical2HEqual<true>, | ||
| 1548 | &GLSLDecompiler::Logical2HLessEqual<true>, | ||
| 1549 | &GLSLDecompiler::Logical2HGreaterThan<true>, | ||
| 1550 | &GLSLDecompiler::Logical2HNotEqual<true>, | ||
| 1551 | &GLSLDecompiler::Logical2HGreaterEqual<true>, | ||
| 1534 | 1552 | ||
| 1535 | &GLSLDecompiler::Texture, | 1553 | &GLSLDecompiler::Texture, |
| 1536 | &GLSLDecompiler::TextureLod, | 1554 | &GLSLDecompiler::TextureLod, |
| @@ -1633,6 +1651,12 @@ std::string GetCommonDeclarations() { | |||
| 1633 | "}\n\n" | 1651 | "}\n\n" |
| 1634 | "vec2 toHalf2(float value) {\n" | 1652 | "vec2 toHalf2(float value) {\n" |
| 1635 | " return unpackHalf2x16(ftou(value));\n" | 1653 | " return unpackHalf2x16(ftou(value));\n" |
| 1654 | "}\n\n" | ||
| 1655 | "bvec2 halfFloatNanComparison(bvec2 comparison, vec2 pair1, vec2 pair2) {\n" | ||
| 1656 | " bvec2 is_nan1 = isnan(pair1);\n" | ||
| 1657 | " bvec2 is_nan2 = isnan(pair2);\n" | ||
| 1658 | " return bvec2(comparison.x || is_nan1.x || is_nan2.x, comparison.y || is_nan1.y || " | ||
| 1659 | "is_nan2.y);\n" | ||
| 1636 | "}\n"; | 1660 | "}\n"; |
| 1637 | } | 1661 | } |
| 1638 | 1662 | ||
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 5175f83c6..5c1c591f8 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -285,13 +285,6 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si | |||
| 285 | 285 | ||
| 286 | Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, | 286 | Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, |
| 287 | const MetaHalfArithmetic& meta, Node op_a, Node op_b) { | 287 | const MetaHalfArithmetic& meta, Node op_a, Node op_b) { |
| 288 | UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan || | ||
| 289 | condition == PredCondition::NotEqualWithNan || | ||
| 290 | condition == PredCondition::LessEqualWithNan || | ||
| 291 | condition == PredCondition::GreaterThanWithNan || | ||
| 292 | condition == PredCondition::GreaterEqualWithNan, | ||
| 293 | "Unimplemented NaN comparison for half floats"); | ||
| 294 | |||
| 295 | const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { | 288 | const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { |
| 296 | {PredCondition::LessThan, OperationCode::Logical2HLessThan}, | 289 | {PredCondition::LessThan, OperationCode::Logical2HLessThan}, |
| 297 | {PredCondition::Equal, OperationCode::Logical2HEqual}, | 290 | {PredCondition::Equal, OperationCode::Logical2HEqual}, |
| @@ -299,11 +292,11 @@ Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition | |||
| 299 | {PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan}, | 292 | {PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan}, |
| 300 | {PredCondition::NotEqual, OperationCode::Logical2HNotEqual}, | 293 | {PredCondition::NotEqual, OperationCode::Logical2HNotEqual}, |
| 301 | {PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual}, | 294 | {PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual}, |
| 302 | {PredCondition::LessThanWithNan, OperationCode::Logical2HLessThan}, | 295 | {PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan}, |
| 303 | {PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqual}, | 296 | {PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan}, |
| 304 | {PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqual}, | 297 | {PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan}, |
| 305 | {PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThan}, | 298 | {PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan}, |
| 306 | {PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqual}}; | 299 | {PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan}}; |
| 307 | 300 | ||
| 308 | const auto comparison{PredicateComparisonTable.find(condition)}; | 301 | const auto comparison{PredicateComparisonTable.find(condition)}; |
| 309 | UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), | 302 | UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 4888998d3..0ae51389b 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -150,12 +150,18 @@ enum class OperationCode { | |||
| 150 | LogicalUNotEqual, /// (uint a, uint b) -> bool | 150 | LogicalUNotEqual, /// (uint a, uint b) -> bool |
| 151 | LogicalUGreaterEqual, /// (uint a, uint b) -> bool | 151 | LogicalUGreaterEqual, /// (uint a, uint b) -> bool |
| 152 | 152 | ||
| 153 | Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 153 | Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 154 | Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 154 | Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 155 | Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 155 | Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 156 | Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 156 | Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 157 | Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 157 | Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 158 | Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | 158 | Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 |
| 159 | Logical2HLessThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 160 | Logical2HEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 161 | Logical2HLessEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 162 | Logical2HGreaterThanWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 163 | Logical2HNotEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 164 | Logical2HGreaterEqualWithNan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 | ||
| 159 | 165 | ||
| 160 | Texture, /// (MetaTexture, float[N] coords) -> float4 | 166 | Texture, /// (MetaTexture, float[N] coords) -> float4 |
| 161 | TextureLod, /// (MetaTexture, float[N] coords) -> float4 | 167 | TextureLod, /// (MetaTexture, float[N] coords) -> float4 |