mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
remove redundant cache and tiler validation
This commit is contained in:
@@ -1243,12 +1243,6 @@ bool BufferCache::IsRegionCpuModified(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::PublishImageBacking(uint64_t vaddr, uint64_t size) {
|
void BufferCache::PublishImageBacking(uint64_t vaddr, uint64_t size) {
|
||||||
if (vaddr == 0 || size == 0 || vaddr >= TRACKER_ADDRESS_SIZE ||
|
|
||||||
size > TRACKER_ADDRESS_SIZE - vaddr) {
|
|
||||||
EXIT("BufferCache: invalid image-backing publication, addr=0x%016" PRIx64
|
|
||||||
" size=0x%016" PRIx64 "\n",
|
|
||||||
vaddr, size);
|
|
||||||
}
|
|
||||||
FaultSafeCacheLock lock(this, m_mutex);
|
FaultSafeCacheLock lock(this, m_mutex);
|
||||||
auto owner = m_buffers.end();
|
auto owner = m_buffers.end();
|
||||||
for (auto it = m_buffers.begin(); it != m_buffers.end(); ++it) {
|
for (auto it = m_buffers.begin(); it != m_buffers.end(); ++it) {
|
||||||
@@ -1265,10 +1259,7 @@ void BufferCache::PublishImageBacking(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
owner = it;
|
owner = it;
|
||||||
}
|
}
|
||||||
if ((owner != m_buffers.end() &&
|
if ((owner != m_buffers.end() && m_memory_tracker.IsRegionCpuModified(vaddr, size)) ||
|
||||||
(owner->second->ctx == nullptr || owner->second->buffer == nullptr ||
|
|
||||||
owner->second->buffer->buffer == nullptr ||
|
|
||||||
m_memory_tracker.IsRegionCpuModified(vaddr, size))) ||
|
|
||||||
m_memory_tracker.IsRegionGpuModified(vaddr, size) ||
|
m_memory_tracker.IsRegionGpuModified(vaddr, size) ||
|
||||||
!m_gpu_modified_ranges.Intersections(vaddr, size).empty()) {
|
!m_gpu_modified_ranges.Intersections(vaddr, size).empty()) {
|
||||||
EXIT("BufferCache: image backing requires clean buffer ownership, addr=0x%016" PRIx64
|
EXIT("BufferCache: image backing requires clean buffer ownership, addr=0x%016" PRIx64
|
||||||
|
|||||||
@@ -431,38 +431,21 @@ struct TextureCache::ReadbackWorker {
|
|||||||
!storage || (single_layer_storage && cached.info.base_level == 0 &&
|
!storage || (single_layer_storage && cached.info.base_level == 0 &&
|
||||||
cached.info.levels == 1 && cached.info.base_array == 0 && linear);
|
cached.info.levels == 1 && cached.info.base_array == 0 && linear);
|
||||||
const auto layers = target ? cached.target.layers : 1u;
|
const auto layers = target ? cached.target.layers : 1u;
|
||||||
const auto rows = static_cast<uint64_t>(info.height - 1);
|
if ((!linear && !tiled) || !basic_storage || info.levels != 1 || info.size > UINT32_MAX) {
|
||||||
if ((!linear && !tiled) || !basic_storage || info.address == 0 || info.size == 0 ||
|
|
||||||
info.width == 0 || info.height == 0 || info.levels != 1 || info.pitch < info.width ||
|
|
||||||
info.bytes_per_element == 0 || layers == 0 || info.size > UINT32_MAX ||
|
|
||||||
info.size % layers != 0 || cached.image->layers != layers ||
|
|
||||||
rows > (UINT64_MAX - info.width) / info.pitch) {
|
|
||||||
EXIT("TextureCache: unsupported color-image readback layout, addr=0x%016" PRIx64
|
EXIT("TextureCache: unsupported color-image readback layout, addr=0x%016" PRIx64
|
||||||
" size=0x%016" PRIx64 " extent=%ux%u pitch=%u bpe=%u levels=%u tile=%u kind=%u\n",
|
" size=0x%016" PRIx64 " extent=%ux%u pitch=%u bpe=%u levels=%u tile=%u kind=%u\n",
|
||||||
info.address, info.size, info.width, info.height, info.pitch,
|
info.address, info.size, info.width, info.height, info.pitch,
|
||||||
info.bytes_per_element, info.levels, info.tile_mode,
|
info.bytes_per_element, info.levels, info.tile_mode,
|
||||||
static_cast<uint32_t>(cached.kind));
|
static_cast<uint32_t>(cached.kind));
|
||||||
}
|
}
|
||||||
const auto linear_elements = rows * info.pitch + info.width;
|
|
||||||
if (linear_elements > UINT64_MAX / info.bytes_per_element) {
|
|
||||||
EXIT("TextureCache: color-image readback size overflow\n");
|
|
||||||
}
|
|
||||||
const auto linear_size = linear_elements * info.bytes_per_element;
|
|
||||||
const auto slice_size = info.size / layers;
|
const auto slice_size = info.size / layers;
|
||||||
const bool meta_overlap = cache.HasMetaOverlapLocked(info.address, info.size);
|
const bool meta_overlap = cache.HasMetaOverlapLocked(info.address, info.size);
|
||||||
const bool buffer_overlap = cache.m_buffer_cache.HasPageOverlap(info.address, info.size);
|
const bool buffer_overlap = cache.m_buffer_cache.HasPageOverlap(info.address, info.size);
|
||||||
if (linear_size > slice_size || cached.image->format != info.format ||
|
if (meta_overlap || buffer_overlap) {
|
||||||
cached.image->extent.width != info.width ||
|
|
||||||
cached.image->extent.height != info.height ||
|
|
||||||
(tiled && !IsSupportedRenderTargetElementSize(info.bytes_per_element)) ||
|
|
||||||
meta_overlap || buffer_overlap) {
|
|
||||||
EXIT("TextureCache: color-image readback storage is unsupported, addr=0x%016" PRIx64
|
EXIT("TextureCache: color-image readback storage is unsupported, addr=0x%016" PRIx64
|
||||||
" size=0x%016" PRIx64 " linear=0x%016" PRIx64
|
" size=0x%016" PRIx64 " meta=%d buffer=%d kind=%u\n",
|
||||||
" format=%d/%d extent=%ux%u/%ux%u bpe=%u tiled=%d meta=%d kind=%u\n",
|
info.address, info.size, meta_overlap, buffer_overlap,
|
||||||
info.address, info.size, linear_size, static_cast<int>(cached.image->format),
|
static_cast<uint32_t>(cached.kind));
|
||||||
static_cast<int>(info.format), cached.image->extent.width,
|
|
||||||
cached.image->extent.height, info.width, info.height, info.bytes_per_element,
|
|
||||||
tiled, meta_overlap, static_cast<uint32_t>(cached.kind));
|
|
||||||
}
|
}
|
||||||
download.resize(info.size);
|
download.resize(info.size);
|
||||||
std::fill(download.begin(), download.end(), 0);
|
std::fill(download.begin(), download.end(), 0);
|
||||||
@@ -982,8 +965,9 @@ void UploadRenderTargetLayers(GraphicContext* ctx, RenderTextureVulkanImage* ima
|
|||||||
false, false, false, "TextureCache render target");
|
false, false, false, "TextureCache render target");
|
||||||
const bool render_target_tiled =
|
const bool render_target_tiled =
|
||||||
info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget);
|
||||||
if ((render_target_tiled && !layout.fmt_tiled_render_target) ||
|
if (!standard64 &&
|
||||||
(standard64 && !layout.fmt_tiled_standard64kb) || layout.pitch != info.pitch) {
|
((render_target_tiled && !layout.fmt_tiled_render_target) ||
|
||||||
|
layout.pitch != info.pitch)) {
|
||||||
EXIT("TextureCache: unsupported render-target mip upload layout, pitch=%u/%u tile=%u\n",
|
EXIT("TextureCache: unsupported render-target mip upload layout, pitch=%u/%u tile=%u\n",
|
||||||
info.pitch, layout.pitch, info.tile_mode);
|
info.pitch, layout.pitch, info.tile_mode);
|
||||||
}
|
}
|
||||||
@@ -1785,6 +1769,7 @@ VulkanImage* TextureCache::FindTexture(CommandBuffer* command, GraphicContext* c
|
|||||||
if (command == nullptr || ctx == nullptr || info.address == 0 || info.size == 0 ||
|
if (command == nullptr || ctx == nullptr || info.address == 0 || info.size == 0 ||
|
||||||
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
|
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
|
||||||
info.width == 0 || info.height == 0 || info.depth == 0 || info.levels == 0 ||
|
info.width == 0 || info.height == 0 || info.depth == 0 || info.levels == 0 ||
|
||||||
|
info.levels >= 16 ||
|
||||||
info.view_levels == 0 || info.base_level + info.view_levels > info.levels) {
|
info.view_levels == 0 || info.base_level + info.view_levels > info.levels) {
|
||||||
EXIT("TextureCache: invalid sampled-image request, command=%p ctx=%p addr=0x%016" PRIx64
|
EXIT("TextureCache: invalid sampled-image request, command=%p ctx=%p addr=0x%016" PRIx64
|
||||||
" size=0x%016" PRIx64 " extent=%ux%ux%u levels=%u\n",
|
" size=0x%016" PRIx64 " extent=%ux%ux%u levels=%u\n",
|
||||||
@@ -2302,6 +2287,7 @@ DepthStencilVulkanImage* TextureCache::FindDepthTarget(CommandBuffer* command, G
|
|||||||
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
|
info.address >= TRACKER_ADDRESS_SIZE || info.size > TRACKER_ADDRESS_SIZE - info.address ||
|
||||||
(info.address & 0xffffu) != 0 || info.width == 0 || info.height == 0 ||
|
(info.address & 0xffffu) != 0 || info.width == 0 || info.height == 0 ||
|
||||||
info.pitch < info.width || info.layers == 0 || info.size % info.layers != 0 ||
|
info.pitch < info.width || info.layers == 0 || info.size % info.layers != 0 ||
|
||||||
|
info.size > UINT32_MAX || info.stencil_size > UINT32_MAX ||
|
||||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
||||||
(has_stencil &&
|
(has_stencil &&
|
||||||
(info.stencil_address == 0 || info.stencil_size == 0 ||
|
(info.stencil_address == 0 || info.stencil_size == 0 ||
|
||||||
@@ -3101,10 +3087,8 @@ void TextureCache::PrepareHostWrite(uint64_t vaddr, uint64_t size) {
|
|||||||
void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
||||||
const bool render_target = cached.kind == CachedImage::Kind::RenderTarget;
|
const bool render_target = cached.kind == CachedImage::Kind::RenderTarget;
|
||||||
const bool video_out = cached.kind == CachedImage::Kind::VideoOut;
|
const bool video_out = cached.kind == CachedImage::Kind::VideoOut;
|
||||||
RenderTargetInfo target {};
|
RenderTargetInfo target = cached.target;
|
||||||
if (render_target) {
|
if (video_out) {
|
||||||
target = cached.target;
|
|
||||||
} else if (video_out) {
|
|
||||||
const auto& info = cached.video_out;
|
const auto& info = cached.video_out;
|
||||||
target.address = info.address;
|
target.address = info.address;
|
||||||
target.size = info.size;
|
target.size = info.size;
|
||||||
@@ -3117,64 +3101,43 @@ void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
|||||||
}
|
}
|
||||||
const bool linear = target.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
const bool linear = target.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kLinear);
|
||||||
const bool tiled = IsTiledRenderTarget(target);
|
const bool tiled = IsTiledRenderTarget(target);
|
||||||
const auto rows = static_cast<uint64_t>(target.height - 1);
|
|
||||||
TileSizeAlign exact {};
|
TileSizeAlign exact {};
|
||||||
bool single_slice = false;
|
bool single_slice = false;
|
||||||
if (IsSupportedStandard64RenderTarget(target)) {
|
if (IsSupportedStandard64RenderTarget(target)) {
|
||||||
const auto format = RenderTargetTransferFormat(target.bytes_per_element);
|
exact = {static_cast<uint32_t>(target.size), 65536};
|
||||||
const auto expected_pitch =
|
single_slice = true;
|
||||||
TileGetTexturePitch(format, target.width, target.levels, target.tile_mode);
|
|
||||||
TileGetTextureSize(format, target.width, target.height, expected_pitch, target.levels,
|
|
||||||
target.tile_mode, &exact, nullptr, nullptr);
|
|
||||||
single_slice = target.pitch == expected_pitch && exact.align == 65536 && exact.size != 0;
|
|
||||||
} else {
|
} else {
|
||||||
single_slice = TileGetRenderTargetSize(target.width, target.height, target.pitch,
|
single_slice = TileGetRenderTargetSize(target.width, target.height, target.pitch,
|
||||||
target.bytes_per_element, &exact);
|
target.bytes_per_element, &exact);
|
||||||
}
|
}
|
||||||
const bool layered_size = target.layers != 0 && single_slice &&
|
const bool layered_size =
|
||||||
exact.size <= UINT64_MAX / target.layers &&
|
single_slice && static_cast<uint64_t>(exact.size) * target.layers == target.size;
|
||||||
exact.size * target.layers == target.size;
|
|
||||||
const bool exact_tiled = tiled && exact.align == 65536 && layered_size;
|
const bool exact_tiled = tiled && exact.align == 65536 && layered_size;
|
||||||
const bool valid_video_out =
|
const bool valid_kind = render_target ||
|
||||||
video_out && cached.video_out.compression == VideoOutCompression::Uncompressed &&
|
(video_out && cached.video_out.compression ==
|
||||||
cached.video_out.metadata_address == 0 && cached.video_out.dcc_control == 0 &&
|
VideoOutCompression::Uncompressed);
|
||||||
target.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) &&
|
if (!valid_kind || !cached.gpu_modified || cached.buffer_modified || target.levels != 1 ||
|
||||||
target.bytes_per_element == 4 && (target.address & 0xffffu) == 0;
|
target.size > UINT32_MAX || (!linear && !exact_tiled) ||
|
||||||
const bool valid_cache = (render_target || valid_video_out) && cached.gpu_modified &&
|
HasMetaOverlapLocked(target.address, target.size)) {
|
||||||
!cached.buffer_modified && cached.ctx != nullptr &&
|
|
||||||
cached.image != nullptr;
|
|
||||||
const bool valid_target =
|
|
||||||
target.address != 0 && target.size != 0 && target.width != 0 && target.height != 0 &&
|
|
||||||
target.pitch >= target.width && target.bytes_per_element != 0 && target.layers != 0 &&
|
|
||||||
target.size % target.layers == 0 && target.size <= UINT32_MAX && target.levels == 1 &&
|
|
||||||
rows <= (UINT64_MAX - target.width) / target.pitch;
|
|
||||||
const bool valid_image = cached.image != nullptr && cached.image->layers == target.layers;
|
|
||||||
if (!valid_cache || !valid_target || (!linear && !exact_tiled) || !valid_image) {
|
|
||||||
EXIT("TextureCache: unsupported color-image buffer synchronization, "
|
EXIT("TextureCache: unsupported color-image buffer synchronization, "
|
||||||
"addr=0x%016" PRIx64 " size=0x%016" PRIx64
|
"addr=0x%016" PRIx64 " size=0x%016" PRIx64
|
||||||
" extent=%ux%u pitch=%u bpe=%u levels=%u layers=%u/%u tile=%u"
|
" extent=%ux%u pitch=%u bpe=%u levels=%u layers=%u tile=%u"
|
||||||
" kind=%u compression=%u gpu_modified=%d buffer_modified=%d\n",
|
" kind=%u compression=%u gpu_modified=%d buffer_modified=%d\n",
|
||||||
target.address, target.size, target.width, target.height, target.pitch,
|
target.address, target.size, target.width, target.height, target.pitch,
|
||||||
target.bytes_per_element, target.levels, target.layers,
|
target.bytes_per_element, target.levels, target.layers, target.tile_mode,
|
||||||
cached.image == nullptr ? 0 : cached.image->layers, target.tile_mode,
|
|
||||||
static_cast<uint32_t>(cached.kind),
|
static_cast<uint32_t>(cached.kind),
|
||||||
video_out ? static_cast<uint32_t>(cached.video_out.compression) : 0,
|
video_out ? static_cast<uint32_t>(cached.video_out.compression) : 0,
|
||||||
cached.gpu_modified, cached.buffer_modified);
|
cached.gpu_modified, cached.buffer_modified);
|
||||||
}
|
}
|
||||||
const auto linear_elements = rows * target.pitch + target.width;
|
|
||||||
if (linear_elements > UINT64_MAX / target.bytes_per_element) {
|
|
||||||
EXIT("TextureCache: color-image buffer synchronization size overflow\n");
|
|
||||||
}
|
|
||||||
const auto linear_size = linear_elements * target.bytes_per_element;
|
|
||||||
const auto slice_size = target.size / target.layers;
|
const auto slice_size = target.size / target.layers;
|
||||||
if (linear_size > slice_size || cached.image->format != target.format ||
|
if (cached.image->format != target.format ||
|
||||||
cached.image->extent.width != target.width ||
|
cached.image->extent.width != target.width ||
|
||||||
cached.image->extent.height != target.height ||
|
cached.image->extent.height != target.height ||
|
||||||
(tiled && !IsSupportedRenderTargetElementSize(target.bytes_per_element)) ||
|
(tiled && !IsSupportedRenderTargetElementSize(target.bytes_per_element)) ||
|
||||||
HasMetaOverlapLocked(target.address, target.size)) {
|
HasMetaOverlapLocked(target.address, target.size)) {
|
||||||
EXIT("TextureCache: color-image buffer synchronization storage mismatch, "
|
EXIT("TextureCache: color-image buffer synchronization storage mismatch, "
|
||||||
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 " linear=0x%016" PRIx64 "\n",
|
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 " linear=0x%016" PRIx64 "\n",
|
||||||
target.address, target.size, linear_size);
|
target.address, target.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the CPU Tiler backend for the image-to-buffer synchronization seam.
|
// This is the CPU Tiler backend for the image-to-buffer synchronization seam.
|
||||||
@@ -3199,9 +3162,6 @@ void TextureCache::SynchronizeColorImageToBufferLocked(CachedImage& cached) {
|
|||||||
}
|
}
|
||||||
m_memory_tracker.ForEachDownloadRange<true>(target.address, target.size,
|
m_memory_tracker.ForEachDownloadRange<true>(target.address, target.size,
|
||||||
[](uint64_t, uint64_t) noexcept {});
|
[](uint64_t, uint64_t) noexcept {});
|
||||||
if (m_memory_tracker.IsRegionGpuModified(target.address, target.size)) {
|
|
||||||
EXIT("TextureCache: color-image buffer synchronization retained GPU ownership\n");
|
|
||||||
}
|
|
||||||
m_buffer_cache.PublishImageBacking(target.address, target.size);
|
m_buffer_cache.PublishImageBacking(target.address, target.size);
|
||||||
cached.gpu_modified = false;
|
cached.gpu_modified = false;
|
||||||
cached.buffer_modified = true;
|
cached.buffer_modified = true;
|
||||||
@@ -3262,17 +3222,9 @@ bool TextureCache::InvalidateMemoryFromGPU(uint64_t vaddr, uint64_t size,
|
|||||||
case BufferImageWrite::InvalidateTexture:
|
case BufferImageWrite::InvalidateTexture:
|
||||||
case BufferImageWrite::InvalidateVideoOut: cached.buffer_modified = true; return true;
|
case BufferImageWrite::InvalidateVideoOut: cached.buffer_modified = true; return true;
|
||||||
case BufferImageWrite::SynchronizeRenderTarget:
|
case BufferImageWrite::SynchronizeRenderTarget:
|
||||||
if (cached.kind != CachedImage::Kind::RenderTarget) {
|
|
||||||
EXIT("TextureCache: render-target synchronization action has kind=%u\n",
|
|
||||||
static_cast<uint32_t>(cached.kind));
|
|
||||||
}
|
|
||||||
SynchronizeColorImageToBufferLocked(cached);
|
SynchronizeColorImageToBufferLocked(cached);
|
||||||
return true;
|
return true;
|
||||||
case BufferImageWrite::SynchronizeVideoOut:
|
case BufferImageWrite::SynchronizeVideoOut:
|
||||||
if (cached.kind != CachedImage::Kind::VideoOut) {
|
|
||||||
EXIT("TextureCache: video-out synchronization action has kind=%u\n",
|
|
||||||
static_cast<uint32_t>(cached.kind));
|
|
||||||
}
|
|
||||||
SynchronizeColorImageToBufferLocked(cached);
|
SynchronizeColorImageToBufferLocked(cached);
|
||||||
return true;
|
return true;
|
||||||
case BufferImageWrite::None:
|
case BufferImageWrite::None:
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ static void UploadPromotedD16Depth(GraphicContext* ctx, DepthStencilVulkanImage*
|
|||||||
const uint64_t texels = static_cast<uint64_t>(info.pitch) * info.height;
|
const uint64_t texels = static_cast<uint64_t>(info.pitch) * info.height;
|
||||||
const uint64_t host_slice_size = texels * sizeof(uint32_t);
|
const uint64_t host_slice_size = texels * sizeof(uint32_t);
|
||||||
const uint64_t host_upload_size = host_slice_size * info.layers;
|
const uint64_t host_upload_size = host_slice_size * info.layers;
|
||||||
if (slice_size % sizeof(uint16_t) != 0 || texels > slice_size / sizeof(uint16_t) ||
|
if (host_upload_size > UINT32_MAX) {
|
||||||
host_upload_size > UINT32_MAX) {
|
|
||||||
EXIT("Tiler: invalid D16 host-promotion footprint, guest_slice=0x%016" PRIx64
|
EXIT("Tiler: invalid D16 host-promotion footprint, guest_slice=0x%016" PRIx64
|
||||||
" host_slice=0x%016" PRIx64 " layers=%u\n",
|
" host_slice=0x%016" PRIx64 " layers=%u\n",
|
||||||
slice_size, host_slice_size, info.layers);
|
slice_size, host_slice_size, info.layers);
|
||||||
@@ -54,19 +53,6 @@ static void UploadPromotedD16Depth(GraphicContext* ctx, DepthStencilVulkanImage*
|
|||||||
|
|
||||||
void Tiler::DetileImage(GraphicContext* ctx, GpuTextureVulkanImage* image, const ImageInfo& info,
|
void Tiler::DetileImage(GraphicContext* ctx, GpuTextureVulkanImage* image, const ImageInfo& info,
|
||||||
const BufferImageCopySource& source, bool refresh, bool storage) const {
|
const BufferImageCopySource& source, bool refresh, bool storage) const {
|
||||||
if (ctx == nullptr || image == nullptr || info.address == 0 || info.size == 0 ||
|
|
||||||
info.width == 0 || info.height == 0 || info.depth == 0 || info.levels == 0 ||
|
|
||||||
info.levels >= 16 || !source.cpu_current || source.address != info.address ||
|
|
||||||
source.size != info.size || (source.buffer == nullptr && source.offset != 0)) {
|
|
||||||
EXIT("Tiler: unsupported sampled-image detile, ctx=%p image=%p source_buffer=%p "
|
|
||||||
"source=0x%016" PRIx64 "+0x%016" PRIx64 " offset=0x%016" PRIx64
|
|
||||||
" current=%d image=0x%016" PRIx64 "+0x%016" PRIx64
|
|
||||||
" extent=%ux%ux%u levels=%u tile=%u storage=%d\n",
|
|
||||||
static_cast<const void*>(ctx), static_cast<const void*>(image),
|
|
||||||
static_cast<const void*>(source.buffer), source.address, source.size, source.offset,
|
|
||||||
source.cpu_current, info.address, info.size, info.width, info.height, info.depth,
|
|
||||||
info.levels, info.tile, storage);
|
|
||||||
}
|
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
VulkanDeviceWaitIdle(ctx);
|
VulkanDeviceWaitIdle(ctx);
|
||||||
}
|
}
|
||||||
@@ -79,9 +65,6 @@ void Tiler::DetileImage(GraphicContext* ctx, GpuTextureVulkanImage* image, const
|
|||||||
auto regions = TextureBuildUploadRegions(layout, image->format, info.width, info.height,
|
auto regions = TextureBuildUploadRegions(layout, image->format, info.width, info.height,
|
||||||
info.depth, info.levels, array_texture, volume_texture,
|
info.depth, info.levels, array_texture, volume_texture,
|
||||||
TextureUploadDestination::MipLevels, slice_layout);
|
TextureUploadDestination::MipLevels, slice_layout);
|
||||||
// Keep the buffer owner explicit at the detiling seam. The current PS5
|
|
||||||
// backend consumes the coherent guest publication; a GPU detiler can consume source.buffer and
|
|
||||||
// source.offset here without changing TextureCache ownership or alias classification.
|
|
||||||
TextureUploadGuestImage(
|
TextureUploadGuestImage(
|
||||||
ctx, image, reinterpret_cast<const void*>(source.address), info.size, regions, layout,
|
ctx, image, reinterpret_cast<const void*>(source.address), info.size, regions, layout,
|
||||||
info.format, info.width, info.height, info.depth, info.levels, slice_layout,
|
info.format, info.width, info.height, info.depth, info.levels, slice_layout,
|
||||||
@@ -93,24 +76,6 @@ void Tiler::DetileImage(GraphicContext* ctx, GpuTextureVulkanImage* image, const
|
|||||||
void Tiler::DetileImage(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
void Tiler::DetileImage(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
||||||
const DepthTargetInfo& info, const BufferImageCopySource& source,
|
const DepthTargetInfo& info, const BufferImageCopySource& source,
|
||||||
bool refresh, uint32_t base_layer) const {
|
bool refresh, uint32_t base_layer) const {
|
||||||
if (ctx == nullptr || image == nullptr || info.address == 0 || info.size == 0 ||
|
|
||||||
info.width == 0 || info.height == 0 || info.pitch < info.width || info.layers == 0 ||
|
|
||||||
info.size % info.layers != 0 || base_layer > image->layers ||
|
|
||||||
info.layers > image->layers - base_layer || info.size > UINT32_MAX ||
|
|
||||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
|
||||||
!IsSupportedDepthTargetFormat(info) || !source.cpu_current ||
|
|
||||||
source.address != info.address || source.size != info.size ||
|
|
||||||
(source.buffer == nullptr && source.offset != 0)) {
|
|
||||||
EXIT("Tiler: unsupported depth detile, ctx=%p image=%p source_buffer=%p "
|
|
||||||
"source=0x%016" PRIx64 "+0x%016" PRIx64 " offset=0x%016" PRIx64
|
|
||||||
" current=%d depth=0x%016" PRIx64 "+0x%016" PRIx64
|
|
||||||
" extent=%ux%u pitch=%u tile=%u format=%d guest_format=%u bpe=%u\n",
|
|
||||||
static_cast<const void*>(ctx), static_cast<const void*>(image),
|
|
||||||
static_cast<const void*>(source.buffer), source.address, source.size, source.offset,
|
|
||||||
source.cpu_current, info.address, info.size, info.width, info.height, info.pitch,
|
|
||||||
info.tile_mode, static_cast<int>(info.format), info.guest_format,
|
|
||||||
info.bytes_per_element);
|
|
||||||
}
|
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
VulkanDeviceWaitIdle(ctx);
|
VulkanDeviceWaitIdle(ctx);
|
||||||
}
|
}
|
||||||
@@ -152,40 +117,9 @@ void Tiler::DetileImage(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
|||||||
void Tiler::DetileStencil(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
void Tiler::DetileStencil(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
||||||
const DepthTargetInfo& info, const BufferImageCopySource& source,
|
const DepthTargetInfo& info, const BufferImageCopySource& source,
|
||||||
bool refresh, uint32_t base_layer) const {
|
bool refresh, uint32_t base_layer) const {
|
||||||
TileSizeAlign stencil_size {};
|
|
||||||
TileSizeAlign htile_size {};
|
|
||||||
TileSizeAlign depth_size {};
|
|
||||||
const auto stencil_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt);
|
const auto stencil_format = Prospero::GpuEnumValue(Prospero::BufferFormat::k8UInt);
|
||||||
const auto* policy = FindGuestDepthFormatPolicy(info.guest_format);
|
|
||||||
const auto stencil_pitch = TileGetTexturePitch(
|
const auto stencil_pitch = TileGetTexturePitch(
|
||||||
stencil_format, info.width, 1, Prospero::GpuEnumValue(Prospero::TileMode::kDepth));
|
stencil_format, info.width, 1, Prospero::GpuEnumValue(Prospero::TileMode::kDepth));
|
||||||
const bool supported_layout =
|
|
||||||
policy != nullptr && IsSupportedDepthTargetFormat(info) &&
|
|
||||||
TileGetDepthSize(info.width, info.height, 0, Prospero::GpuEnumValue(policy->depth_format),
|
|
||||||
Prospero::GpuEnumValue(Prospero::StencilFormat::k8UInt),
|
|
||||||
info.htile_address != 0, &stencil_size, &htile_size, &depth_size) &&
|
|
||||||
info.layers != 0 && info.stencil_size % info.layers == 0 &&
|
|
||||||
stencil_size.size == info.stencil_size / info.layers && stencil_size.align == 65536 &&
|
|
||||||
stencil_pitch != 0;
|
|
||||||
if (ctx == nullptr || image == nullptr || info.address == 0 || info.size == 0 ||
|
|
||||||
info.stencil_address == 0 || info.stencil_size == 0 || info.width == 0 ||
|
|
||||||
info.height == 0 || base_layer > image->layers ||
|
|
||||||
info.layers > image->layers - base_layer || info.stencil_size > UINT32_MAX ||
|
|
||||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
|
||||||
info.stencil_htile_compressed || !supported_layout || !source.cpu_current ||
|
|
||||||
source.address != info.stencil_address || source.size != info.stencil_size ||
|
|
||||||
(source.buffer == nullptr && source.offset != 0)) {
|
|
||||||
EXIT("Tiler: unsupported stencil detile, ctx=%p image=%p source_buffer=%p "
|
|
||||||
"source=0x%016" PRIx64 "+0x%016" PRIx64 " offset=0x%016" PRIx64
|
|
||||||
" current=%d stencil=0x%016" PRIx64 "+0x%016" PRIx64
|
|
||||||
" extent=%ux%u depth_pitch=%u stencil_pitch=%u tile=%u format=%d guest_format=%u "
|
|
||||||
"bpe=%u\n",
|
|
||||||
static_cast<const void*>(ctx), static_cast<const void*>(image),
|
|
||||||
static_cast<const void*>(source.buffer), source.address, source.size, source.offset,
|
|
||||||
source.cpu_current, info.stencil_address, info.stencil_size, info.width, info.height,
|
|
||||||
info.pitch, stencil_pitch, info.tile_mode, static_cast<int>(info.format),
|
|
||||||
info.guest_format, info.bytes_per_element);
|
|
||||||
}
|
|
||||||
if (refresh) {
|
if (refresh) {
|
||||||
VulkanDeviceWaitIdle(ctx);
|
VulkanDeviceWaitIdle(ctx);
|
||||||
}
|
}
|
||||||
@@ -212,11 +146,10 @@ void Tiler::DetileStencil(GraphicContext* ctx, DepthStencilVulkanImage* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info) const {
|
void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info) const {
|
||||||
if (dst == nullptr || src == nullptr || info.address == 0 || info.size == 0 ||
|
const bool standard64 = IsSupportedStandard64RenderTarget(info);
|
||||||
info.width == 0 || info.height == 0 || info.pitch < info.width ||
|
if ((info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kRenderTarget) &&
|
||||||
!IsTiledRenderTarget(info) ||
|
!standard64) ||
|
||||||
info.levels != 1 || info.layers == 0 || info.size % info.layers != 0 ||
|
info.levels != 1) {
|
||||||
!IsSupportedRenderTargetElementSize(info.bytes_per_element)) {
|
|
||||||
EXIT("Tiler: unsupported render-target tile, dst=%p src=%p "
|
EXIT("Tiler: unsupported render-target tile, dst=%p src=%p "
|
||||||
"addr=0x%016" PRIx64 "+0x%016" PRIx64
|
"addr=0x%016" PRIx64 "+0x%016" PRIx64
|
||||||
" extent=%ux%u pitch=%u levels=%u tile=%u bpe=%u\n",
|
" extent=%ux%u pitch=%u levels=%u tile=%u bpe=%u\n",
|
||||||
@@ -227,7 +160,7 @@ void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info)
|
|||||||
for (uint32_t layer = 0; layer < info.layers; layer++) {
|
for (uint32_t layer = 0; layer < info.layers; layer++) {
|
||||||
auto* guest_slice = static_cast<uint8_t*>(dst) + slice_size * layer;
|
auto* guest_slice = static_cast<uint8_t*>(dst) + slice_size * layer;
|
||||||
auto* linear_slice = static_cast<const uint8_t*>(src) + slice_size * layer;
|
auto* linear_slice = static_cast<const uint8_t*>(src) + slice_size * layer;
|
||||||
if (IsSupportedStandard64RenderTarget(info)) {
|
if (standard64) {
|
||||||
TileConvertLinearToTiledStandard64KB32(guest_slice, linear_slice, info.width,
|
TileConvertLinearToTiledStandard64KB32(guest_slice, linear_slice, info.width,
|
||||||
info.height, info.pitch, slice_size);
|
info.height, info.pitch, slice_size);
|
||||||
} else {
|
} else {
|
||||||
@@ -238,12 +171,9 @@ void Tiler::TileImage(void* dst, const void* src, const RenderTargetInfo& info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Tiler::TileImage(void* dst, const void* src, const DepthTargetInfo& info) const {
|
void Tiler::TileImage(void* dst, const void* src, const DepthTargetInfo& info) const {
|
||||||
const bool supported_format = IsSupportedDepthTargetFormat(info);
|
if (info.stencil_address != 0 || info.stencil_size != 0 ||
|
||||||
if (dst == nullptr || src == nullptr || info.address == 0 || info.size == 0 ||
|
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) ||
|
||||||
info.stencil_address != 0 || info.stencil_size != 0 || info.width == 0 ||
|
!IsSupportedDepthTargetFormat(info)) {
|
||||||
info.height == 0 || info.pitch < info.width ||
|
|
||||||
info.tile_mode != Prospero::GpuEnumValue(Prospero::TileMode::kDepth) || info.layers == 0 ||
|
|
||||||
info.size % info.layers != 0 || !supported_format) {
|
|
||||||
EXIT("Tiler: unsupported depth-target tile, dst=%p src=%p "
|
EXIT("Tiler: unsupported depth-target tile, dst=%p src=%p "
|
||||||
"depth=0x%016" PRIx64 "+0x%016" PRIx64 " stencil=0x%016" PRIx64 "+0x%016" PRIx64
|
"depth=0x%016" PRIx64 "+0x%016" PRIx64 " stencil=0x%016" PRIx64 "+0x%016" PRIx64
|
||||||
" extent=%ux%u pitch=%u tile=%u format=%d guest_format=%u bpe=%u\n",
|
" extent=%ux%u pitch=%u tile=%u format=%d guest_format=%u bpe=%u\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user