diff options
| author | 2019-11-01 00:34:38 -0300 | |
|---|---|---|
| committer | 2019-12-09 23:25:21 -0300 | |
| commit | 6233b1db089686e1ea0dde68278e9086981d6f76 (patch) | |
| tree | 42199ac76ce7f34d543d77a5a70cc3e5f46e2576 /src/video_core | |
| parent | Merge pull request #3205 from ReinUsesLisp/vk-device (diff) | |
| download | yuzu-6233b1db089686e1ea0dde68278e9086981d6f76.tar.gz yuzu-6233b1db089686e1ea0dde68278e9086981d6f76.tar.xz yuzu-6233b1db089686e1ea0dde68278e9086981d6f76.zip | |
shader_ir/memory: Implement patch stores
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 3 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 34 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 20 | ||||
| -rw-r--r-- | src/video_core/shader/track.cpp | 1 |
4 files changed, 38 insertions, 20 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 8b7dcbe9d..7703a76a3 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -98,10 +98,11 @@ union Attribute { | |||
| 98 | BitField<20, 10, u64> immediate; | 98 | BitField<20, 10, u64> immediate; |
| 99 | BitField<22, 2, u64> element; | 99 | BitField<22, 2, u64> element; |
| 100 | BitField<24, 6, Index> index; | 100 | BitField<24, 6, Index> index; |
| 101 | BitField<31, 1, u64> patch; | ||
| 101 | BitField<47, 3, AttributeSize> size; | 102 | BitField<47, 3, AttributeSize> size; |
| 102 | 103 | ||
| 103 | bool IsPhysical() const { | 104 | bool IsPhysical() const { |
| 104 | return element == 0 && static_cast<u64>(index.Value()) == 0; | 105 | return patch == 0 && element == 0 && static_cast<u64>(index.Value()) == 0; |
| 105 | } | 106 | } |
| 106 | } fmt20; | 107 | } fmt20; |
| 107 | 108 | ||
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/node.h b/src/video_core/shader/node.h index b2576bdd6..8f4811c88 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -213,13 +213,14 @@ class PredicateNode; | |||
| 213 | class AbufNode; | 213 | class AbufNode; |
| 214 | class CbufNode; | 214 | class CbufNode; |
| 215 | class LmemNode; | 215 | class LmemNode; |
| 216 | class PatchNode; | ||
| 216 | class SmemNode; | 217 | class SmemNode; |
| 217 | class GmemNode; | 218 | class GmemNode; |
| 218 | class CommentNode; | 219 | class CommentNode; |
| 219 | 220 | ||
| 220 | using NodeData = | 221 | using NodeData = std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, |
| 221 | std::variant<OperationNode, ConditionalNode, GprNode, ImmediateNode, InternalFlagNode, | 222 | InternalFlagNode, PredicateNode, AbufNode, PatchNode, CbufNode, |
| 222 | PredicateNode, AbufNode, CbufNode, LmemNode, SmemNode, GmemNode, CommentNode>; | 223 | LmemNode, SmemNode, GmemNode, CommentNode>; |
| 223 | using Node = std::shared_ptr<NodeData>; | 224 | using Node = std::shared_ptr<NodeData>; |
| 224 | using Node4 = std::array<Node, 4>; | 225 | using Node4 = std::array<Node, 4>; |
| 225 | using NodeBlock = std::vector<Node>; | 226 | using NodeBlock = std::vector<Node>; |
| @@ -542,6 +543,19 @@ private: | |||
| 542 | u32 element{}; | 543 | u32 element{}; |
| 543 | }; | 544 | }; |
| 544 | 545 | ||
| 546 | /// Patch memory (used to communicate tessellation stages). | ||
| 547 | class PatchNode final { | ||
| 548 | public: | ||
| 549 | explicit PatchNode(u32 offset) : offset{offset} {} | ||
| 550 | |||
| 551 | u32 GetOffset() const { | ||
| 552 | return offset; | ||
| 553 | } | ||
| 554 | |||
| 555 | private: | ||
| 556 | u32 offset{}; | ||
| 557 | }; | ||
| 558 | |||
| 545 | /// Constant buffer node, usually mapped to uniform buffers in GLSL | 559 | /// Constant buffer node, usually mapped to uniform buffers in GLSL |
| 546 | class CbufNode final { | 560 | class CbufNode final { |
| 547 | public: | 561 | public: |
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 | ||
| 12 | namespace VideoCommon::Shader { | 13 | namespace VideoCommon::Shader { |