mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-30 09:08:19 +00:00
texture_cache: apply DCC fast clears of mipmapped color targets
Co-authored-by: Artyom Zabroda <artyomzabroda@gmail.com>
This commit is contained in:
1 parent
ae67e2db51
commit
a5cfdcfd32
7 files changed
+189
-79
No files matched your search
@@ -259,6 +259,17 @@ static bool GetMipTailLayout(const TileBlockLayout& block, MipTailLayout& out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint32_t FirstTailLevel(const MipTailLayout& tail, uint32_t width, uint32_t height,
|
||||
uint32_t levels) {
|
||||
for (uint32_t level = 0; levels > 1 && level < levels; ++level) {
|
||||
if (ShiftCeil(width, level) <= tail.width_limit &&
|
||||
ShiftCeil(height, level) <= tail.height_limit && levels - level <= tail.max_levels) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
return levels;
|
||||
}
|
||||
|
||||
bool TileGetTextureElementLayout(Prospero::BufferFormat format, TileTextureElementLayout& out) {
|
||||
if (const auto bytes = Prospero::NumBytesPerElement(format); std::has_single_bit(bytes)) {
|
||||
out = {bytes, 1, 1};
|
||||
@@ -336,23 +347,14 @@ bool TileGetTiledTextureLayout(const TileSurfaceDescription& description, TileSu
|
||||
TileSurfaceLayout result {};
|
||||
result.description = description;
|
||||
result.texture = texture;
|
||||
result.first_tail_level = description.levels;
|
||||
const uint32_t block_slices =
|
||||
volume ? ShiftCeil(description.depth, std::countr_zero(block.block_depth))
|
||||
: description.layers;
|
||||
|
||||
MipTailLayout tail {};
|
||||
const bool has_tail = GetMipTailLayout(block, tail);
|
||||
if (has_tail && description.levels > 1) {
|
||||
for (uint32_t level = 0; level < description.levels; ++level) {
|
||||
if (ShiftCeil(width0, level) <= tail.width_limit &&
|
||||
ShiftCeil(height0, level) <= tail.height_limit &&
|
||||
description.levels - level <= tail.max_levels) {
|
||||
result.first_tail_level = level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.first_tail_level = GetMipTailLayout(block, tail)
|
||||
? FirstTailLevel(tail, width0, height0, description.levels)
|
||||
: description.levels;
|
||||
|
||||
for (uint32_t level = 0; level < result.first_tail_level; ++level) {
|
||||
auto& mip = result.mips[level];
|
||||
@@ -1213,44 +1215,52 @@ bool TileGetRenderTargetSize(uint32_t width, uint32_t height, uint32_t pitch,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TileGetColorMetadataSize(uint32_t width, uint32_t height, uint32_t slices,
|
||||
uint32_t block_width, uint32_t block_height,
|
||||
TileSizeAlign& total_size) {
|
||||
if (width == 0 || height == 0 || slices == 0) {
|
||||
return false;
|
||||
}
|
||||
const uint64_t blocks_x = (static_cast<uint64_t>(width) + block_width - 1u) / block_width;
|
||||
const uint64_t blocks_y = (static_cast<uint64_t>(height) + block_height - 1u) / block_height;
|
||||
const uint64_t blocks = blocks_x * blocks_y;
|
||||
if (blocks > UINT32_MAX / 4096u / slices) {
|
||||
return false;
|
||||
}
|
||||
total_size.size = static_cast<uint32_t>(blocks * slices * 4096u);
|
||||
total_size.align = 4096;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TileGetDccSize(uint32_t width, uint32_t height, uint32_t slices,
|
||||
uint32_t bytes_per_element, uint32_t levels, Prospero::TileMode tile,
|
||||
TileSizeAlign& total_size, uint32_t num_fragments_log2) {
|
||||
TileSizeAlign& total_size, uint32_t num_fragments_log2, TileSizeOffset* mips) {
|
||||
total_size = {};
|
||||
if (levels != 1 || num_fragments_log2 != 0 ||
|
||||
!std::has_single_bit(bytes_per_element) || bytes_per_element > 16 ||
|
||||
(tile != Prospero::TileMode::kRenderTarget && tile != Prospero::TileMode::kDepth)) {
|
||||
TileBlockLayout block {};
|
||||
MipTailLayout tail {};
|
||||
if (slices == 0 || levels > 16 || num_fragments_log2 != 0 ||
|
||||
(tile != Prospero::TileMode::kRenderTarget && tile != Prospero::TileMode::kDepth) ||
|
||||
!TileGetBlockLayout(tile == Prospero::TileMode::kDepth ? TileBlockFamily::Depth64KB
|
||||
: TileBlockFamily::RenderTarget64KB,
|
||||
bytes_per_element, block) ||
|
||||
!GetMipTailLayout(block, tail)) {
|
||||
return false;
|
||||
}
|
||||
// Gen5 DCC uses 4 KiB blocks, with one byte per 256 bytes of color data.
|
||||
// Metadata stays thin for volume surfaces, so every depth slice has its own block raster.
|
||||
// Gen5 DCC uses 4 KiB blocks, with one byte per 256 bytes of color data. Each slice stores
|
||||
// its mips backwards through the first tail mip, which fits one block; later tail mips have
|
||||
// none. Metadata stays thin for volume surfaces, so every depth slice has its own block raster.
|
||||
const uint32_t coverage_bits = 20u - std::countr_zero(bytes_per_element);
|
||||
return TileGetColorMetadataSize(width, height, slices, 1u << ((coverage_bits + 1u) / 2u),
|
||||
1u << (coverage_bits / 2u), total_size);
|
||||
uint64_t slice_size = 0;
|
||||
for (uint32_t level = std::min(FirstTailLevel(tail, width, height, levels) + 1u, levels);
|
||||
level-- > 0;) {
|
||||
const uint64_t size = uint64_t {ShiftCeil(width, level + (coverage_bits + 1u) / 2u)} *
|
||||
ShiftCeil(height, level + coverage_bits / 2u) * 4096u;
|
||||
if (mips != nullptr) {
|
||||
mips[level] = {.size = static_cast<uint32_t>(size),
|
||||
.offset = static_cast<uint32_t>(slice_size)};
|
||||
}
|
||||
slice_size += size;
|
||||
}
|
||||
if (slice_size == 0 || slice_size > UINT32_MAX / slices) {
|
||||
return false;
|
||||
}
|
||||
total_size = {static_cast<uint32_t>(slice_size * slices), 4096};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TileGetCmaskSize(uint32_t width, uint32_t height, uint32_t slices, uint32_t levels,
|
||||
TileSizeAlign& total_size) {
|
||||
total_size = {};
|
||||
// Gen5 CMASK stores four bits per 8x8 tile in 4 KiB blocks covering 1024x512 pixels.
|
||||
return levels == 1 && TileGetColorMetadataSize(width, height, slices, 1024, 512, total_size);
|
||||
const uint64_t blocks = uint64_t {ShiftCeil(width, 10)} * ShiftCeil(height, 9);
|
||||
if (levels != 1 || blocks == 0 || slices == 0 || blocks > UINT32_MAX / 4096u / slices) {
|
||||
return false;
|
||||
}
|
||||
total_size = {static_cast<uint32_t>(blocks * slices * 4096u), 4096};
|
||||
return true;
|
||||
}
|
||||
|
||||
void TileGetTextureSize(Prospero::BufferFormat format, uint32_t width, uint32_t height,
|
||||
|
||||
Reference in new issue
Block a user