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.
This commit is contained in:
PixelyIon 2022-05-12 18:19:36 +05:30
parent 543ac3042e
commit 2a99e1784d
2 changed files with 19 additions and 8 deletions

View File

@ -111,10 +111,11 @@ namespace skyline::gpu::interconnect {
private: private:
struct RenderTarget { struct RenderTarget {
bool disabled{true}; //!< If this RT has been disabled and will be an unbound attachment instead bool disabled{true}; //!< If this RT has been disabled and will be an unbound attachment instead
IOVA iova; IOVA iova{};
u32 widthBytes; //!< The width in bytes for linear textures u32 widthBytes{}; //!< The width in bytes for linear textures
GuestTexture guest; bool is3d{}; //!< If the RT is 3D, this controls if the RT is 3D or layered
std::shared_ptr<TextureView> view; GuestTexture guest{};
std::shared_ptr<TextureView> view{};
RenderTarget() { RenderTarget() {
guest.dimensions = texture::Dimensions(1, 1, 1); guest.dimensions = texture::Dimensions(1, 1, 1);
@ -332,6 +333,12 @@ namespace skyline::gpu::interconnect {
.blockDepth = static_cast<u8>(1U << mode.blockDepthLog2), .blockDepth = static_cast<u8>(1U << mode.blockDepthLog2),
}; };
} }
if (renderTarget.is3d != mode.is3d) {
std::swap(renderTarget.guest.dimensions.depth, renderTarget.guest.layerCount);
renderTarget.is3d = mode.is3d;
}
renderTarget.view.reset(); renderTarget.view.reset();
} }
@ -344,14 +351,18 @@ namespace skyline::gpu::interconnect {
} }
void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) { 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(); renderTarget.view.reset();
} }
void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) { void SetColorRenderTargetArrayMode(size_t index, maxwell3d::RenderTargetArrayMode mode) {
auto &renderTarget{colorRenderTargets.at(index)};
if (mode.volume) if (mode.volume)
throw exception("Color RT Array Volumes are not supported (with layer count = {})", mode.layerCount); throw exception("Color RT Array Volumes are not supported (with {} = {})", renderTarget.is3d ? "depth" : "layer count", mode.depthOrlayerCount);
SetRenderTargetArrayMode(colorRenderTargets.at(index), mode); SetRenderTargetArrayMode(renderTarget, mode);
} }
void SetDepthRenderTargetArrayMode(maxwell3d::RenderTargetArrayMode mode) { void SetDepthRenderTargetArrayMode(maxwell3d::RenderTargetArrayMode mode) {

View File

@ -69,7 +69,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d::type {
}; };
struct RenderTargetArrayMode { 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; bool volume : 1;
u16 _pad_ : 15; u16 _pad_ : 15;
}; };