Merge pull request #2995 from ReinUsesLisp/ignore-gmem

shader_ir/memory: Ignore global memory when tracking fails
master
Fernando Sahmkow 2019-10-22 13:22:43 +07:00 committed by GitHub
commit c4a0aa9207
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 18 deletions

@ -166,9 +166,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}(); }();
const auto [real_address_base, base_address, descriptor] = const auto [real_address_base, base_address, descriptor] =
TrackAndGetGlobalMemory(bb, instr, false); TrackGlobalMemory(bb, instr, false);
const u32 count = GetUniformTypeElementsCount(type); const u32 count = GetUniformTypeElementsCount(type);
if (!real_address_base || !base_address) {
// Tracking failed, load zeroes.
for (u32 i = 0; i < count; ++i) {
SetRegister(bb, instr.gpr0.Value() + i, Immediate(0.0f));
}
break;
}
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
const Node it_offset = Immediate(i * 4); const Node it_offset = Immediate(i * 4);
const Node real_address = const Node real_address =
@ -260,22 +268,19 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
}(); }();
const auto [real_address_base, base_address, descriptor] = const auto [real_address_base, base_address, descriptor] =
TrackAndGetGlobalMemory(bb, instr, true); TrackGlobalMemory(bb, instr, true);
if (!real_address_base || !base_address) {
// Encode in temporary registers like this: real_base_address, {registers_to_be_written...} // Tracking failed, skip the store.
SetTemporary(bb, 0, real_address_base); break;
}
const u32 count = GetUniformTypeElementsCount(type); const u32 count = GetUniformTypeElementsCount(type);
for (u32 i = 0; i < count; ++i) {
SetTemporary(bb, i + 1, GetRegister(instr.gpr0.Value() + i));
}
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
const Node it_offset = Immediate(i * 4); const Node it_offset = Immediate(i * 4);
const Node real_address = const Node real_address = Operation(OperationCode::UAdd, real_address_base, it_offset);
Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset);
const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); const Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
const Node value = GetRegister(instr.gpr0.Value() + i);
bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporary(i + 1))); bb.push_back(Operation(OperationCode::Assign, gmem, value));
} }
break; break;
} }
@ -301,7 +306,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
return pc; return pc;
} }
std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb, std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackGlobalMemory(NodeBlock& bb,
Instruction instr, Instruction instr,
bool is_write) { bool is_write) {
const auto addr_register{GetRegister(instr.gmem.gpr)}; const auto addr_register{GetRegister(instr.gmem.gpr)};
@ -309,7 +314,9 @@ std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeB
const auto [base_address, index, offset] = const auto [base_address, index, offset] =
TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size())); TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()));
ASSERT(base_address != nullptr); ASSERT_OR_EXECUTE_MSG(base_address != nullptr,
{ return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); },
"Global memory tracking failed");
bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset)));

@ -371,8 +371,9 @@ private:
std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code,
s64 cursor) const; s64 cursor) const;
std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory( std::tuple<Node, Node, GlobalMemoryBase> TrackGlobalMemory(NodeBlock& bb,
NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write); Tegra::Shader::Instruction instr,
bool is_write);
const ProgramCode& program_code; const ProgramCode& program_code;
const u32 main_offset; const u32 main_offset;