mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
Handle stencil storage/depth transitions
This commit is contained in:
@@ -326,6 +326,7 @@ inline constexpr std::array<VideoOutFormatPolicy, 6> VIDEO_OUT_FORMAT_POLICIES {
|
||||
enum class DepthOverlap : uint8_t {
|
||||
None,
|
||||
RetireSampled,
|
||||
RetireStorage,
|
||||
ExpandTarget,
|
||||
DiscardTarget,
|
||||
Unsupported
|
||||
@@ -815,6 +816,23 @@ ClassifyStorageBufferRebind(bool buffer_overlap, bool cached_gpu_modified,
|
||||
return DepthOverlap::Unsupported;
|
||||
}
|
||||
|
||||
// Mirrors storage -> depth-target binding transition. An inaccessible stencil aspect
|
||||
// does not require the otherwise necessary image content copy.
|
||||
[[nodiscard]] inline DepthOverlap ClassifyStorageDepthOverlap(const ImageInfo& storage,
|
||||
const DepthTargetInfo& depth) {
|
||||
const bool overlaps_depth = ImageRangeOverlaps(storage.address, storage.size, depth.address,
|
||||
depth.size);
|
||||
const bool overlaps_stencil = depth.stencil_address != 0 &&
|
||||
ImageRangeOverlaps(storage.address, storage.size,
|
||||
depth.stencil_address, depth.stencil_size);
|
||||
if (!overlaps_depth && !overlaps_stencil) {
|
||||
return DepthOverlap::None;
|
||||
}
|
||||
return !overlaps_depth && overlaps_stencil && !depth.stencil_access
|
||||
? DepthOverlap::RetireStorage
|
||||
: DepthOverlap::Unsupported;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline RenderTargetOverlap
|
||||
ClassifyRenderTargetOverlap(const ImageInfo& sampled, bool sampled_gpu_modified, bool same_context,
|
||||
const RenderTargetInfo& target) {
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace Libs::Graphics {
|
||||
uint32_t width, uint32_t height,
|
||||
uint32_t depth) noexcept {
|
||||
return (format == Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt) &&
|
||||
type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) && width == 1 &&
|
||||
height == 1 && depth == 1) ||
|
||||
type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) && width != 0 &&
|
||||
height != 0 && depth == 1) ||
|
||||
(format == Prospero::GpuEnumValue(Prospero::BufferFormat::k32UInt) &&
|
||||
type == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) && width != 0 &&
|
||||
height != 0 && depth == 1);
|
||||
|
||||
@@ -2533,6 +2533,7 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
std::shared_ptr<CachedImage> sampled_depth_source;
|
||||
std::shared_ptr<CachedImage> native_depth_source;
|
||||
std::shared_ptr<CachedImage> discarded_depth_source;
|
||||
std::shared_ptr<CachedImage> retired_storage_source;
|
||||
for (const auto& entry: m_images) {
|
||||
auto& cached = *entry;
|
||||
const bool overlaps =
|
||||
@@ -2554,6 +2555,9 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
cached.buffer_modified, cached.ctx == ctx, info);
|
||||
break;
|
||||
case CachedImage::Kind::StorageTexture:
|
||||
overlap = cached.ctx == ctx ? ClassifyStorageDepthOverlap(cached.info, info)
|
||||
: DepthOverlap::Unsupported;
|
||||
break;
|
||||
case CachedImage::Kind::RenderTarget:
|
||||
case CachedImage::Kind::VideoOut: break;
|
||||
}
|
||||
@@ -2565,9 +2569,20 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
sampled_depth_source = entry;
|
||||
}
|
||||
break;
|
||||
case DepthOverlap::RetireStorage:
|
||||
supported = cached.kind == CachedImage::Kind::StorageTexture &&
|
||||
cached.gpu_modified && !cached.buffer_modified &&
|
||||
!cached.info.IsCpuDirty() &&
|
||||
retired_storage_source == nullptr && native_depth_source == nullptr &&
|
||||
discarded_depth_source == nullptr;
|
||||
if (supported) {
|
||||
retired_storage_source = entry;
|
||||
}
|
||||
break;
|
||||
case DepthOverlap::ExpandTarget:
|
||||
supported =
|
||||
cached.kind == CachedImage::Kind::DepthTarget && native_depth_source == nullptr;
|
||||
cached.kind == CachedImage::Kind::DepthTarget && native_depth_source == nullptr &&
|
||||
retired_storage_source == nullptr;
|
||||
if (supported) {
|
||||
native_depth_source = entry;
|
||||
}
|
||||
@@ -2575,6 +2590,7 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
case DepthOverlap::DiscardTarget:
|
||||
supported = cached.kind == CachedImage::Kind::DepthTarget &&
|
||||
discarded_depth_source == nullptr && native_depth_source == nullptr;
|
||||
supported = supported && retired_storage_source == nullptr;
|
||||
if (supported) {
|
||||
discarded_depth_source = entry;
|
||||
}
|
||||
@@ -2591,8 +2607,17 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
retire.push_back(&cached);
|
||||
}
|
||||
RequireRetirementIsolation(retire, "depth target", info.address, info.size);
|
||||
RetireImages(retire, native_depth_source != nullptr ? native_depth_source.get()
|
||||
: discarded_depth_source.get());
|
||||
if (retired_storage_source != nullptr) {
|
||||
m_memory_tracker.UnmarkRegionAsGpuModified(retired_storage_source->info.address,
|
||||
retired_storage_source->info.size);
|
||||
retired_storage_source->gpu_modified = false;
|
||||
}
|
||||
const auto* transition_source = native_depth_source != nullptr
|
||||
? native_depth_source.get()
|
||||
: (discarded_depth_source != nullptr
|
||||
? discarded_depth_source.get()
|
||||
: nullptr);
|
||||
RetireImages(retire, transition_source);
|
||||
const bool coherent_guest_stencil =
|
||||
has_stencil &&
|
||||
IsCoherentGuestImageSource(stencil_source, info.stencil_address, info.stencil_size);
|
||||
@@ -2614,6 +2639,9 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
||||
if (discarded_depth_source != nullptr) {
|
||||
command->RetainResourceUntilFence(discarded_depth_source);
|
||||
}
|
||||
if (retired_storage_source != nullptr) {
|
||||
command->RetainResourceUntilFence(retired_storage_source);
|
||||
}
|
||||
if (native_depth_source != nullptr) {
|
||||
const auto& old = native_depth_source->depth;
|
||||
if (old.layers >= info.layers || native_depth_source->image->layers != old.layers) {
|
||||
|
||||
Reference in New Issue
Block a user