diff options
| author | 2019-07-19 22:20:34 -0300 | |
|---|---|---|
| committer | 2019-07-19 22:21:22 -0300 | |
| commit | 45c162444d357e18b333e94973a39b9d71c7604d (patch) | |
| tree | 9569153bbb3968678b36979e0682c05e992c610c | |
| parent | shader/half_set_predicate: Implement missing HSETP2 variants (diff) | |
| download | yuzu-45c162444d357e18b333e94973a39b9d71c7604d.tar.gz yuzu-45c162444d357e18b333e94973a39b9d71c7604d.tar.xz yuzu-45c162444d357e18b333e94973a39b9d71c7604d.zip | |
shader/half_set_predicate: Fix HSETP2 implementation
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/shader/decode/half_set_predicate.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 3 |
4 files changed, 23 insertions, 44 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 119073776..e19d502bc 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -254,10 +254,6 @@ public: | |||
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | private: | 256 | private: |
| 257 | using OperationDecompilerFn = std::string (GLSLDecompiler::*)(Operation); | ||
| 258 | using OperationDecompilersArray = | ||
| 259 | std::array<OperationDecompilerFn, static_cast<std::size_t>(OperationCode::Amount)>; | ||
| 260 | |||
| 261 | void DeclareVertex() { | 257 | void DeclareVertex() { |
| 262 | if (stage != ShaderStage::Vertex) | 258 | if (stage != ShaderStage::Vertex) |
| 263 | return; | 259 | return; |
| @@ -1400,14 +1396,10 @@ private: | |||
| 1400 | return fmt::format("{}[{}]", pair, VisitOperand(operation, 1, Type::Uint)); | 1396 | return fmt::format("{}[{}]", pair, VisitOperand(operation, 1, Type::Uint)); |
| 1401 | } | 1397 | } |
| 1402 | 1398 | ||
| 1403 | std::string LogicalAll2(Operation operation) { | 1399 | std::string LogicalAnd2(Operation operation) { |
| 1404 | return GenerateUnary(operation, "all", Type::Bool, Type::Bool2); | 1400 | return GenerateUnary(operation, "all", Type::Bool, Type::Bool2); |
| 1405 | } | 1401 | } |
| 1406 | 1402 | ||
| 1407 | std::string LogicalAny2(Operation operation) { | ||
| 1408 | return GenerateUnary(operation, "any", Type::Bool, Type::Bool2); | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | template <bool with_nan> | 1403 | template <bool with_nan> |
| 1412 | std::string GenerateHalfComparison(Operation operation, const std::string& compare_op) { | 1404 | std::string GenerateHalfComparison(Operation operation, const std::string& compare_op) { |
| 1413 | const std::string comparison{GenerateBinaryCall(operation, compare_op, Type::Bool2, | 1405 | const std::string comparison{GenerateBinaryCall(operation, compare_op, Type::Bool2, |
| @@ -1714,7 +1706,7 @@ private: | |||
| 1714 | return "utof(gl_WorkGroupID"s + GetSwizzle(element) + ')'; | 1706 | return "utof(gl_WorkGroupID"s + GetSwizzle(element) + ')'; |
| 1715 | } | 1707 | } |
| 1716 | 1708 | ||
| 1717 | static constexpr OperationDecompilersArray operation_decompilers = { | 1709 | static constexpr std::array operation_decompilers = { |
| 1718 | &GLSLDecompiler::Assign, | 1710 | &GLSLDecompiler::Assign, |
| 1719 | 1711 | ||
| 1720 | &GLSLDecompiler::Select, | 1712 | &GLSLDecompiler::Select, |
| @@ -1798,8 +1790,7 @@ private: | |||
| 1798 | &GLSLDecompiler::LogicalXor, | 1790 | &GLSLDecompiler::LogicalXor, |
| 1799 | &GLSLDecompiler::LogicalNegate, | 1791 | &GLSLDecompiler::LogicalNegate, |
| 1800 | &GLSLDecompiler::LogicalPick2, | 1792 | &GLSLDecompiler::LogicalPick2, |
| 1801 | &GLSLDecompiler::LogicalAll2, | 1793 | &GLSLDecompiler::LogicalAnd2, |
| 1802 | &GLSLDecompiler::LogicalAny2, | ||
| 1803 | 1794 | ||
| 1804 | &GLSLDecompiler::LogicalLessThan<Type::Float>, | 1795 | &GLSLDecompiler::LogicalLessThan<Type::Float>, |
| 1805 | &GLSLDecompiler::LogicalEqual<Type::Float>, | 1796 | &GLSLDecompiler::LogicalEqual<Type::Float>, |
| @@ -1863,6 +1854,7 @@ private: | |||
| 1863 | &GLSLDecompiler::WorkGroupId<1>, | 1854 | &GLSLDecompiler::WorkGroupId<1>, |
| 1864 | &GLSLDecompiler::WorkGroupId<2>, | 1855 | &GLSLDecompiler::WorkGroupId<2>, |
| 1865 | }; | 1856 | }; |
| 1857 | static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); | ||
| 1866 | 1858 | ||
| 1867 | std::string GetRegister(u32 index) const { | 1859 | std::string GetRegister(u32 index) const { |
| 1868 | return GetDeclarationWithSuffix(index, "gpr"); | 1860 | return GetDeclarationWithSuffix(index, "gpr"); |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 9b2d8e987..d267712c9 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -205,10 +205,6 @@ public: | |||
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | private: | 207 | private: |
| 208 | using OperationDecompilerFn = Id (SPIRVDecompiler::*)(Operation); | ||
| 209 | using OperationDecompilersArray = | ||
| 210 | std::array<OperationDecompilerFn, static_cast<std::size_t>(OperationCode::Amount)>; | ||
| 211 | |||
| 212 | static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount); | 208 | static constexpr auto INTERNAL_FLAGS_COUNT = static_cast<std::size_t>(InternalFlag::Amount); |
| 213 | 209 | ||
| 214 | void AllocateBindings() { | 210 | void AllocateBindings() { |
| @@ -804,12 +800,7 @@ private: | |||
| 804 | return {}; | 800 | return {}; |
| 805 | } | 801 | } |
| 806 | 802 | ||
| 807 | Id LogicalAll2(Operation operation) { | 803 | Id LogicalAnd2(Operation operation) { |
| 808 | UNIMPLEMENTED(); | ||
| 809 | return {}; | ||
| 810 | } | ||
| 811 | |||
| 812 | Id LogicalAny2(Operation operation) { | ||
| 813 | UNIMPLEMENTED(); | 804 | UNIMPLEMENTED(); |
| 814 | return {}; | 805 | return {}; |
| 815 | } | 806 | } |
| @@ -1206,7 +1197,7 @@ private: | |||
| 1206 | return {}; | 1197 | return {}; |
| 1207 | } | 1198 | } |
| 1208 | 1199 | ||
| 1209 | static constexpr OperationDecompilersArray operation_decompilers = { | 1200 | static constexpr std::array operation_decompilers = { |
| 1210 | &SPIRVDecompiler::Assign, | 1201 | &SPIRVDecompiler::Assign, |
| 1211 | 1202 | ||
| 1212 | &SPIRVDecompiler::Ternary<&Module::OpSelect, Type::Float, Type::Bool, Type::Float, | 1203 | &SPIRVDecompiler::Ternary<&Module::OpSelect, Type::Float, Type::Bool, Type::Float, |
| @@ -1291,8 +1282,7 @@ private: | |||
| 1291 | &SPIRVDecompiler::Binary<&Module::OpLogicalNotEqual, Type::Bool>, | 1282 | &SPIRVDecompiler::Binary<&Module::OpLogicalNotEqual, Type::Bool>, |
| 1292 | &SPIRVDecompiler::Unary<&Module::OpLogicalNot, Type::Bool>, | 1283 | &SPIRVDecompiler::Unary<&Module::OpLogicalNot, Type::Bool>, |
| 1293 | &SPIRVDecompiler::LogicalPick2, | 1284 | &SPIRVDecompiler::LogicalPick2, |
| 1294 | &SPIRVDecompiler::LogicalAll2, | 1285 | &SPIRVDecompiler::LogicalAnd2, |
| 1295 | &SPIRVDecompiler::LogicalAny2, | ||
| 1296 | 1286 | ||
| 1297 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::Float>, | 1287 | &SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool, Type::Float>, |
| 1298 | &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::Float>, | 1288 | &SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool, Type::Float>, |
| @@ -1357,6 +1347,7 @@ private: | |||
| 1357 | &SPIRVDecompiler::WorkGroupId<1>, | 1347 | &SPIRVDecompiler::WorkGroupId<1>, |
| 1358 | &SPIRVDecompiler::WorkGroupId<2>, | 1348 | &SPIRVDecompiler::WorkGroupId<2>, |
| 1359 | }; | 1349 | }; |
| 1350 | static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); | ||
| 1360 | 1351 | ||
| 1361 | const VKDevice& device; | 1352 | const VKDevice& device; |
| 1362 | const ShaderIR& ir; | 1353 | const ShaderIR& ir; |
diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp index ff41fb2b5..ad180d6df 100644 --- a/src/video_core/shader/decode/half_set_predicate.cpp +++ b/src/video_core/shader/decode/half_set_predicate.cpp | |||
| @@ -51,26 +51,23 @@ u32 ShaderIR::DecodeHalfSetPredicate(NodeBlock& bb, u32 pc) { | |||
| 51 | op_b = Immediate(0); | 51 | op_b = Immediate(0); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | // We can't use the constant predicate as destination. | ||
| 55 | ASSERT(instr.hsetp2.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||
| 56 | |||
| 57 | const Node second_pred = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0); | ||
| 58 | |||
| 59 | const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op); | 54 | const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op); |
| 60 | const OperationCode pair_combiner = | 55 | const Node pred39 = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred); |
| 61 | h_and ? OperationCode::LogicalAll2 : OperationCode::LogicalAny2; | ||
| 62 | 56 | ||
| 63 | const Node comparison = GetPredicateComparisonHalf(cond, op_a, op_b); | 57 | const auto Write = [&](u64 dest, Node src) { |
| 64 | const Node first_pred = Operation(pair_combiner, comparison); | 58 | SetPredicate(bb, dest, Operation(combiner, std::move(src), pred39)); |
| 59 | }; | ||
| 65 | 60 | ||
| 66 | // Set the primary predicate to the result of Predicate OP SecondPredicate | 61 | const Node comparison = GetPredicateComparisonHalf(cond, op_a, op_b); |
| 67 | const Node value = Operation(combiner, first_pred, second_pred); | 62 | const u64 first = instr.hsetp2.pred0; |
| 68 | SetPredicate(bb, instr.hsetp2.pred3, value); | 63 | const u64 second = instr.hsetp2.pred3; |
| 69 | 64 | if (h_and) { | |
| 70 | if (instr.hsetp2.pred0 != static_cast<u64>(Pred::UnusedIndex)) { | 65 | const Node joined = Operation(OperationCode::LogicalAnd2, comparison); |
| 71 | // Set the secondary predicate to the result of !Predicate OP SecondPredicate, if enabled | 66 | Write(first, joined); |
| 72 | const Node negated_pred = Operation(OperationCode::LogicalNegate, first_pred); | 67 | Write(second, Operation(OperationCode::LogicalNegate, joined)); |
| 73 | SetPredicate(bb, instr.hsetp2.pred0, Operation(combiner, negated_pred, second_pred)); | 68 | } else { |
| 69 | Write(first, Operation(OperationCode::LogicalPick2, comparison, Immediate(0u))); | ||
| 70 | Write(second, Operation(OperationCode::LogicalPick2, comparison, Immediate(1u))); | ||
| 74 | } | 71 | } |
| 75 | 72 | ||
| 76 | return pc; | 73 | return pc; |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 7427ed896..715184d67 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -101,8 +101,7 @@ enum class OperationCode { | |||
| 101 | LogicalXor, /// (bool a, bool b) -> bool | 101 | LogicalXor, /// (bool a, bool b) -> bool |
| 102 | LogicalNegate, /// (bool a) -> bool | 102 | LogicalNegate, /// (bool a) -> bool |
| 103 | LogicalPick2, /// (bool2 pair, uint index) -> bool | 103 | LogicalPick2, /// (bool2 pair, uint index) -> bool |
| 104 | LogicalAll2, /// (bool2 a) -> bool | 104 | LogicalAnd2, /// (bool2 a) -> bool |
| 105 | LogicalAny2, /// (bool2 a) -> bool | ||
| 106 | 105 | ||
| 107 | LogicalFLessThan, /// (float a, float b) -> bool | 106 | LogicalFLessThan, /// (float a, float b) -> bool |
| 108 | LogicalFEqual, /// (float a, float b) -> bool | 107 | LogicalFEqual, /// (float a, float b) -> bool |