diff options
| author | 2019-04-30 18:12:30 -0300 | |
|---|---|---|
| committer | 2019-05-02 21:46:25 -0300 | |
| commit | 71aa9d08772eb07ccae7b141e032e6e7e57871a1 (patch) | |
| tree | 8cd11960894f23ff14b0129c247f2927dc0e815c /src | |
| parent | gl_shader_decompiler: Abstract generic attribute operations (diff) | |
| download | yuzu-71aa9d08772eb07ccae7b141e032e6e7e57871a1.tar.gz yuzu-71aa9d08772eb07ccae7b141e032e6e7e57871a1.tar.xz yuzu-71aa9d08772eb07ccae7b141e032e6e7e57871a1.zip | |
shader_ir/memory: Implement physical input attributes
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 4 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 20 |
4 files changed, 32 insertions, 6 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 766bb4f79..e4a9471b8 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -98,6 +98,10 @@ union Attribute { | |||
| 98 | BitField<22, 2, u64> element; | 98 | BitField<22, 2, u64> element; |
| 99 | BitField<24, 6, Index> index; | 99 | BitField<24, 6, Index> index; |
| 100 | BitField<47, 3, AttributeSize> size; | 100 | BitField<47, 3, AttributeSize> size; |
| 101 | |||
| 102 | bool IsPhysical() const { | ||
| 103 | return element == 0 && static_cast<u64>(index.Value()) == 0; | ||
| 104 | } | ||
| 101 | } fmt20; | 105 | } fmt20; |
| 102 | 106 | ||
| 103 | union { | 107 | union { |
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 84db4d4dc..339692295 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -50,13 +50,16 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 50 | UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, | 50 | UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, |
| 51 | "Unaligned attribute loads are not supported"); | 51 | "Unaligned attribute loads are not supported"); |
| 52 | 52 | ||
| 53 | const Node buffer{GetRegister(instr.gpr39)}; | ||
| 54 | |||
| 53 | u64 next_element = instr.attribute.fmt20.element; | 55 | u64 next_element = instr.attribute.fmt20.element; |
| 54 | auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); | 56 | auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); |
| 55 | 57 | ||
| 56 | const auto LoadNextElement = [&](u32 reg_offset) { | 58 | const auto LoadNextElement = [&](u32 reg_offset) { |
| 57 | const Node buffer = GetRegister(instr.gpr39); | 59 | const Node attribute{instr.attribute.fmt20.IsPhysical() |
| 58 | const Node attribute = | 60 | ? GetPhysicalInputAttribute(instr.gpr8, buffer) |
| 59 | GetInputAttribute(static_cast<Attribute::Index>(next_index), next_element, buffer); | 61 | : GetInputAttribute(static_cast<Attribute::Index>(next_index), |
| 62 | next_element, buffer)}; | ||
| 60 | 63 | ||
| 61 | SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute); | 64 | SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute); |
| 62 | 65 | ||
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 0307ae5b0..947a372a2 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -94,6 +94,11 @@ Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffe | |||
| 94 | return StoreNode(AbufNode(index, static_cast<u32>(element), buffer)); | 94 | return StoreNode(AbufNode(index, static_cast<u32>(element), buffer)); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) { | ||
| 98 | use_physical_attributes = true; | ||
| 99 | return StoreNode(AbufNode(GetRegister(physical_address), buffer)); | ||
| 100 | } | ||
| 101 | |||
| 97 | Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { | 102 | Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { |
| 98 | if (index == Attribute::Index::ClipDistances0123 || | 103 | if (index == Attribute::Index::ClipDistances0123 || |
| 99 | index == Attribute::Index::ClipDistances4567) { | 104 | index == Attribute::Index::ClipDistances4567) { |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 6aff64394..3a1164d4f 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -469,6 +469,9 @@ public: | |||
| 469 | Node buffer = {}) | 469 | Node buffer = {}) |
| 470 | : buffer{buffer}, index{index}, element{element} {} | 470 | : buffer{buffer}, index{index}, element{element} {} |
| 471 | 471 | ||
| 472 | explicit constexpr AbufNode(Node physical_address, Node buffer = {}) | ||
| 473 | : physical_address{physical_address}, buffer{buffer} {} | ||
| 474 | |||
| 472 | Tegra::Shader::Attribute::Index GetIndex() const { | 475 | Tegra::Shader::Attribute::Index GetIndex() const { |
| 473 | return index; | 476 | return index; |
| 474 | } | 477 | } |
| @@ -481,10 +484,19 @@ public: | |||
| 481 | return buffer; | 484 | return buffer; |
| 482 | } | 485 | } |
| 483 | 486 | ||
| 487 | bool IsPhysicalBuffer() const { | ||
| 488 | return physical_address != nullptr; | ||
| 489 | } | ||
| 490 | |||
| 491 | Node GetPhysicalAddress() const { | ||
| 492 | return physical_address; | ||
| 493 | } | ||
| 494 | |||
| 484 | private: | 495 | private: |
| 485 | const Node buffer; | 496 | Node physical_address{}; |
| 486 | const Tegra::Shader::Attribute::Index index; | 497 | Node buffer{}; |
| 487 | const u32 element; | 498 | Tegra::Shader::Attribute::Index index{}; |
| 499 | u32 element{}; | ||
| 488 | }; | 500 | }; |
| 489 | 501 | ||
| 490 | /// Constant buffer node, usually mapped to uniform buffers in GLSL | 502 | /// Constant buffer node, usually mapped to uniform buffers in GLSL |
| @@ -691,6 +703,8 @@ private: | |||
| 691 | Node GetPredicate(bool immediate); | 703 | Node GetPredicate(bool immediate); |
| 692 | /// Generates a node representing an input attribute. Keeps track of used attributes. | 704 | /// Generates a node representing an input attribute. Keeps track of used attributes. |
| 693 | Node GetInputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer = {}); | 705 | Node GetInputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer = {}); |
| 706 | /// Generates a node representing a physical input attribute. | ||
| 707 | Node GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer = {}); | ||
| 694 | /// Generates a node representing an output attribute. Keeps track of used attributes. | 708 | /// Generates a node representing an output attribute. Keeps track of used attributes. |
| 695 | Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); | 709 | Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); |
| 696 | /// Generates a node representing an internal flag | 710 | /// Generates a node representing an internal flag |