diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/ColorTargetLayout.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/ColorTargetLayout.cpp index e9c5fe3bc3..7c27f92c6e 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/ColorTargetLayout.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/ColorTargetLayout.cpp @@ -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"); diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp index 843d9de329..6f1f3e14d6 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp @@ -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; diff --git a/core/libs/prx/libSceAgcDriver/tests/ColorTargetLayout.cpp b/core/libs/prx/libSceAgcDriver/tests/ColorTargetLayout.cpp index 5d02bebda1..636bc574fd 100644 --- a/core/libs/prx/libSceAgcDriver/tests/ColorTargetLayout.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/ColorTargetLayout.cpp @@ -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); }); diff --git a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp index c908a3a41d..ad7975db7a 100644 --- a/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/Graphics.cpp @@ -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);