shader_ir/memory: Implement physical input attributes

This commit is contained in:
ReinUsesLisp 2019-04-30 18:12:30 -03:00
parent b7d412c99b
commit 71aa9d0877
4 changed files with 32 additions and 6 deletions

View File

@ -98,6 +98,10 @@ union Attribute {
BitField<22, 2, u64> element; BitField<22, 2, u64> element;
BitField<24, 6, Index> index; BitField<24, 6, Index> index;
BitField<47, 3, AttributeSize> size; BitField<47, 3, AttributeSize> size;
bool IsPhysical() const {
return element == 0 && static_cast<u64>(index.Value()) == 0;
}
} fmt20; } fmt20;
union { union {

View File

@ -50,13 +50,16 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0,
"Unaligned attribute loads are not supported"); "Unaligned attribute loads are not supported");
const Node buffer{GetRegister(instr.gpr39)};
u64 next_element = instr.attribute.fmt20.element; u64 next_element = instr.attribute.fmt20.element;
auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value());
const auto LoadNextElement = [&](u32 reg_offset) { const auto LoadNextElement = [&](u32 reg_offset) {
const Node buffer = GetRegister(instr.gpr39); const Node attribute{instr.attribute.fmt20.IsPhysical()
const Node attribute = ? GetPhysicalInputAttribute(instr.gpr8, buffer)
GetInputAttribute(static_cast<Attribute::Index>(next_index), next_element, buffer); : GetInputAttribute(static_cast<Attribute::Index>(next_index),
next_element, buffer)};
SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute); SetRegister(bb, instr.gpr0.Value() + reg_offset, attribute);

View File

@ -94,6 +94,11 @@ Node ShaderIR::GetInputAttribute(Attribute::Index index, u64 element, Node buffe
return StoreNode(AbufNode(index, static_cast<u32>(element), buffer)); return StoreNode(AbufNode(index, static_cast<u32>(element), buffer));
} }
Node ShaderIR::GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer) {
use_physical_attributes = true;
return StoreNode(AbufNode(GetRegister(physical_address), buffer));
}
Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) { Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buffer) {
if (index == Attribute::Index::ClipDistances0123 || if (index == Attribute::Index::ClipDistances0123 ||
index == Attribute::Index::ClipDistances4567) { index == Attribute::Index::ClipDistances4567) {

View File

@ -469,6 +469,9 @@ public:
Node buffer = {}) Node buffer = {})
: buffer{buffer}, index{index}, element{element} {} : buffer{buffer}, index{index}, element{element} {}
explicit constexpr AbufNode(Node physical_address, Node buffer = {})
: physical_address{physical_address}, buffer{buffer} {}
Tegra::Shader::Attribute::Index GetIndex() const { Tegra::Shader::Attribute::Index GetIndex() const {
return index; return index;
} }
@ -481,10 +484,19 @@ public:
return buffer; return buffer;
} }
bool IsPhysicalBuffer() const {
return physical_address != nullptr;
}
Node GetPhysicalAddress() const {
return physical_address;
}
private: private:
const Node buffer; Node physical_address{};
const Tegra::Shader::Attribute::Index index; Node buffer{};
const u32 element; Tegra::Shader::Attribute::Index index{};
u32 element{};
}; };
/// Constant buffer node, usually mapped to uniform buffers in GLSL /// Constant buffer node, usually mapped to uniform buffers in GLSL
@ -691,6 +703,8 @@ private:
Node GetPredicate(bool immediate); Node GetPredicate(bool immediate);
/// Generates a node representing an input attribute. Keeps track of used attributes. /// Generates a node representing an input attribute. Keeps track of used attributes.
Node GetInputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer = {}); Node GetInputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer = {});
/// Generates a node representing a physical input attribute.
Node GetPhysicalInputAttribute(Tegra::Shader::Register physical_address, Node buffer = {});
/// Generates a node representing an output attribute. Keeps track of used attributes. /// Generates a node representing an output attribute. Keeps track of used attributes.
Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer); Node GetOutputAttribute(Tegra::Shader::Attribute::Index index, u64 element, Node buffer);
/// Generates a node representing an internal flag /// Generates a node representing an internal flag