mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-21 08:12:09 -05:00
Merge pull request #7325 from Cleverdee/fix/image-table-nested-addend
fix(recompiler): fold chained immediate addends of image-table record offsets
This commit is contained in:
2 files changed
+44
-4
No files matched your search
@@ -1904,6 +1904,40 @@ void verifyPointerTableOffsetCarry() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void verifyChainedTableOffset() {
|
||||
using namespace ShaderRecompiler;
|
||||
namespace Abi = ImageTableAbi;
|
||||
static TableTexture textures[2];
|
||||
alignas(256) static std::array<std::uint32_t, 0x3000> root{};
|
||||
static std::array<std::uint32_t, 8> keys{};
|
||||
static std::array<std::uint32_t, 4> output{};
|
||||
const auto keysV = TableV(keys.data(), 0u, static_cast<std::uint32_t>(sizeof(keys)));
|
||||
const auto outputV = TableV(output.data(), 0u, static_cast<std::uint32_t>(sizeof(output)));
|
||||
std::copy(keysV.begin(), keysV.end(), root.begin());
|
||||
std::copy(outputV.begin(), outputV.end(), root.begin() + 4);
|
||||
const auto at = [&](std::uint32_t offset, std::array<std::uint32_t, 8> words) {
|
||||
std::copy(words.begin(), words.end(), root.begin() + offset / 4u);
|
||||
};
|
||||
at(0x60u + 3u * 32u, TableT(textures[0].bytes.data(), TableFormat8888UNorm, TableType2D));
|
||||
at(0x60u + 5u * 32u, TableT(textures[1].bytes.data(), TableFormat32UInt, TableType2D));
|
||||
const auto base = static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(root.data()));
|
||||
const std::array<std::uint32_t, 2> userData{static_cast<std::uint32_t>(base), static_cast<std::uint32_t>(base >> 32u)};
|
||||
const std::vector<std::uint32_t> code{0xf4080200u, 0xfa000000u, 0xf4080700u, 0xfa000010u, 0xf4080800u, 0xfa000020u, 0x7e200500u, 0x8f108210u, 0xf4200444u,
|
||||
0x20000000u, 0x8711ff11u, 0x000000ffu, 0x8f128511u, 0x8113a012u, 0x81149013u, 0xf4080900u, 0x26000040u, 0xf4080a00u, 0x28000040u, 0xf09c0f08u,
|
||||
0x01090000u, 0xe0700000u, 0x80070000u, 0xbf810000u};
|
||||
auto request = TableRequest(code, userData);
|
||||
request.shader.codeAddress = 0x37000u;
|
||||
const auto plan = GetResourcePlan(request);
|
||||
require(plan->info.images.size() == 1u && plan->info.images[0].table == 0u, "chained table offset: a T# whose second load offset adds to the first one's was not planned as a table");
|
||||
const auto& column = *plan->descriptorSources.at(plan->info.images[0].source).tableColumn;
|
||||
require(column.address && column.stride == 32u && column.addend == 0x20u && column.offset == 0x40u && column.maxKey == 0xffu && column.foldedAddend == 0x20u && column.foldedCarry == 16u, "chained table offset: the column is wrong");
|
||||
const auto compiled = CompileTable(request);
|
||||
const auto& snapshot = compiled.capture->snapshot.tables.tables.at(0);
|
||||
const auto& words = compiled.capture->snapshot.tables.words;
|
||||
require(snapshot.keys == 256u && (snapshot.codes[3] & Abi::PoisonFlag) == 0u && (snapshot.codes[5] & Abi::PoisonFlag) == 0u, "chained table offset: the records were not resolved");
|
||||
require(words.at(snapshot.codes[3]).dwords[0] == root[(0x60u + 3u * 32u) / 4u] && words.at(snapshot.codes[3]).dwords[7] == root[(0x60u + 3u * 32u) / 4u + 7u] && words.at(snapshot.codes[5]).dwords[0] == root[(0x60u + 5u * 32u) / 4u] && snapshot.codes[3] != snapshot.codes[5], "chained table offset: a record was read from the wrong offset");
|
||||
}
|
||||
|
||||
void verifyDescriptorPhis() {
|
||||
using namespace ShaderRecompiler;
|
||||
constexpr std::uint32_t Format8888UNorm = 56;
|
||||
@@ -5307,6 +5341,7 @@ int main(int argc, char** argv) {
|
||||
verifyScalarAddressRule();
|
||||
verifyPointerImageTable();
|
||||
verifyPointerTableOffsetCarry();
|
||||
verifyChainedTableOffset();
|
||||
std::cout << "Image table keys, maps, records and registration passed\n";
|
||||
return 0;
|
||||
}
|
||||
@@ -5338,6 +5373,7 @@ int main(int argc, char** argv) {
|
||||
verifyScalarAddressRule();
|
||||
verifyPointerImageTable();
|
||||
verifyPointerTableOffsetCarry();
|
||||
verifyChainedTableOffset();
|
||||
verifyDescriptorPhis();
|
||||
verifyUniformTableImage();
|
||||
verifyLaneSelectedDescriptors();
|
||||
|
||||
@@ -542,11 +542,15 @@ private:
|
||||
static IrValue* SplitImmediateAddend(IrValue* value, std::uint32_t& addend) {
|
||||
value = value->Resolve();
|
||||
addend = 0;
|
||||
if (value->Opcode() == IrOpcode::IAdd32 && value->ArgumentCount() == 2u) {
|
||||
if (immediateU32(value->Argument(0), addend)) return value->Argument(1)->Resolve();
|
||||
if (immediateU32(value->Argument(1), addend)) return value->Argument(0)->Resolve();
|
||||
while (value->Opcode() == IrOpcode::IAdd32 && value->ArgumentCount() == 2u) {
|
||||
std::uint32_t immediate = 0;
|
||||
IrValue* rest = nullptr;
|
||||
if (immediateU32(value->Argument(0), immediate)) rest = value->Argument(1)->Resolve();
|
||||
else if (immediateU32(value->Argument(1), immediate)) rest = value->Argument(0)->Resolve();
|
||||
else break;
|
||||
addend += immediate;
|
||||
value = rest;
|
||||
}
|
||||
addend = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user