mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
render: fix tiled depth comparison textures
Co-authored-by: Ettore Sartori <85788613+Ekt0re@users.noreply.github.com> Co-authored-by: Mac <me@itsmemac.com>
This commit is contained in:
+45
-36
@@ -130,7 +130,10 @@ bool TextureCache::SameBacking(const ImageInfo& cached, const ImageInfo& request
|
||||
|
||||
TextureCache::BindingType TextureCache::UploadBinding(const Image& image) {
|
||||
if (image.info.IsDepth()) {
|
||||
return BindingType::DepthTarget;
|
||||
return image.info.tile_mode == Prospero::TileMode::kDepth ||
|
||||
image.info.tile_mode == Prospero::TileMode::kLinear
|
||||
? BindingType::DepthTarget
|
||||
: BindingType::Texture;
|
||||
}
|
||||
if (image.usage.render_target) {
|
||||
return BindingType::RenderTarget;
|
||||
@@ -815,7 +818,7 @@ ImageId TextureCache::ExpandImage(const ImageInfo& info, ImageId source_id) {
|
||||
return expanded_id;
|
||||
}
|
||||
|
||||
struct TextureCache::ColorTransferPlan {
|
||||
struct TextureCache::TextureTransferPlan {
|
||||
TextureUploadLayout layout;
|
||||
std::vector<vk::BufferImageCopy> regions;
|
||||
std::vector<GpuTileInfo> tiles;
|
||||
@@ -834,14 +837,14 @@ static uint64_t GetLinearSize(std::span<const GpuTileInfo> tiles) {
|
||||
}
|
||||
|
||||
struct TextureCache::DownloadPlan {
|
||||
ColorTransferPlan color;
|
||||
bool depth = false;
|
||||
bool valid = false;
|
||||
TextureTransferPlan texture;
|
||||
bool depth_target = false;
|
||||
bool valid = false;
|
||||
};
|
||||
|
||||
TextureCache::ColorTransferPlan
|
||||
TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
TransferDirection direction) const {
|
||||
TextureCache::TextureTransferPlan
|
||||
TextureCache::BuildTextureTransfer(const Image& image, BindingType binding,
|
||||
TransferDirection direction) const {
|
||||
const auto& info = image.info;
|
||||
auto format = info.guest_format;
|
||||
uint32_t layers = info.TransferLayers();
|
||||
@@ -850,7 +853,7 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
const char* owner =
|
||||
direction == TransferDirection::Upload ? "TextureCache" : "TextureCache readback";
|
||||
|
||||
ColorTransferPlan plan;
|
||||
TextureTransferPlan plan;
|
||||
if (direction == TransferDirection::Upload) {
|
||||
switch (binding) {
|
||||
case BindingType::Texture: break;
|
||||
@@ -895,6 +898,11 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
info.resources.levels, layers, info.tile_mode,
|
||||
info.data.size, allow_depth_tile, volume, owner);
|
||||
plan.regions = TextureBuildImageCopies(plan.layout);
|
||||
if (info.IsDepth()) {
|
||||
for (auto& region: plan.regions) {
|
||||
region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eDepth;
|
||||
}
|
||||
}
|
||||
plan.tiled = plan.layout.surface.description.tile_mode != Prospero::TileMode::kLinear;
|
||||
if (plan.tiled) {
|
||||
if (!TextureBuildGpuTileInfos(info.data.size, plan.regions, plan.layout,
|
||||
@@ -908,12 +916,13 @@ TextureCache::BuildColorTransfer(const Image& image, BindingType binding,
|
||||
}
|
||||
|
||||
TextureCache::DownloadPlan TextureCache::BuildDownload(const Image& image) const {
|
||||
const auto& info = image.info;
|
||||
DownloadPlan plan {.depth = info.IsDepth()};
|
||||
const auto& info = image.info;
|
||||
const auto binding = UploadBinding(image);
|
||||
DownloadPlan plan {.depth_target = binding == BindingType::DepthTarget};
|
||||
if (info.samples != 1 || image.backing.samples != 1) {
|
||||
return plan;
|
||||
}
|
||||
if (plan.depth) {
|
||||
if (plan.depth_target) {
|
||||
plan.valid = IsSupportedDepthPlaneReadback(info) && info.resources.layers != 0 &&
|
||||
info.data.size % info.resources.layers == 0 &&
|
||||
Prospero::NumBytesPerElement(info.guest_format) == info.bytes_per_block;
|
||||
@@ -922,8 +931,8 @@ TextureCache::DownloadPlan TextureCache::BuildDownload(const Image& image) const
|
||||
if (info.metadata.compression != VideoOutCompression::Uncompressed) {
|
||||
return plan;
|
||||
}
|
||||
plan.color = BuildColorTransfer(image, UploadBinding(image), TransferDirection::Download);
|
||||
plan.valid = plan.color.valid;
|
||||
plan.texture = BuildTextureTransfer(image, binding, TransferDirection::Download);
|
||||
plan.valid = plan.texture.valid;
|
||||
return plan;
|
||||
}
|
||||
|
||||
@@ -938,9 +947,9 @@ void TextureCache::UploadImage(Image& image, Buffer& source, uint64_t source_off
|
||||
};
|
||||
|
||||
if (binding != BindingType::DepthTarget) {
|
||||
auto plan = BuildColorTransfer(image, binding, TransferDirection::Upload);
|
||||
auto plan = BuildTextureTransfer(image, binding, TransferDirection::Upload);
|
||||
if (!plan.valid) {
|
||||
EXIT("TextureCache: invalid color upload: binding=%u addr=0x%016" PRIx64
|
||||
EXIT("TextureCache: invalid texture upload: binding=%u addr=0x%016" PRIx64
|
||||
" size=0x%016" PRIx64 " format=%u tile=%u family=%u extent=%ux%ux%u "
|
||||
"pitch=%u levels=%u layers=%u samples=%u\n",
|
||||
static_cast<uint32_t>(binding), info.data.address, info.data.size,
|
||||
@@ -1536,7 +1545,7 @@ void TextureCache::DownloadImageData(Image& image, Buffer& destination, uint64_t
|
||||
if (!plan.valid) {
|
||||
EXIT("TextureCache: invalid image download plan\n");
|
||||
}
|
||||
if (plan.depth) {
|
||||
if (plan.depth_target) {
|
||||
if (destination_size != image.info.data.size) {
|
||||
EXIT("TextureCache: partial depth image download is unsupported\n");
|
||||
}
|
||||
@@ -1544,26 +1553,26 @@ void TextureCache::DownloadImageData(Image& image, Buffer& destination, uint64_t
|
||||
return;
|
||||
}
|
||||
|
||||
auto& color = plan.color;
|
||||
const auto transform = color.swap_bgra16 ? TileManager::ColorTransform::SwapBgra16
|
||||
: TileManager::ColorTransform::None;
|
||||
if (!color.tiled) {
|
||||
auto& texture = plan.texture;
|
||||
const auto transform = texture.swap_bgra16 ? TileManager::ColorTransform::SwapBgra16
|
||||
: TileManager::ColorTransform::None;
|
||||
if (!texture.tiled) {
|
||||
if (transform == TileManager::ColorTransform::SwapBgra16) {
|
||||
auto linear = m_tiler.GetScratchBuffer(destination_size);
|
||||
image.Download(color.regions, linear.buffer, 0, linear.size);
|
||||
image.Download(texture.regions, linear.buffer, 0, linear.size);
|
||||
m_tiler.SwapBgra16(linear,
|
||||
{destination.Handle(), destination_offset, destination_size});
|
||||
return;
|
||||
}
|
||||
for (auto& copy: color.regions) {
|
||||
for (auto& copy: texture.regions) {
|
||||
copy.bufferOffset += destination_offset;
|
||||
}
|
||||
image.Download(color.regions, destination.Handle(), destination_offset, destination_size);
|
||||
image.Download(texture.regions, destination.Handle(), destination_offset, destination_size);
|
||||
return;
|
||||
}
|
||||
|
||||
m_tiler.TileImage(image, color.regions, destination.Handle(), destination_offset,
|
||||
destination_size, color.linear_size, color.tiles, transform);
|
||||
m_tiler.TileImage(image, texture.regions, destination.Handle(), destination_offset,
|
||||
destination_size, texture.linear_size, texture.tiles, transform);
|
||||
}
|
||||
|
||||
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, uint64_t vaddr, uint64_t size) {
|
||||
@@ -1634,24 +1643,24 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, uint64_t vaddr, uin
|
||||
if (!plan.valid) {
|
||||
return false;
|
||||
}
|
||||
if (plan.depth && copy_size != image.info.data.size) {
|
||||
if (plan.depth_target && copy_size != image.info.data.size) {
|
||||
return false;
|
||||
}
|
||||
if (!plan.depth && levels < image.info.resources.levels) {
|
||||
auto& color = plan.color;
|
||||
std::erase_if(color.regions, [levels](const vk::BufferImageCopy& region) {
|
||||
if (!plan.depth_target && levels < image.info.resources.levels) {
|
||||
auto& texture = plan.texture;
|
||||
std::erase_if(texture.regions, [levels](const vk::BufferImageCopy& region) {
|
||||
return region.imageSubresource.mipLevel >= levels;
|
||||
});
|
||||
if (color.regions.empty()) {
|
||||
if (texture.regions.empty()) {
|
||||
return false;
|
||||
}
|
||||
if (color.tiled) {
|
||||
color.tiles.clear();
|
||||
if (!TextureBuildGpuTileInfos(copy_size, color.regions, color.layout, levels,
|
||||
color.tiles)) {
|
||||
if (texture.tiled) {
|
||||
texture.tiles.clear();
|
||||
if (!TextureBuildGpuTileInfos(copy_size, texture.regions, texture.layout, levels,
|
||||
texture.tiles)) {
|
||||
return false;
|
||||
}
|
||||
color.linear_size = GetLinearSize(color.tiles);
|
||||
texture.linear_size = GetLinearSize(texture.tiles);
|
||||
}
|
||||
}
|
||||
m_texture_cache.DownloadImageData(image, buffer, buf_offset, copy_size, std::move(plan));
|
||||
|
||||
+4
-4
@@ -83,7 +83,7 @@ public:
|
||||
|
||||
private:
|
||||
enum class TransferDirection { Upload, Download };
|
||||
struct ColorTransferPlan;
|
||||
struct TextureTransferPlan;
|
||||
struct DownloadPlan;
|
||||
|
||||
struct MetaDataInfo {
|
||||
@@ -139,9 +139,9 @@ private:
|
||||
[[nodiscard]] ImageId ExpandImage(const ImageInfo& info, ImageId source);
|
||||
void RefreshImage(ImageId id);
|
||||
void InitializeImage(ImageId id);
|
||||
[[nodiscard]] ColorTransferPlan BuildColorTransfer(const Image& image, BindingType binding,
|
||||
TransferDirection direction) const;
|
||||
[[nodiscard]] DownloadPlan BuildDownload(const Image& image) const;
|
||||
[[nodiscard]] TextureTransferPlan
|
||||
BuildTextureTransfer(const Image& image, BindingType binding, TransferDirection direction) const;
|
||||
[[nodiscard]] DownloadPlan BuildDownload(const Image& image) const;
|
||||
void UploadImage(Image& image, Buffer& source, uint64_t source_offset);
|
||||
void DownloadImageData(Image& image, Buffer& destination, uint64_t destination_offset,
|
||||
uint64_t destination_size, DownloadPlan plan);
|
||||
|
||||
@@ -252,7 +252,7 @@ bool IsSupportedSampledVideoOutView(const ShaderRecompiler::IR::ImageResource& r
|
||||
descriptor.BaseArray5() == 0;
|
||||
}
|
||||
|
||||
bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, const Image& image,
|
||||
bool IsSupportedSampledDepthDescriptor(const ShaderTextureResource& descriptor, const Image& image,
|
||||
bool r128) {
|
||||
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
|
||||
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
|
||||
@@ -291,7 +291,9 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, c
|
||||
(supported_2d || supported_array || supported_cube || supported_msaa_2d ||
|
||||
supported_msaa_array) &&
|
||||
levels_ok && descriptor.MinLod() == 0 &&
|
||||
descriptor.TileMode() == Prospero::TileMode::kDepth && descriptor.BCSwizzle() == 0 &&
|
||||
descriptor.TileMode() == image.info.tile_mode &&
|
||||
(!multisampled || descriptor.TileMode() == Prospero::TileMode::kDepth) &&
|
||||
descriptor.BCSwizzle() == 0 &&
|
||||
(!descriptor.MsaaDepth() || multisampled) && pitch >= width && pitch == image.info.pitch;
|
||||
}
|
||||
|
||||
@@ -332,12 +334,12 @@ bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, co
|
||||
image.info.metadata.range.Valid() && image.info.metadata.range.address == metadata_addr;
|
||||
}
|
||||
|
||||
static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
static void ValidateSampledDepthBinding(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
const ShaderTextureResource& descriptor, const Image* image,
|
||||
vk::Format view_format, uint64_t size) {
|
||||
const bool resource_ok = IsSupportedSampledDepthResource(resource);
|
||||
const bool descriptor_ok =
|
||||
image != nullptr && IsSupportedDepthTargetDescriptor(descriptor, *image, resource.r128);
|
||||
image != nullptr && IsSupportedSampledDepthDescriptor(descriptor, *image, resource.r128);
|
||||
const bool encoding_ok =
|
||||
image != nullptr && IsSupportedDepthTextureEncoding(descriptor, *image, resource.r128);
|
||||
const bool format_ok =
|
||||
@@ -348,7 +350,7 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource
|
||||
const auto descriptor_pitch =
|
||||
TileGetTexturePitch(descriptor.Format(), static_cast<uint32_t>(descriptor.Width5()) + 1u,
|
||||
descriptor.TileMode());
|
||||
EXIT("unsupported sampled depth target: resource=%d descriptor=%d encoding=%d format=%d "
|
||||
EXIT("unsupported sampled depth image: resource=%d descriptor=%d encoding=%d format=%d "
|
||||
"class=%u numeric=%u dimension=%u mip_mode=%u read=%d written=%d atomic=%d compare=%d "
|
||||
"guest_format=%u swizzle=0x%03x image_format=%d view_format=%d image_layers=%u "
|
||||
"descriptor_type=%u base_array=%u depth=%u descriptor_pitch=%u target_pitch=%u "
|
||||
@@ -745,7 +747,10 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
||||
ValidateStorageTexture(resource, descriptor, size.size);
|
||||
}
|
||||
|
||||
const auto pixel_format = surface_format.vk_format;
|
||||
const auto* depth_format = resource.depth_compare ? FindGuestDepthFormatPolicy(format) : nullptr;
|
||||
EXIT_NOT_IMPLEMENTED(resource.depth_compare && depth_format == nullptr);
|
||||
const auto pixel_format =
|
||||
depth_format != nullptr ? depth_format->depth_attachment_format : surface_format.vk_format;
|
||||
const auto storage_view_format = storage && format == Prospero::BufferFormat::k32SInt
|
||||
? vk::Format::eR32Uint
|
||||
: SrgbStorageViewFormat(pixel_format);
|
||||
@@ -784,7 +789,7 @@ TextureBinding RenderExecutor::ResolveTexture(const ShaderRecompiler::IR::ImageR
|
||||
if (storage) {
|
||||
EXIT("depth target cannot be bound as a storage image\n");
|
||||
}
|
||||
ValidateDepthTargetBinding(resource, descriptor, image, pixel_format, size.size);
|
||||
ValidateSampledDepthBinding(resource, descriptor, image, pixel_format, size.size);
|
||||
(void)SelectSampledDepthView(image->info.pixel_format, pixel_format,
|
||||
descriptor.DstSelXYZW());
|
||||
} else if (storage) {
|
||||
|
||||
@@ -78,8 +78,8 @@ struct TargetTextureViewInfo {
|
||||
ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource,
|
||||
Prospero::ImageType type, uint32_t base_layer, uint32_t image_layers);
|
||||
|
||||
[[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
|
||||
const Image& image, bool r128 = false);
|
||||
[[nodiscard]] bool IsSupportedSampledDepthDescriptor(const ShaderTextureResource& descriptor,
|
||||
const Image& image, bool r128 = false);
|
||||
[[nodiscard]] bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor,
|
||||
const Image& image, bool r128 = false);
|
||||
[[nodiscard]] bool
|
||||
|
||||
Reference in New Issue
Block a user