mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
fix(agc): retain shader memory region vectors
This commit is contained in:
1 parent
63e4a63804
commit
55a3eeb074
2 files changed
+43
-22
No files matched your search
@@ -826,7 +826,8 @@ void verifyOutOfRangeConstantReads() {
|
||||
require(plan->info.images.size() == 2u && plan->info.samplers.size() == 1u, "out-of-range s_buffer_load: the two T#s were not planned as one image each");
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(request);
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
static_cast<void>(Recompile(request, *capture));
|
||||
const auto holds = [&](const std::array<std::uint32_t, 8>& words) {
|
||||
return std::ranges::any_of(capture->snapshot.images, [&](const DescriptorValue& value) {
|
||||
@@ -1001,8 +1002,10 @@ void verifyGuardedDescriptorSources() {
|
||||
fill(valid, mode);
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(storeRequest);
|
||||
storeRequest.context.memory = memory.Regions();
|
||||
return Recompile(storeRequest, *capture);
|
||||
const auto memoryRegions = memory.Regions();
|
||||
auto compileRequest = storeRequest;
|
||||
compileRequest.context.memory = memoryRegions;
|
||||
return Recompile(compileRequest, *capture);
|
||||
};
|
||||
const auto storePlan = GetResourcePlan(storeRequest);
|
||||
require(storePlan->info.images.size() == 2u && storePlan->descriptorSources.size() == 1u, "guarded images: the two stores were not planned as two images of one T#");
|
||||
@@ -3506,7 +3509,8 @@ void verifyDescriptorPhis() {
|
||||
require(plan->info.images.size() == images && plan->info.samplers.size() == samplers && plan->info.sampledPairs.size() == 2u, "descriptor Phi: the edges were not given one resource each");
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(request);
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
const auto compiled = Recompile(request, *capture);
|
||||
require(countOps(compiled->spirv, OpImageSampleExplicitLod) == 2u, "descriptor Phi: the specialized SPIR-V does not sample once per edge");
|
||||
#if ANYPS5_ENABLE_SPIRV_TOOLS
|
||||
@@ -3537,7 +3541,8 @@ void verifyDescriptorPhis() {
|
||||
auto twoLane = makeRequest(samplerCode, 64u);
|
||||
AgcDriver::ShaderMemory twoLaneMemory({});
|
||||
const auto twoLaneCapture = twoLaneMemory.Capture(twoLane);
|
||||
twoLane.context.memory = twoLaneMemory.Regions();
|
||||
const auto twoLaneRegions = twoLaneMemory.Regions();
|
||||
twoLane.context.memory = twoLaneRegions;
|
||||
require(countOps(Recompile(twoLane, *twoLaneCapture)->spirv, OpImageSampleExplicitLod) == 4u, "descriptor Phi: the specialized two-lane SPIR-V does not sample once per edge and half");
|
||||
|
||||
auto dynamic = makeRequest(dynamicCode);
|
||||
@@ -3559,7 +3564,8 @@ void verifyDescriptorPhis() {
|
||||
require(sequentialPlan->info.images.size() == 2u && sequentialPlan->info.samplers.size() == 2u, "descriptor Phi: a T# and an S# chosen in separate blocks were not split into their SRT descriptors");
|
||||
AgcDriver::ShaderMemory sequentialMemory({});
|
||||
const auto sequentialCapture = sequentialMemory.Capture(sequential);
|
||||
sequential.context.memory = sequentialMemory.Regions();
|
||||
const auto sequentialRegions = sequentialMemory.Regions();
|
||||
sequential.context.memory = sequentialRegions;
|
||||
static_cast<void>(Recompile(sequential, *sequentialCapture));
|
||||
|
||||
const auto planRestoredSampler = [&](std::span<const std::uint32_t> code, const char* message) {
|
||||
@@ -3568,7 +3574,8 @@ void verifyDescriptorPhis() {
|
||||
require(plan->info.samplers.size() == 1u && plan->info.sampledPairs.size() == 1u, message);
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(request);
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
static_cast<void>(Recompile(request, *capture));
|
||||
};
|
||||
std::vector<std::uint32_t> restoredSamplerCode{0xf40c0200u, 0xfa000000u, 0xf4080500u, 0xfa000020u, 0xf4080600u, 0xfa000040u, 0xbe930380u, 0xbf8cc07fu, 0xf09c0f08u, 0x00a20400u, 0xbe900380u, 0xbe910380u, 0xbe9c0414u, 0xbe9e0416u, 0xbf068011u, 0xbf850001u, 0x80128112u, 0xbe94041cu, 0xbe96041eu, 0x80118111u, 0xbf0a8211u, 0xbf85fff6u, 0xf09c0f08u, 0x00a20000u, 0x80108110u, 0xbf0a8210u, 0xbf85fff0u, 0x80138113u, 0xbf0a8213u, 0xbf85ffecu, 0xbf8c3f70u, 0xe0700000u, 0x80060000u, 0xe0700000u, 0x80060400u, 0x7d880090u, 0xbea23c6au, 0x4a020081u, 0xe0700000u, 0x80060100u, 0xbf810000u};
|
||||
@@ -3742,7 +3749,8 @@ void verifyLaneSelectedDescriptors() {
|
||||
require(plan->info.images.size() == 2u && plan->info.samplers.size() == 1u, "lane-selected T#: the T#s selected per lane were not planned as one image each");
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(request);
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
static_cast<void>(Recompile(request, *capture));
|
||||
const auto holds = [&](const std::array<std::uint32_t, 8>& words) {
|
||||
return std::ranges::any_of(capture->snapshot.images, [&](const DescriptorValue& value) {
|
||||
@@ -3788,7 +3796,8 @@ void verifyProgramCounterRelativeData() {
|
||||
};
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
static_cast<void>(memory.Capture(request));
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
const auto first = Recompile(request);
|
||||
require(dataBase(first) == codeAddress + 56u, "program counter data: the V# does not name the data at the shader's address");
|
||||
auto relocated = request;
|
||||
@@ -5457,7 +5466,8 @@ void verifyComputedTexelOffsets() {
|
||||
request.useCache = false;
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
static_cast<void>(memory.Capture(request));
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
return Recompile(request).spirv;
|
||||
};
|
||||
const auto sampleOperands = [](std::span<const std::uint32_t> words) {
|
||||
@@ -5507,7 +5517,8 @@ void verifyShaderClockScopes() {
|
||||
request.useCache = false;
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
static_cast<void>(memory.Capture(request));
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
const auto words = Recompile(request).spirv;
|
||||
std::map<std::uint32_t, std::uint32_t> constants;
|
||||
std::vector<std::uint32_t> scopeIds;
|
||||
@@ -5821,7 +5832,8 @@ void verifyUnnormalizedSamplers() {
|
||||
request.layout.pushConstantSizeBytes = 128;
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
static_cast<void>(memory.Capture(request));
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
return Recompile(request);
|
||||
};
|
||||
const auto flags = [](const RecompileResult& result, DescriptorRole role) {
|
||||
@@ -6244,7 +6256,8 @@ void verifyTwoLaneUniformValues() {
|
||||
request.layout.pushConstantSizeBytes = 128;
|
||||
AgcDriver::ShaderMemory memory({});
|
||||
const auto capture = memory.Capture(request);
|
||||
request.context.memory = memory.Regions();
|
||||
const auto memoryRegions = memory.Regions();
|
||||
request.context.memory = memoryRegions;
|
||||
const auto words = Recompile(request, *capture)->spirv;
|
||||
std::size_t count = 0;
|
||||
for (std::size_t cursor = 5; cursor < words.size();) {
|
||||
@@ -6825,7 +6838,8 @@ void verifyGuardedNullPointers() {
|
||||
const auto valid = validMemory.Capture(branch.request);
|
||||
require(valid->snapshot.srtPoison.empty() && valid->plan->guardedSrtSlots.size() == 1u && slotPc(*valid->plan, valid->plan->guardedSrtSlots[0]) == 0x2cu && GuardRecords(*valid), "guarded pointer: a mapped nested pointer was poisoned, or its read has no guard");
|
||||
require(valid->snapshot.flattenedSrt.at(valid->plan->guardedSrtSlots[0]) == payload, "guarded pointer: a mapped nested read does not hold its word");
|
||||
branch.request.context.memory = validMemory.Regions();
|
||||
const auto validRegions = validMemory.Regions();
|
||||
branch.request.context.memory = validRegions;
|
||||
const auto validResult = Recompile(branch.request, *valid);
|
||||
require(validResult->poisonedSrtReads == 0u && faultBinding(*validResult) && validResult->bdaAbiVersion == BdaAbi::Version, "guarded pointer: a guarded program has no fault buffer");
|
||||
|
||||
@@ -6867,20 +6881,23 @@ void verifyGuardedNullPointers() {
|
||||
const bool throughPointer = own == 0x38u && poison.address == unmapped;
|
||||
require(poison.pc == 0x2cu && (pointerWord || throughPointer), "guarded pointer: a derived poison does not name the inaccessible read");
|
||||
}
|
||||
chain.request.context.memory = chainMemory.Regions();
|
||||
const auto chainRegions = chainMemory.Regions();
|
||||
chain.request.context.memory = chainRegions;
|
||||
const auto chainResult = Recompile(chain.request, *chained);
|
||||
indirect = 0;
|
||||
point(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&indirect)));
|
||||
AgcDriver::ShaderMemory nullChainMemory({});
|
||||
const auto nullChain = nullChainMemory.Capture(chain.request);
|
||||
require(nullChain->snapshot.srtPoison.size() == 1u && nullChain->snapshot.srtPoison[0].pc == 0x38u && nullChain->snapshot.srtPoison[0].address == 0u && GuardRecords(*nullChain), "guarded pointer: a null pointer read from memory did not poison the read through it");
|
||||
chain.request.context.memory = nullChainMemory.Regions();
|
||||
const auto nullChainRegions = nullChainMemory.Regions();
|
||||
chain.request.context.memory = nullChainRegions;
|
||||
const auto nullChainResult = Recompile(chain.request, *nullChain);
|
||||
indirect = payloadAddress;
|
||||
AgcDriver::ShaderMemory mappedChainMemory({});
|
||||
const auto mappedChain = mappedChainMemory.Capture(chain.request);
|
||||
require(mappedChain->snapshot.srtPoison.empty() && mappedChain->plan->guardedSrtSlots.size() == 3u && GuardRecords(*mappedChain), "guarded pointer: a mapped pointer chain was poisoned, or its reads have no guards");
|
||||
chain.request.context.memory = mappedChainMemory.Regions();
|
||||
const auto mappedChainRegions = mappedChainMemory.Regions();
|
||||
chain.request.context.memory = mappedChainRegions;
|
||||
const auto mappedChainResult = Recompile(chain.request, *mappedChain);
|
||||
require(chainResult->poisonedSrtReads == 3u && nullChainResult->poisonedSrtReads == 1u && mappedChainResult->poisonedSrtReads == 0u, "guarded pointer: a chain result does not count its poisoned reads");
|
||||
require(samePipeline(*chainResult, *mappedChainResult) && samePipeline(*nullChainResult, *mappedChainResult), "guarded pointer: a chain's poison changed the variant, the specialization or the module");
|
||||
@@ -6903,7 +6920,8 @@ void verifyGuardedNullPointers() {
|
||||
AgcDriver::ShaderMemory zeroMemory({});
|
||||
const auto zeroCapture = zeroMemory.Capture(descriptor.request);
|
||||
require(zeroCapture->snapshot.srtPoison.empty() && zeroBuffer(*zeroCapture) && GuardRecords(*zeroCapture), "guarded pointer: a zero V# read from mapped memory was poisoned or not read");
|
||||
descriptor.request.context.memory = zeroMemory.Regions();
|
||||
const auto zeroRegions = zeroMemory.Regions();
|
||||
descriptor.request.context.memory = zeroRegions;
|
||||
const auto zeroResult = Recompile(descriptor.request, *zeroCapture);
|
||||
for (const auto pointer : {std::uint64_t{0}, unmapped}) {
|
||||
point(pointer);
|
||||
@@ -6959,7 +6977,8 @@ void verifyGuardedNullPointers() {
|
||||
const auto rootlessCapture = rootlessMemory.Capture(rootless.request);
|
||||
require(rootlessCapture->snapshot.nullRootReads != 0u && GuardRecords(*rootlessCapture), "guarded pointer: reads through a null user-data pointer were not counted");
|
||||
require(std::all_of(rootlessCapture->snapshot.buffers.begin(), rootlessCapture->snapshot.buffers.end(), [](const DescriptorValue& value) { return std::all_of(value.dwords.begin(), value.dwords.end(), [](std::uint32_t word) { return word == 0u; }); }), "guarded pointer: a V# read through a null user-data pointer is not zero");
|
||||
rootless.request.context.memory = rootlessMemory.Regions();
|
||||
const auto rootlessRegions = rootlessMemory.Regions();
|
||||
rootless.request.context.memory = rootlessRegions;
|
||||
const auto rootlessResult = Recompile(rootless.request, *rootlessCapture);
|
||||
require(rootlessResult->poisonedSrtReads >= rootlessCapture->snapshot.nullRootReads, "guarded pointer: a capture through a null user-data pointer is cacheable");
|
||||
point(0u);
|
||||
@@ -7449,7 +7468,8 @@ int main(int argc, char** argv) {
|
||||
const auto changedCapture = changedMemory.Capture(request);
|
||||
auto changed = updated;
|
||||
changed.useCache = true;
|
||||
changed.context.memory = changedMemory.Regions();
|
||||
const auto changedRegions = changedMemory.Regions();
|
||||
changed.context.memory = changedRegions;
|
||||
auto before = updated;
|
||||
before.useCache = true;
|
||||
before.context.memory = updatedRegions;
|
||||
@@ -7512,7 +7532,8 @@ int main(int argc, char** argv) {
|
||||
AgcDriver::ShaderMemory nullRoot({});
|
||||
const auto nullRootCapture = nullRoot.Capture(request);
|
||||
require(nullRootCapture->snapshot.nullRootReads != 0u, "reads through a null user-data pointer were not counted");
|
||||
request.context.memory = nullRoot.Regions();
|
||||
const auto nullRootRegions = nullRoot.Regions();
|
||||
request.context.memory = nullRootRegions;
|
||||
require(Recompile(request, *nullRootCapture)->poisonedSrtReads >= nullRootCapture->snapshot.nullRootReads, "a capture through a null user-data pointer is cacheable");
|
||||
std::cout << "Shader memory capture, strict validation and deterministic replay passed\n";
|
||||
return 0;
|
||||
|
||||
@@ -131,7 +131,7 @@ Captured Capture(std::byte* table) {
|
||||
result.memory = std::make_unique<AgcDriver::ShaderMemory>(std::span<const MemoryRegion>{});
|
||||
result.capture = result.memory->Capture(request);
|
||||
result.regions = result.memory->TakeRecentRegions();
|
||||
request.context.memory = result.memory->Regions();
|
||||
request.context.memory = result.regions;
|
||||
result.compiled = Recompile(request, *result.capture);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user