Implement 0x12 CopyData, sampled-to-depth fix, stencil detailing

This commit is contained in:
nmzik
2026-07-16 19:03:31 +02:00
parent ceb7c6765e
commit 0d7c7510d7
17 changed files with 843 additions and 502 deletions
+55 -5
View File
@@ -1919,7 +1919,32 @@ void TileConvertTiledToLinearStandard256B(void* dst, const void* src, uint32_t f
}
}
// Prospero depth-tile address table for 2D, 1xAA surfaces by element size.
// Prospero depth/stencil-tile address table for 2D, 1xAA surfaces by element size.
static constexpr uint32_t Depth64KB8XOffsetBytes(uint32_t x) {
uint32_t offset = 0;
offset ^= x & 0x0001u;
offset ^= (x << 1u) & 0x0004u;
offset ^= (x << 2u) & 0x0010u;
offset ^= (x << 3u) & 0x0040u;
offset ^= (x << 5u) & 0x0300u;
offset ^= (x << 4u) & 0x0400u;
offset ^= (x << 6u) & 0x0800u;
offset ^= (x << 7u) & 0x2000u;
offset ^= (x << 8u) & 0x8000u;
return offset;
}
static constexpr uint32_t Depth64KB8YOffsetBytes(uint32_t y) {
uint32_t offset = 0;
offset ^= (y << 1u) & 0x0002u;
offset ^= (y << 2u) & 0x0008u;
offset ^= (y << 3u) & 0x00a0u;
offset ^= (y << 5u) & 0x0f00u;
offset ^= (y << 6u) & 0x1000u;
offset ^= (y << 7u) & 0x4000u;
return offset;
}
static constexpr uint32_t Depth64KB16XOffsetBytes(uint32_t x) {
uint32_t offset = 0;
offset ^= (x << 1u) & 0x0002u;
@@ -1964,6 +1989,9 @@ static constexpr uint32_t Depth64KB32YOffsetBytes(uint32_t y) {
return offset;
}
static_assert(Depth64KB8XOffsetBytes(2) == 0x0004u);
static_assert(Depth64KB8YOffsetBytes(1) == 0x0002u);
static_assert((Depth64KB8XOffsetBytes(3) ^ Depth64KB8YOffsetBytes(5)) == 0x0027u);
static_assert(Depth64KB16XOffsetBytes(2) == 0x0008u);
static_assert(Depth64KB16YOffsetBytes(1) == 0x0004u);
static_assert((Depth64KB16XOffsetBytes(3) ^ Depth64KB16YOffsetBytes(5)) == 0x004eu);
@@ -1971,6 +1999,20 @@ static_assert(Depth64KB32XOffsetBytes(2) == 0x0010u);
static_assert(Depth64KB32YOffsetBytes(1) == 0x0008u);
static_assert((Depth64KB32XOffsetBytes(3) ^ Depth64KB32YOffsetBytes(5)) == 0x009cu);
struct Depth64KB8Tables {
std::array<uint32_t, 256> x_words {};
std::array<uint32_t, 256> y_words {};
constexpr Depth64KB8Tables() {
for (uint32_t x = 0; x < x_words.size(); x++) {
x_words[x] = Depth64KB8XOffsetBytes(x);
}
for (uint32_t y = 0; y < y_words.size(); y++) {
y_words[y] = Depth64KB8YOffsetBytes(y);
}
}
};
struct Depth64KB16Tables {
std::array<uint32_t, 256> x_words {};
std::array<uint32_t, 128> y_words {};
@@ -2089,15 +2131,19 @@ static void TileConvertDepth(void* dst, const void* src, uint32_t format, uint32
uint32_t height, uint32_t pitch, uint64_t size) {
KYTY_PROFILER_FUNCTION();
const uint32_t bytes_per_element = Prospero::NumBytesPerElement(format);
const uint32_t block_width = bytes_per_element == 2 ? 256u : 128u;
const bool supported_bpe =
bytes_per_element == 1 || bytes_per_element == 2 || bytes_per_element == 4;
const uint32_t block_width = supported_bpe && bytes_per_element <= 2 ? 256u : 128u;
const uint32_t block_height = supported_bpe ? 65536u / (block_width * bytes_per_element) : 0;
if (dst == nullptr || src == nullptr || width == 0 || height == 0 || pitch < width ||
(bytes_per_element != 2 && bytes_per_element != 4) || pitch % block_width != 0 ||
!supported_bpe || pitch % block_width != 0 ||
size == 0 || size % 65536u != 0) {
EXIT("unsupported depth conversion, dst=%p src=%p format=%u "
"extent=%ux%u pitch=%u size=0x%016" PRIx64 "\n",
dst, src, format, width, height, pitch, size);
}
const uint64_t block_rows = (static_cast<uint64_t>(height) + 127u) / 128u;
const uint64_t block_rows =
(static_cast<uint64_t>(height) + block_height - 1u) / block_height;
const uint64_t blocks_per_row = pitch / block_width;
if (blocks_per_row > UINT64_MAX / block_rows ||
blocks_per_row * block_rows > UINT64_MAX / 65536u ||
@@ -2106,7 +2152,11 @@ static void TileConvertDepth(void* dst, const void* src, uint32_t format, uint32
"extent=%ux%u pitch=%u bpe=%u size=0x%016" PRIx64 "\n",
width, height, pitch, bytes_per_element, size);
}
if (bytes_per_element == 2) {
if (bytes_per_element == 1) {
static constexpr Depth64KB8Tables tables;
TileConvertDepthTyped<tiled_to_linear, uint8_t>(dst, src, width, height, pitch, size,
tables.x_words, tables.y_words);
} else if (bytes_per_element == 2) {
static constexpr Depth64KB16Tables tables;
TileConvertDepthTyped<tiled_to_linear, uint16_t>(dst, src, width, height, pitch, size,
tables.x_words, tables.y_words);