mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
Merge pull request #10368 from Ondra97/codex/fix-storage-native-overlap-span
fix(agc): check whole storage views for native surface overlap
This commit is contained in:
2 files changed
+45
-2
No files matched your search
@@ -1189,9 +1189,9 @@ std::shared_ptr<StorageTexture> cachedStorageTexture(const Context& context, std
|
||||
const auto viewed = ArrayLayerWindow(requested, context.limits.maxImageArrayLayers);
|
||||
if (viewed.baseAddress != requested.baseAddress) guestBytes = 0;
|
||||
Require(viewed.dimension != TextureDimension::k2DMsaa, "storage image access to a multisampled texture is not implemented");
|
||||
RequireNoMultisampleTarget(viewed.baseAddress, guestBytes != 0 ? static_cast<std::size_t>(guestBytes) : 1u, "a storage image access");
|
||||
if (auto depth = DepthSurfaceStorage(context, words, viewed, mip)) return depth;
|
||||
const auto viewedBytes = guestBytes != 0 ? guestBytes : DescribeSurface(viewed).guestBytes;
|
||||
RequireNoMultisampleTarget(viewed.baseAddress, static_cast<std::size_t>(viewedBytes), "a storage image access");
|
||||
if (auto depth = DepthSurfaceStorage(context, words, viewed, mip)) return depth;
|
||||
if (viewedBytes >= (1ull << 30u)) {
|
||||
static std::atomic<std::uint64_t> large{0};
|
||||
const auto count = large.fetch_add(1) + 1;
|
||||
|
||||
@@ -704,6 +704,48 @@ void CheckDepthAttachmentAlias() {
|
||||
std::puts("native depth attachment alias changes layout while retaining held GPU views");
|
||||
}
|
||||
|
||||
void CheckStorageAliasRetirement() {
|
||||
const auto device = OpenVulkanTestDevice();
|
||||
Require(device != nullptr, "native depth storage alias requires Vulkan");
|
||||
const auto context = device->graphicsContext();
|
||||
constexpr VkExtent2D extent{5u, 3u};
|
||||
constexpr std::uint32_t samples = 4u;
|
||||
constexpr std::size_t prefix = 65536u;
|
||||
const auto bytes = static_cast<std::size_t>(MultisampledDepthBytes_nid_no_patch(extent, 4u, samples));
|
||||
TargetMemory memory(prefix + bytes), metadata(65536u);
|
||||
std::memset(memory.Data(), 0x3c, prefix + bytes);
|
||||
std::memset(metadata.Data(), 0, 65536u);
|
||||
struct Cleanup {
|
||||
AgcDriver::VulkanDevice& device;
|
||||
~Cleanup() { device.WaitIdle(); ClearCachedTextures(device.Device()); ClearDepthSurfaces(device.Device()); }
|
||||
} cleanup{*device};
|
||||
GuestTextureResource alias{};
|
||||
alias.baseAddress = memory.Address();
|
||||
alias.width = 256u;
|
||||
alias.height = static_cast<std::uint32_t>((prefix + bytes) / 1024u);
|
||||
alias.mipCount = alias.allocatedMipCount = 1u;
|
||||
alias.dimension = TextureDimension::k2D;
|
||||
alias.tileMode = TextureTileMode::kLinear;
|
||||
alias.format = 22u;
|
||||
alias.dstSelX = 0u;
|
||||
alias.dstSelY = alias.dstSelZ = 4u;
|
||||
alias.dstSelW = 5u;
|
||||
auto cached = CachedStorageSurface(context, alias);
|
||||
Require(cached != nullptr, "storage alias was not cached before native depth creation");
|
||||
DepthTarget depth{memory.Address() + prefix, 0u, extent, VK_FORMAT_D32_SFLOAT, 0.0f, 0u, metadata.Address(), false, samples};
|
||||
depth.depthSwizzle = 24u;
|
||||
depth.iterate256 = depth.htilePipeAligned = depth.htileDepthOnly = true;
|
||||
Require(DepthSurfaceView(context, depth) != VK_NULL_HANDLE && DepthSurfaceAt(depth.address), "storage alias fixture has no native depth owner");
|
||||
auto disjoint = alias;
|
||||
disjoint.height = static_cast<std::uint32_t>(prefix / 1024u);
|
||||
Require(CachedStorageSurface(context, disjoint) != nullptr, "disjoint storage alias was not created");
|
||||
Require(DepthSurfaceAt(depth.address), "storage access ending at native depth retired a disjoint owner");
|
||||
Require(CachedStorageSurface(context, alias) != nullptr, "overlapping cached storage alias was not returned");
|
||||
Require(!DepthSurfaceAt(depth.address), "a cached storage view kept a native depth owner inside its range");
|
||||
for (std::size_t offset = 0u; offset < prefix + bytes; ++offset) Require(memory.Data()[offset] == std::byte{0x3c}, "retiring unwritten native depth changed guest bytes");
|
||||
std::puts("cached storage span retires only intersecting native depth owners");
|
||||
}
|
||||
|
||||
enum class ClearFault { None, PartialStore, CpuWrite, DepthWrite, BadMetadata, UnprovenDispatch, PendingWrite, Overlap, PossibleStore, CompletedPossibleStore, DriverDispatch, ImportWindowWrite };
|
||||
|
||||
void CheckClearDispatch() {
|
||||
@@ -1337,6 +1379,7 @@ int main(int argc, char** argv) {
|
||||
CheckDrawFeedback();
|
||||
const auto context = device->GetContext();
|
||||
if (argc == 1) CheckDepthAttachmentAlias();
|
||||
if (argc == 1) CheckStorageAliasRetirement();
|
||||
std::unique_lock lock(AgcDriver::GuestMemory::GpuMutex());
|
||||
Require(DepthSupported(context, VK_FORMAT_D32_SFLOAT, 4u), "the native depth regression requires sampled D32 with four samples");
|
||||
if (argc == 2 && std::string_view(argv[1]) == "--clear-refusals") {
|
||||
|
||||
Reference in new issue
Block a user