summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-04-30 18:12:30 -0300
committerGravatar ReinUsesLisp2019-05-02 21:46:25 -0300
commit71aa9d08772eb07ccae7b141e032e6e7e57871a1 (patch)
tree8cd11960894f23ff14b0129c247f2927dc0e815c /src
parentgl_shader_decompiler: Abstract generic attribute operations (diff)
downloadyuzu-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.h4
-rw-r--r--src/video_core/shader/decode/memory.cpp9
-rw-r--r--src/video_core/shader/shader_ir.cpp5
-rw-r--r--src/video_core/shader/shader_ir.h20
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
97Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) {
98 use_physical_attributes = true;
99 return StoreNode(AbufNode(GetRegister(physical_address), buffer));
100}
101
97Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { 102Node 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
484private: 495private:
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