mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-05 13:20:11 +00:00
Merge pull request #5982 from milescoviello/fix/depth-surface-later-level
fix(agc): treat a view past a depth surface's first level as memory
This commit is contained in:
3 files changed
+19
-11
No files matched your search
@@ -380,7 +380,7 @@ public:
|
||||
return ResolveTextureFormat(resource.format) == expected || depthBits;
|
||||
}
|
||||
|
||||
void RequireStorable(const GuestTextureResource& resource, std::uint32_t mip) const {
|
||||
void RequireStorable(const GuestTextureResource& resource) const {
|
||||
const bool stencil = target.stencilAddress != 0 && resource.baseAddress == target.stencilAddress;
|
||||
Require(target.samples == 1, "storage image access to a multisampled depth surface is not implemented");
|
||||
if (!stencil && hostFormat != target.format) {
|
||||
@@ -388,11 +388,6 @@ public:
|
||||
std::snprintf(text, sizeof(text), "AGC graphics: storage image access to the depth plane of depth surface 0x%llx (vk format %d) stored as vk format %d is not implemented", static_cast<unsigned long long>(target.address), static_cast<int>(target.format), static_cast<int>(hostFormat));
|
||||
throw std::runtime_error(text);
|
||||
}
|
||||
if (mip != 0 || resource.baseLevel != 0) {
|
||||
char text[224];
|
||||
std::snprintf(text, sizeof(text), "AGC graphics: storage image access to level %u of the %s plane of depth surface 0x%llx is not implemented", mip, stencil ? "stencil" : "depth", static_cast<unsigned long long>(target.address));
|
||||
throw std::runtime_error(text);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<StorageTexture> Storage(std::span<const std::uint32_t> words, const GuestTextureResource& resource, std::uint32_t mip) {
|
||||
@@ -404,7 +399,7 @@ public:
|
||||
std::snprintf(text, sizeof(text), "AGC graphics: storage image access to depth/stencil surface 0x%llx is not implemented (storage=%ux%u guest format=%u mip=%u dimension=%d tile=%d)", static_cast<unsigned long long>(resource.baseAddress), resource.width, resource.height, resource.format, mip, static_cast<int>(resource.dimension), static_cast<int>(resource.tileMode));
|
||||
throw std::runtime_error(text);
|
||||
}
|
||||
RequireStorable(resource, mip);
|
||||
RequireStorable(resource);
|
||||
ApplyFastClear();
|
||||
auto& plane = stencil ? stencilPlane : depthPlane;
|
||||
if (plane.storage == nullptr || plane.storage->Descriptor().format != resource.format || plane.storage->Descriptor().tileMode != resource.tileMode || plane.storage->Descriptor().baseAddress != resource.baseAddress || plane.storage->Descriptor().dimension != resource.dimension) {
|
||||
@@ -1343,7 +1338,7 @@ std::shared_ptr<Texture> DepthSurfaceTexture(const Context& context, std::span<c
|
||||
Recorder::CountBarriers(Recorder::CommandClass::Draw, 1);
|
||||
return found->Sampled(words, resource, components);
|
||||
}
|
||||
if (resource.width != base.extent.width || resource.height != base.extent.height) return nullptr;
|
||||
if (resource.width != base.extent.width || resource.height != base.extent.height || resource.baseLevel != 0) return nullptr;
|
||||
const bool d16 = base.format == VK_FORMAT_D16_UNORM || base.format == VK_FORMAT_D16_UNORM_S8_UINT;
|
||||
const auto format = ResolveTextureFormat(resource.format);
|
||||
const bool depthBits = !stencil && words.size() >= 4 && ShaderRecompiler::DepthBitsTextureWidth(words[1], words[3]) == (d16 ? 16u : 32u);
|
||||
@@ -1468,7 +1463,7 @@ std::shared_ptr<StorageTexture> layeredDepthStorage(const Context& context, Dept
|
||||
const auto layers = resource.depthOrLastArray + 1u;
|
||||
const bool d16 = target.format == VK_FORMAT_D16_UNORM || target.format == VK_FORMAT_D16_UNORM_S8_UINT;
|
||||
const auto bytesPerTexel = d16 ? 2u : 4u;
|
||||
surface.RequireStorable(resource, mip);
|
||||
surface.RequireStorable(resource);
|
||||
const auto geometry = DescribeSurface(resource);
|
||||
if (layers > 1 && geometry.GuestLayerOffset(1) != DepthSliceBytes(target.extent, bytesPerTexel)) {
|
||||
char text[256];
|
||||
@@ -1487,6 +1482,7 @@ std::shared_ptr<StorageTexture> layeredDepthStorage(const Context& context, Dept
|
||||
}
|
||||
|
||||
std::shared_ptr<StorageTexture> DepthSurfaceStorage(const Context& context, std::span<const std::uint32_t> words, const GuestTextureResource& resource, std::uint32_t mip) {
|
||||
if (mip != 0 || resource.baseLevel != 0) return nullptr;
|
||||
std::lock_guard lock(surfacesMutex());
|
||||
const auto& list = surfaces();
|
||||
const auto found = std::find_if(list.rbegin(), list.rend(), [&](const auto& surface) {
|
||||
|
||||
@@ -216,6 +216,9 @@ struct View {
|
||||
std::uint32_t tileMode = TileDepth64KB;
|
||||
std::uint32_t type = Type2D;
|
||||
std::uint32_t lastArray = 0;
|
||||
std::uint32_t baseLevel = 0;
|
||||
std::uint32_t lastLevel = 0;
|
||||
std::uint32_t maxMip = 0;
|
||||
};
|
||||
|
||||
std::array<std::uint32_t, 8> tsharp(const View& view) {
|
||||
@@ -226,8 +229,9 @@ std::array<std::uint32_t, 8> tsharp(const View& view) {
|
||||
words[0] = static_cast<std::uint32_t>(base);
|
||||
words[1] = static_cast<std::uint32_t>((base >> 32u) & 0xffu) | ((view.format & 0x1ffu) << 20u) | ((widthMinus1 & 0x3u) << 30u);
|
||||
words[2] = ((widthMinus1 >> 2u) & 0xfffu) | ((heightMinus1 & 0x3fffu) << 14u);
|
||||
words[3] = 4u | (5u << 3u) | (6u << 6u) | (7u << 9u) | ((view.tileMode & 0x1fu) << 20u) | ((view.type & 0xfu) << 28u);
|
||||
words[3] = 4u | (5u << 3u) | (6u << 6u) | (7u << 9u) | ((view.baseLevel & 0xfu) << 12u) | ((view.lastLevel & 0xfu) << 16u) | ((view.tileMode & 0x1fu) << 20u) | ((view.type & 0xfu) << 28u);
|
||||
words[4] = view.lastArray & 0x1fffu;
|
||||
words[5] = (view.maxMip & 0xfu) << 4u;
|
||||
return words;
|
||||
}
|
||||
|
||||
@@ -403,6 +407,8 @@ void RunDepthSurfaceReuseTests() {
|
||||
Require(lookup(context, {depth32, FormatR32Float, 512, 512, TileDepth64KB, Type2DArray, 5}) == nullptr, "a 2D array view of another extent over a depth surface must be read as reused memory");
|
||||
Require(lookup(context, {depth32, FormatR32Uint, 384, 384, TileRenderTarget64KB}) == nullptr, "an R32 uint view without a depth layout must be read as reused memory");
|
||||
Require(lookup(context, {depth16, FormatR32Float, 256, 256}) == nullptr, "an R32F view of a D16 surface's own extent must be read as reused memory");
|
||||
Require(lookup(context, {depth32, FormatR32Float, 384, 384, TileDepth64KB, Type2D, 0, 0, 0, 4}) != nullptr, "the first level of a mipmapped R32F view of a D32 surface's own extent must sample its depth plane");
|
||||
Require(lookup(context, {depth32, FormatR32Float, 384, 384, TileDepth64KB, Type2D, 0, 1, 1, 4}) == nullptr, "a view that starts past the first level of a D32 surface's own extent must be read as reused memory");
|
||||
|
||||
Require(lookup(context, {stencil, FormatR8Uint, 320, 180}) != nullptr, "an 8-bit view of a stencil plane's own extent must sample the stencil plane");
|
||||
Require(lookup(context, {stencil, FormatR8G8B8A8Unorm, 320, 180, TileRenderTarget64KB}) == nullptr, "an RGBA8 view of a stencil plane's own extent must be read as reused memory");
|
||||
|
||||
@@ -199,7 +199,13 @@ void Run(Context context, std::uint8_t* block) {
|
||||
Require(DepthSurfaceStorage(context, {}, PlaneResource(address, Format32Float, Side / 2), 0) == nullptr, "a storage view of another extent over the depth memory was taken for the depth surface");
|
||||
Require(DepthSurfaceTexture(context, {}, PlaneResource(address, Format32Float, Side / 2), {}) == nullptr, "a sampled view of another extent over the depth memory was taken for the depth surface");
|
||||
Require(DepthSurfaceStorage(context, {}, PlaneResource(address, Format8Uint), 0) == nullptr, "an 8-bit storage view of the depth plane was taken for the depth surface");
|
||||
ExpectFailure([&] { static_cast<void>(DepthSurfaceStorage(context, {}, PlaneResource(address, Format32Float), 1)); }, "not implemented", "a storage view of another level of the depth plane was accepted");
|
||||
Require(DepthSurfaceStorage(context, {}, PlaneResource(address, Format32Float), 1) == nullptr, "a storage access to a later level over the depth memory was taken for the depth surface");
|
||||
auto later = PlaneResource(address, Format32Float);
|
||||
later.mipCount = 2;
|
||||
later.baseLevel = 1;
|
||||
later.lastLevel = 1;
|
||||
Require(DepthSurfaceStorage(context, {}, later, 0) == nullptr, "a storage view of a later level over the depth memory was taken for the depth surface");
|
||||
Require(DepthSurfaceTexture(context, {}, later, {}) == nullptr, "a sampled view of a later level over the depth memory was taken for the depth surface");
|
||||
const auto depth = DepthSurfaceStorage(context, {}, PlaneResource(address, Format32Float), 0);
|
||||
Require(depth != nullptr, "the depth plane has no storage image");
|
||||
submit(recorder);
|
||||
|
||||
Reference in new issue
Block a user