From 2a99e1784df278ee79bc0db4bca5a76a7c9b7327 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Thu, 12 May 2022 18:19:36 +0530 Subject: [PATCH] Fix Maxwell3D RT Depth/Layer Count Logic The Maxwell3D RT layer count wasn't being set correctly as it has the same register as the depth values and is toggled between the two based on another register value. --- .../gpu/interconnect/graphics_context.h | 25 +++++++++++++------ .../skyline/soc/gm20b/engines/maxwell/types.h | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index 9548356b..6f8da3ba 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -111,10 +111,11 @@ namespace skyline::gpu::interconnect { private: struct RenderTarget { bool disabled{true}; //!< If this RT has been disabled and will be an unbound attachment instead - IOVA iova; - u32 widthBytes; //!< The width in bytes for linear textures - GuestTexture guest; - std::shared_ptr view; + IOVA iova{}; + u32 widthBytes{}; //!< The width in bytes for linear textures + bool is3d{}; //!< If the RT is 3D, this controls if the RT is 3D or layered + GuestTexture guest{}; + std::shared_ptr view{}; RenderTarget() { guest.dimensions = texture::Dimensions(1, 1, 1); @@ -332,6 +333,12 @@ namespace skyline::gpu::interconnect { .blockDepth = static_cast(1U << mode.blockDepthLog2), }; } + + if (renderTarget.is3d != mode.is3d) { + std::swap(renderTarget.guest.dimensions.depth, renderTarget.guest.layerCount); + renderTarget.is3d = mode.is3d; + } + renderTarget.view.reset(); } @@ -344,14 +351,18 @@ namespace skyline::gpu::interconnect { } void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) { - renderTarget.guest.dimensions.depth = mode.layerCount; + if (renderTarget.is3d) + renderTarget.guest.dimensions.depth = mode.depthOrlayerCount; + else + renderTarget.guest.layerCount = mode.depthOrlayerCount; renderTarget.view.reset(); } void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) { + auto &renderTarget{colorRenderTargets.at(index)}; if (mode.volume) - throw exception("Color RT Array Volumes are not supported (with layer count = {})", mode.layerCount); - SetRenderTargetArrayMode(colorRenderTargets.at(index), mode); + throw exception("Color RT Array Volumes are not supported (with {} = {})", renderTarget.is3d ? "depth" : "layer count", mode.depthOrlayerCount); + SetRenderTargetArrayMode(renderTarget, mode); } void SetDepthRenderTargetArrayMode(maxwell3d::RenderTargetArrayMode mode) { diff --git a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h index 9f48edc5..ed91a7c2 100644 --- a/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h +++ b/app/src/main/cpp/skyline/soc/gm20b/engines/maxwell/types.h @@ -69,7 +69,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type { }; struct RenderTargetArrayMode { - u16 layerCount; + u16 depthOrlayerCount; //!< The 3D depth or layer count of the render target depending on if it's 3D or not bool volume : 1; u16 _pad_ : 15; };