fix(agc): render into one slice of a 2D array color target

DecodeColorTileMode rejected 2D color targets with a nonzero MIP0_DEPTH, so
an array target could only be rendered into through a view of a surface that
declares one slice. radeonsi sets CB_COLOR_ATTRIB3.MIP0_DEPTH to the last layer
of an array target (si_state.c, ac_descriptors.c), and Mesa-built homebrew
emits such targets. The view's slice already moves the target by one slice
size; it is now also checked against MIP0_DEPTH.
This commit is contained in:
AlxcBTW authored and Dean Galvin committed 2026-10-10 21:20:29 +13:00
1 parent f6af6d11d3
commit ce8bee6980
4 files changed
+9 -2

No files matched your search

@@ -43,7 +43,7 @@ std::uint32_t standard64Extra(std::uint32_t x, std::uint32_t y, std::uint32_t el
ColorTileMode DecodeColorTileMode(std::uint32_t attrib3) {
const auto resourceType = (attrib3 >> 24u) & 3u;
require((attrib3 & 0x80002000u) == 0 && ((resourceType <= 1 && (attrib3 & 0x1fffu) == 0) || resourceType == 2) && ((attrib3 >> 27u) & 7u) == 1, "AGC graphics: unsupported color depth, dimension, resource level or metadata mode");
require((attrib3 & 0x80002000u) == 0 && ((resourceType == 0 && (attrib3 & 0x1fffu) == 0) || resourceType == 1 || resourceType == 2) && ((attrib3 >> 27u) & 7u) == 1, "AGC graphics: unsupported color depth, dimension, resource level or metadata mode");
const auto mode = (attrib3 >> 14u) & 0x1fu;
const auto fmaskMode = (attrib3 >> 19u) & 0x1fu;
require(fmaskMode == 0 || fmaskMode == 0x18, "AGC graphics: unsupported color FMASK swizzle mode");
@@ -815,6 +815,8 @@ ColorTarget DecodeColorBuffer(const Registers& cx, std::uint32_t slot) {
Require(maxMip == 0 && (info & 0x10000000u) == 0, "mipmapped or DCC 3D color targets are unsupported");
Require(slice < color.depth, "the color view slice is beyond the 3D surface");
color.depthSlice = slice;
} else if ((attrib3 & 0x1fffu) != 0) {
Require(slice <= (attrib3 & 0x1fffu), "the color view slice is beyond the array surface");
}
color.extent = {((attrib2 >> 14u) & 0x3fffu) + 1u, (attrib2 & 0x3fffu) + 1u};
color.elementBytes = decoded.elementBytes;
@@ -25,7 +25,7 @@ void reject(TAction action) {
void RunColorTargetLayoutTests() {
Require(DecodeColorTileMode(0x4dc6c000) == ColorTileMode::RenderTarget, "logged color descriptor was rejected");
Require(DecodeColorTileMode(0x09000000) == ColorTileMode::Linear, "linear descriptor changed");
reject([] { DecodeColorTileMode(0x4dc6c001); });
Require(DecodeColorTileMode(0x4dc6c001) == ColorTileMode::RenderTarget, "2D array color descriptor with MIP0_DEPTH 1 was rejected");
reject([] { DecodeColorTileMode(0x4dc6e000); });
reject([] { DecodeColorTileMode(0xcdc6c000); });
reject([] { DecodeColorTileMode(0x09004000); });
@@ -916,6 +916,11 @@ void DepthStencilTests() {
queue.context[0x31b] = 1u | (1u << 13u);
const auto slice = AgcDriver::Graphics::DecodeState(queue);
Require(slice.color.address == sliced + 1024u && slice.color.bytes == 1024u, "a color view of one slice did not move the target by one slice");
queue.context[0x3b8] = 0x09000001;
const auto arraySlice = AgcDriver::Graphics::DecodeState(queue);
Require(arraySlice.color.address == sliced + 1024u && arraySlice.color.bytes == 1024u && arraySlice.color.depth == 1u, "a color view of one slice of a 2D array target did not move the target by one slice");
queue.context[0x31b] = 2u | (2u << 13u);
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "beyond the array surface");
queue.context[0x3b8] = 0x0a000003;
queue.context[0x31b] = 2u | (2u << 13u);
const auto volume = AgcDriver::Graphics::DecodeState(queue);