summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
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/decode
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/decode')
-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
3 files changed, 23 insertions, 16 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);