summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp30
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp18
-rw-r--r--src/video_core/shader/decode/other.cpp42
-rw-r--r--src/video_core/shader/shader_ir.h8
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;
31using Tegra::Shader::IpaMode; 31using Tegra::Shader::IpaMode;
32using Tegra::Shader::IpaSampleMode; 32using Tegra::Shader::IpaSampleMode;
33using Tegra::Shader::Register; 33using Tegra::Shader::Register;
34
35using namespace std::string_literals;
34using namespace VideoCommon::Shader; 36using namespace VideoCommon::Shader;
35 37
36using Maxwell = Tegra::Engines::Maxwell3D::Regs; 38using 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.
96std::string GetSwizzle(u32 elem) { 98constexpr 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;
14using Tegra::Shader::Instruction; 14using Tegra::Shader::Instruction;
15using Tegra::Shader::OpCode; 15using Tegra::Shader::OpCode;
16using Tegra::Shader::Register; 16using Tegra::Shader::Register;
17using Tegra::Shader::SystemVariable;
17 18
18u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) { 19u32 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};