diff options
| author | 2019-12-10 08:01:41 -0400 | |
|---|---|---|
| committer | 2019-12-10 08:01:41 -0400 | |
| commit | 6edadef96d57cb021d0131929d5a122ae102ad9e (patch) | |
| tree | e7f42fb2af3b1d83665725db9034d8fb6f3d6c78 /src/video_core/shader/decode | |
| parent | Merge pull request #3205 from ReinUsesLisp/vk-device (diff) | |
| parent | vk_shader_decompiler: Fix build issues on old gcc versions (diff) | |
| download | yuzu-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.cpp | 34 | ||||
| -rw-r--r-- | src/video_core/shader/decode/other.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/decode/warp.cpp | 3 |
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; | |||
| 21 | using Tegra::Shader::Register; | 21 | using Tegra::Shader::Register; |
| 22 | 22 | ||
| 23 | namespace { | 23 | namespace { |
| 24 | |||
| 24 | u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) { | 25 | u32 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 | ||
| 40 | u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | 42 | u32 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); |