summaryrefslogtreecommitdiff
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-12-10 08:01:41 -0400
committerGravatar GitHub2019-12-10 08:01:41 -0400
commit6edadef96d57cb021d0131929d5a122ae102ad9e (patch)
treee7f42fb2af3b1d83665725db9034d8fb6f3d6c78 /src/video_core/shader
parentMerge pull request #3205 from ReinUsesLisp/vk-device (diff)
parentvk_shader_decompiler: Fix build issues on old gcc versions (diff)
downloadyuzu-6edadef96d57cb021d0131929d5a122ae102ad9e.tar.gz
yuzu-6edadef96d57cb021d0131929d5a122ae102ad9e.tar.xz
yuzu-6edadef96d57cb021d0131929d5a122ae102ad9e.zip
Merge pull request #3208 from ReinUsesLisp/vk-shader-decompiler
vk_shader_decompiler: Add tessellation and misc changes
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/memory.cpp34
-rw-r--r--src/video_core/shader/decode/other.cpp2
-rw-r--r--src/video_core/shader/decode/warp.cpp3
-rw-r--r--src/video_core/shader/node.h21
-rw-r--r--src/video_core/shader/shader_ir.h5
-rw-r--r--src/video_core/shader/track.cpp1
6 files changed, 47 insertions, 19 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 335d78146..78e92f52e 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -21,6 +21,7 @@ using Tegra::Shader::OpCode;
21using Tegra::Shader::Register; 21using Tegra::Shader::Register;
22 22
23namespace { 23namespace {
24
24u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) { 25u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) {
25 switch (uniform_type) { 26 switch (uniform_type) {
26 case Tegra::Shader::UniformType::Single: 27 case Tegra::Shader::UniformType::Single:
@@ -35,6 +36,7 @@ u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) {
35 return 1; 36 return 1;
36 } 37 }
37} 38}
39
38} // Anonymous namespace 40} // Anonymous namespace
39 41
40u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { 42u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
@@ -196,28 +198,28 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
196 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, 198 UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0,
197 "Unaligned attribute loads are not supported"); 199 "Unaligned attribute loads are not supported");
198 200
199 u64 next_element = instr.attribute.fmt20.element; 201 u64 element = instr.attribute.fmt20.element;
200 auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); 202 auto index = static_cast<u64>(instr.attribute.fmt20.index.Value());
201 203
202 const auto StoreNextElement = [&](u32 reg_offset) { 204 const u32 num_words = static_cast<u32>(instr.attribute.fmt20.size.Value()) + 1;
203 const auto dest = GetOutputAttribute(static_cast<Attribute::Index>(next_index), 205 for (u32 reg_offset = 0; reg_offset < num_words; ++reg_offset) {
204 next_element, GetRegister(instr.gpr39)); 206 Node dest;
207 if (instr.attribute.fmt20.patch) {
208 const u32 offset = static_cast<u32>(index) * 4 + static_cast<u32>(element);
209 dest = MakeNode<PatchNode>(offset);
210 } else {
211 dest = GetOutputAttribute(static_cast<Attribute::Index>(index), element,
212 GetRegister(instr.gpr39));
213 }
205 const auto src = GetRegister(instr.gpr0.Value() + reg_offset); 214 const auto src = GetRegister(instr.gpr0.Value() + reg_offset);
206 215
207 bb.push_back(Operation(OperationCode::Assign, dest, src)); 216 bb.push_back(Operation(OperationCode::Assign, dest, src));
208 217
209 // Load the next attribute element into the following register. If the element 218 // Load the next attribute element into the following register. If the element to load
210 // to load goes beyond the vec4 size, load the first element of the next 219 // goes beyond the vec4 size, load the first element of the next attribute.
211 // attribute. 220 element = (element + 1) % 4;
212 next_element = (next_element + 1) % 4; 221 index = index + (element == 0 ? 1 : 0);
213 next_index = next_index + (next_element == 0 ? 1 : 0);
214 };
215
216 const u32 num_words = static_cast<u32>(instr.attribute.fmt20.size.Value()) + 1;
217 for (u32 reg_offset = 0; reg_offset < num_words; ++reg_offset) {
218 StoreNextElement(reg_offset);
219 } 222 }
220
221 break; 223 break;
222 } 224 }
223 case OpCode::Id::ST_L: 225 case OpCode::Id::ST_L:
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index 17cd45d3c..5c802886b 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -69,6 +69,8 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
69 case OpCode::Id::MOV_SYS: { 69 case OpCode::Id::MOV_SYS: {
70 const Node value = [this, instr] { 70 const Node value = [this, instr] {
71 switch (instr.sys20) { 71 switch (instr.sys20) {
72 case SystemVariable::InvocationId:
73 return Operation(OperationCode::InvocationId);
72 case SystemVariable::Ydirection: 74 case SystemVariable::Ydirection:
73 return Operation(OperationCode::YNegate); 75 return Operation(OperationCode::YNegate);
74 case SystemVariable::InvocationInfo: 76 case SystemVariable::InvocationInfo:
diff --git a/src/video_core/shader/decode/warp.cpp b/src/video_core/shader/decode/warp.cpp
index d98d0e1dd..11b77f795 100644
--- a/src/video_core/shader/decode/warp.cpp
+++ b/src/video_core/shader/decode/warp.cpp
@@ -38,6 +38,9 @@ u32 ShaderIR::DecodeWarp(NodeBlock& bb, u32 pc) {
38 const Instruction instr = {program_code[pc]}; 38 const Instruction instr = {program_code[pc]};
39 const auto opcode = OpCode::Decode(instr); 39 const auto opcode = OpCode::Decode(instr);
40 40
41 // Signal the backend that this shader uses warp instructions.
42 uses_warps = true;
43
41 switch (opcode->get().GetId()) { 44 switch (opcode->get().GetId()) {
42 case OpCode::Id::VOTE: { 45 case OpCode::Id::VOTE: {
43 const Node value = GetPredicate(instr.vote.value, instr.vote.negate_value != 0); 46 const Node value = GetPredicate(instr.vote.value, instr.vote.negate_value != 0);
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index b2576bdd6..1a4d28ae9 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -172,6 +172,7 @@ enum class OperationCode {
172 EmitVertex, /// () -> void 172 EmitVertex, /// () -> void
173 EndPrimitive, /// () -> void 173 EndPrimitive, /// () -> void
174 174
175 InvocationId, /// () -> int
175 YNegate, /// () -> float 176 YNegate, /// () -> float
176 LocalInvocationIdX, /// () -> uint 177 LocalInvocationIdX, /// () -> uint
177 LocalInvocationIdY, /// () -> uint 178 LocalInvocationIdY, /// () -> uint
@@ -213,13 +214,14 @@ class PredicateNode;
213class AbufNode; 214class AbufNode;
214class CbufNode; 215class CbufNode;
215class LmemNode; 216class LmemNode;
217class PatchNode;
216class SmemNode; 218class SmemNode;
217class GmemNode; 219class GmemNode;
218class CommentNode; 220class CommentNode;
219 221
220using NodeData = 222using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode,
221 std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, InternalFlagNode, 223 InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode,
222 PredicateNode, AbufNode, CbufNode, LmemNode, SmemNode, GmemNode, CommentNode>; 224 LmemNode, SmemNode, GmemNode, CommentNode>;
223using Node = std::shared_ptr<NodeData>; 225using Node = std::shared_ptr<NodeData>;
224using Node4 = std::array<Node, 4>; 226using Node4 = std::array<Node, 4>;
225using NodeBlock = std::vector<Node>; 227using NodeBlock = std::vector<Node>;
@@ -542,6 +544,19 @@ private:
542 u32 element{}; 544 u32 element{};
543}; 545};
544 546
547/// Patch memory (used to communicate tessellation stages).
548class PatchNode final {
549public:
550 explicit PatchNode(u32 offset) : offset{offset} {}
551
552 u32 GetOffset() const {
553 return offset;
554 }
555
556private:
557 u32 offset{};
558};
559
545/// Constant buffer node, usually mapped to uniform buffers in GLSL 560/// Constant buffer node, usually mapped to uniform buffers in GLSL
546class CbufNode final { 561class CbufNode final {
547public: 562public:
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 2f71a50d2..580f84fcb 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -137,6 +137,10 @@ public:
137 return uses_vertex_id; 137 return uses_vertex_id;
138 } 138 }
139 139
140 bool UsesWarps() const {
141 return uses_warps;
142 }
143
140 bool HasPhysicalAttributes() const { 144 bool HasPhysicalAttributes() const {
141 return uses_physical_attributes; 145 return uses_physical_attributes;
142 } 146 }
@@ -415,6 +419,7 @@ private:
415 bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes 419 bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes
416 bool uses_instance_id{}; 420 bool uses_instance_id{};
417 bool uses_vertex_id{}; 421 bool uses_vertex_id{};
422 bool uses_warps{};
418 423
419 Tegra::Shader::Header header; 424 Tegra::Shader::Header header;
420}; 425};
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp
index 55f5949e4..165c79330 100644
--- a/src/video_core/shader/track.cpp
+++ b/src/video_core/shader/track.cpp
@@ -7,6 +7,7 @@
7#include <variant> 7#include <variant>
8 8
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "video_core/shader/node.h"
10#include "video_core/shader/shader_ir.h" 11#include "video_core/shader/shader_ir.h"
11 12
12namespace VideoCommon::Shader { 13namespace VideoCommon::Shader {