diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/shader/decode/other.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 8 |
4 files changed, 76 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6d4658c8b..e9f8d40db 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -31,6 +31,8 @@ using Tegra::Shader::IpaInterpMode; | |||
| 31 | using Tegra::Shader::IpaMode; | 31 | using Tegra::Shader::IpaMode; |
| 32 | using Tegra::Shader::IpaSampleMode; | 32 | using Tegra::Shader::IpaSampleMode; |
| 33 | using Tegra::Shader::Register; | 33 | using Tegra::Shader::Register; |
| 34 | |||
| 35 | using namespace std::string_literals; | ||
| 34 | using namespace VideoCommon::Shader; | 36 | using namespace VideoCommon::Shader; |
| 35 | 37 | ||
| 36 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 38 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| @@ -93,11 +95,9 @@ private: | |||
| 93 | }; | 95 | }; |
| 94 | 96 | ||
| 95 | /// Generates code to use for a swizzle operation. | 97 | /// Generates code to use for a swizzle operation. |
| 96 | std::string GetSwizzle(u32 elem) { | 98 | constexpr const char* GetSwizzle(u32 element) { |
| 97 | ASSERT(elem <= 3); | 99 | constexpr std::array<const char*, 4> swizzle = {".x", ".y", ".z", ".w"}; |
| 98 | std::string swizzle = "."; | 100 | return swizzle.at(element); |
| 99 | swizzle += "xyzw"[elem]; | ||
| 100 | return swizzle; | ||
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /// Translate topology | 103 | /// Translate topology |
| @@ -636,7 +636,7 @@ private: | |||
| 636 | if (stage != ShaderStage::Fragment) { | 636 | if (stage != ShaderStage::Fragment) { |
| 637 | return GeometryPass("position") + GetSwizzle(element); | 637 | return GeometryPass("position") + GetSwizzle(element); |
| 638 | } else { | 638 | } else { |
| 639 | return element == 3 ? "1.0f" : "gl_FragCoord" + GetSwizzle(element); | 639 | return element == 3 ? "1.0f" : ("gl_FragCoord"s + GetSwizzle(element)); |
| 640 | } | 640 | } |
| 641 | case Attribute::Index::PointCoord: | 641 | case Attribute::Index::PointCoord: |
| 642 | switch (element) { | 642 | switch (element) { |
| @@ -921,7 +921,7 @@ private: | |||
| 921 | target = [&]() -> std::string { | 921 | target = [&]() -> std::string { |
| 922 | switch (const auto attribute = abuf->GetIndex(); abuf->GetIndex()) { | 922 | switch (const auto attribute = abuf->GetIndex(); abuf->GetIndex()) { |
| 923 | case Attribute::Index::Position: | 923 | case Attribute::Index::Position: |
| 924 | return "position" + GetSwizzle(abuf->GetElement()); | 924 | return "position"s + GetSwizzle(abuf->GetElement()); |
| 925 | case Attribute::Index::PointSize: | 925 | case Attribute::Index::PointSize: |
| 926 | return "gl_PointSize"; | 926 | return "gl_PointSize"; |
| 927 | case Attribute::Index::ClipDistances0123: | 927 | case Attribute::Index::ClipDistances0123: |
| @@ -1526,6 +1526,16 @@ private: | |||
| 1526 | return "uintBitsToFloat(config_pack[2])"; | 1526 | return "uintBitsToFloat(config_pack[2])"; |
| 1527 | } | 1527 | } |
| 1528 | 1528 | ||
| 1529 | template <u32 element> | ||
| 1530 | std::string LocalInvocationId(Operation) { | ||
| 1531 | return "utof(gl_LocalInvocationID"s + GetSwizzle(element) + ')'; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | template <u32 element> | ||
| 1535 | std::string WorkGroupId(Operation) { | ||
| 1536 | return "utof(gl_WorkGroupID"s + GetSwizzle(element) + ')'; | ||
| 1537 | } | ||
| 1538 | |||
| 1529 | static constexpr OperationDecompilersArray operation_decompilers = { | 1539 | static constexpr OperationDecompilersArray operation_decompilers = { |
| 1530 | &GLSLDecompiler::Assign, | 1540 | &GLSLDecompiler::Assign, |
| 1531 | 1541 | ||
| @@ -1665,6 +1675,12 @@ private: | |||
| 1665 | &GLSLDecompiler::EndPrimitive, | 1675 | &GLSLDecompiler::EndPrimitive, |
| 1666 | 1676 | ||
| 1667 | &GLSLDecompiler::YNegate, | 1677 | &GLSLDecompiler::YNegate, |
| 1678 | &GLSLDecompiler::LocalInvocationId<0>, | ||
| 1679 | &GLSLDecompiler::LocalInvocationId<1>, | ||
| 1680 | &GLSLDecompiler::LocalInvocationId<2>, | ||
| 1681 | &GLSLDecompiler::WorkGroupId<0>, | ||
| 1682 | &GLSLDecompiler::WorkGroupId<1>, | ||
| 1683 | &GLSLDecompiler::WorkGroupId<2>, | ||
| 1668 | }; | 1684 | }; |
| 1669 | 1685 | ||
| 1670 | std::string GetRegister(u32 index) const { | 1686 | std::string GetRegister(u32 index) const { |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index b61a6d170..a5b25aeff 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -1035,6 +1035,18 @@ private: | |||
| 1035 | return {}; | 1035 | return {}; |
| 1036 | } | 1036 | } |
| 1037 | 1037 | ||
| 1038 | template <u32 element> | ||
| 1039 | Id LocalInvocationId(Operation) { | ||
| 1040 | UNIMPLEMENTED(); | ||
| 1041 | return {}; | ||
| 1042 | } | ||
| 1043 | |||
| 1044 | template <u32 element> | ||
| 1045 | Id WorkGroupId(Operation) { | ||
| 1046 | UNIMPLEMENTED(); | ||
| 1047 | return {}; | ||
| 1048 | } | ||
| 1049 | |||
| 1038 | Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, | 1050 | Id DeclareBuiltIn(spv::BuiltIn builtin, spv::StorageClass storage, Id type, |
| 1039 | const std::string& name) { | 1051 | const std::string& name) { |
| 1040 | const Id id = OpVariable(type, storage); | 1052 | const Id id = OpVariable(type, storage); |
| @@ -1291,6 +1303,12 @@ private: | |||
| 1291 | &SPIRVDecompiler::EndPrimitive, | 1303 | &SPIRVDecompiler::EndPrimitive, |
| 1292 | 1304 | ||
| 1293 | &SPIRVDecompiler::YNegate, | 1305 | &SPIRVDecompiler::YNegate, |
| 1306 | &SPIRVDecompiler::LocalInvocationId<0>, | ||
| 1307 | &SPIRVDecompiler::LocalInvocationId<1>, | ||
| 1308 | &SPIRVDecompiler::LocalInvocationId<2>, | ||
| 1309 | &SPIRVDecompiler::WorkGroupId<0>, | ||
| 1310 | &SPIRVDecompiler::WorkGroupId<1>, | ||
| 1311 | &SPIRVDecompiler::WorkGroupId<2>, | ||
| 1294 | }; | 1312 | }; |
| 1295 | 1313 | ||
| 1296 | const ShaderIR& ir; | 1314 | const ShaderIR& ir; |
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index ca7af72e1..a6c123573 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp | |||
| @@ -14,6 +14,7 @@ using Tegra::Shader::ConditionCode; | |||
| 14 | using Tegra::Shader::Instruction; | 14 | using Tegra::Shader::Instruction; |
| 15 | using Tegra::Shader::OpCode; | 15 | using Tegra::Shader::OpCode; |
| 16 | using Tegra::Shader::Register; | 16 | using Tegra::Shader::Register; |
| 17 | using Tegra::Shader::SystemVariable; | ||
| 17 | 18 | ||
| 18 | u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | 19 | u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { |
| 19 | const Instruction instr = {program_code[pc]}; | 20 | const Instruction instr = {program_code[pc]}; |
| @@ -59,20 +60,33 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { | |||
| 59 | break; | 60 | break; |
| 60 | } | 61 | } |
| 61 | case OpCode::Id::MOV_SYS: { | 62 | case OpCode::Id::MOV_SYS: { |
| 62 | switch (instr.sys20) { | 63 | const Node value = [&]() { |
| 63 | case Tegra::Shader::SystemVariable::InvocationInfo: { | 64 | switch (instr.sys20) { |
| 64 | LOG_WARNING(HW_GPU, "MOV_SYS instruction with InvocationInfo is incomplete"); | 65 | case SystemVariable::Ydirection: |
| 65 | SetRegister(bb, instr.gpr0, Immediate(0u)); | 66 | return Operation(OperationCode::YNegate); |
| 66 | break; | 67 | case SystemVariable::InvocationInfo: |
| 67 | } | 68 | LOG_WARNING(HW_GPU, "MOV_SYS instruction with InvocationInfo is incomplete"); |
| 68 | case Tegra::Shader::SystemVariable::Ydirection: { | 69 | return Immediate(0u); |
| 69 | // Config pack's third value is Y_NEGATE's state. | 70 | case SystemVariable::TidX: |
| 70 | SetRegister(bb, instr.gpr0, Operation(OperationCode::YNegate)); | 71 | return Operation(OperationCode::LocalInvocationIdX); |
| 71 | break; | 72 | case SystemVariable::TidY: |
| 72 | } | 73 | return Operation(OperationCode::LocalInvocationIdY); |
| 73 | default: | 74 | case SystemVariable::TidZ: |
| 74 | UNIMPLEMENTED_MSG("Unhandled system move: {}", static_cast<u32>(instr.sys20.Value())); | 75 | return Operation(OperationCode::LocalInvocationIdZ); |
| 75 | } | 76 | case SystemVariable::CtaIdX: |
| 77 | return Operation(OperationCode::WorkGroupIdX); | ||
| 78 | case SystemVariable::CtaIdY: | ||
| 79 | return Operation(OperationCode::WorkGroupIdY); | ||
| 80 | case SystemVariable::CtaIdZ: | ||
| 81 | return Operation(OperationCode::WorkGroupIdZ); | ||
| 82 | default: | ||
| 83 | UNIMPLEMENTED_MSG("Unhandled system move: {}", | ||
| 84 | static_cast<u32>(instr.sys20.Value())); | ||
| 85 | return Immediate(0u); | ||
| 86 | } | ||
| 87 | }(); | ||
| 88 | SetRegister(bb, instr.gpr0, value); | ||
| 89 | |||
| 76 | break; | 90 | break; |
| 77 | } | 91 | } |
| 78 | case OpCode::Id::BRA: { | 92 | case OpCode::Id::BRA: { |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 35f72bddb..ff7472e30 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -181,7 +181,13 @@ enum class OperationCode { | |||
| 181 | EmitVertex, /// () -> void | 181 | EmitVertex, /// () -> void |
| 182 | EndPrimitive, /// () -> void | 182 | EndPrimitive, /// () -> void |
| 183 | 183 | ||
| 184 | YNegate, /// () -> float | 184 | YNegate, /// () -> float |
| 185 | LocalInvocationIdX, /// () -> uint | ||
| 186 | LocalInvocationIdY, /// () -> uint | ||
| 187 | LocalInvocationIdZ, /// () -> uint | ||
| 188 | WorkGroupIdX, /// () -> uint | ||
| 189 | WorkGroupIdY, /// () -> uint | ||
| 190 | WorkGroupIdZ, /// () -> uint | ||
| 185 | 191 | ||
| 186 | Amount, | 192 | Amount, |
| 187 | }; | 193 | }; |