shader_ir/memory: Implement physical input attributes
This commit is contained in:
parent
b7d412c99b
commit
71aa9d0877
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Reference in New Issue