shader: Teach global memory base tracker to follow vectors

This commit is contained in:
ReinUsesLisp 2021-06-23 01:32:47 -03:00 committed by ameerj
parent 97e80dda55
commit 04ef2160f9

View file

@ -253,12 +253,12 @@ struct LowAddrInfo {
/// Tries to track the first 32-bits of a global memory instruction /// Tries to track the first 32-bits of a global memory instruction
std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) { std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
// The first argument is the low level GPU pointer to the global memory instruction // The first argument is the low level GPU pointer to the global memory instruction
const IR::U64 addr{inst->Arg(0)}; const IR::Value addr{inst->Arg(0)};
if (addr.IsImmediate()) { if (addr.IsImmediate()) {
// Not much we can do if it's an immediate // Not much we can do if it's an immediate
return std::nullopt; return std::nullopt;
} }
// This address is expected to either be a PackUint2x32 or a IAdd64 // This address is expected to either be a PackUint2x32, a IAdd64, or a CompositeConstructU32x2
IR::Inst* addr_inst{addr.InstRecursive()}; IR::Inst* addr_inst{addr.InstRecursive()};
s32 imm_offset{0}; s32 imm_offset{0};
if (addr_inst->GetOpcode() == IR::Opcode::IAdd64) { if (addr_inst->GetOpcode() == IR::Opcode::IAdd64) {
@ -274,25 +274,24 @@ std::optional<LowAddrInfo> TrackLowAddress(IR::Inst* inst) {
if (iadd_addr.IsImmediate()) { if (iadd_addr.IsImmediate()) {
return std::nullopt; return std::nullopt;
} }
addr_inst = iadd_addr.Inst(); addr_inst = iadd_addr.InstRecursive();
}
// With IAdd64 handled, now PackUint2x32 is expected without exceptions
if (addr_inst->GetOpcode() != IR::Opcode::PackUint2x32) {
return std::nullopt;
} }
// With IAdd64 handled, now PackUint2x32 is expected
if (addr_inst->GetOpcode() == IR::Opcode::PackUint2x32) {
// PackUint2x32 is expected to be generated from a vector // PackUint2x32 is expected to be generated from a vector
const IR::Value vector{addr_inst->Arg(0)}; const IR::Value vector{addr_inst->Arg(0)};
if (vector.IsImmediate()) { if (vector.IsImmediate()) {
return std::nullopt; return std::nullopt;
} }
// This vector is expected to be a CompositeConstructU32x2 addr_inst = vector.InstRecursive();
IR::Inst* const vector_inst{vector.InstRecursive()}; }
if (vector_inst->GetOpcode() != IR::Opcode::CompositeConstructU32x2) { // The vector is expected to be a CompositeConstructU32x2
if (addr_inst->GetOpcode() != IR::Opcode::CompositeConstructU32x2) {
return std::nullopt; return std::nullopt;
} }
// Grab the first argument from the CompositeConstructU32x2, this is the low address. // Grab the first argument from the CompositeConstructU32x2, this is the low address.
return LowAddrInfo{ return LowAddrInfo{
.value{IR::U32{vector_inst->Arg(0)}}, .value{IR::U32{addr_inst->Arg(0)}},
.imm_offset = imm_offset, .imm_offset = imm_offset,
}; };
} }