From 27de42f8df0225ecb841bfd8f76cb7e862af01e0 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sun, 9 Oct 2022 16:35:35 +0100 Subject: [PATCH] Use surfaceClip as a hint for the underlying rendertarget size TIC sizes may not be aligned to block linear dimensions whereas RT sizes are and then limited by the surface clip. By using this to determine surface size we are more likely to get a match in texture manager for any future usages. --- .../maxwell_3d/pipeline_state.cpp | 38 +++++++++++++++---- .../interconnect/maxwell_3d/pipeline_state.h | 2 + 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp index 4df38e1e..962115d2 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp @@ -13,9 +13,23 @@ #include "pipeline_state.h" namespace skyline::gpu::interconnect::maxwell3d { + static void DetermineRenderTargetDimensions(GuestTexture &guest, const engine::SurfaceClip &clip) { + // RT dimensions always include block linear alignment and contain the unaligned dimensions in surface clip, we ideally want to create the texture using the unaligned dimensions since the texture manager doesn't support resolving such overlaps yet. By checking that the layer size calculated is equal to the RT size we can eliminate most cases where the clip is used not just for aligmnent + u32 underlyingRtLayerSize{guest.CalculateLayerSize()}; + texture::Dimensions underlyingRtDimensions{guest.dimensions}; + guest.dimensions = texture::Dimensions{static_cast(clip.horizontal.width + clip.horizontal.x), + static_cast(clip.vertical.height + clip.vertical.y), + guest.dimensions.depth}; + u32 clippedRtLayerSize{guest.CalculateLayerSize()}; + + // If the calculated sizes don't match then always use the RT dimensions + if (clippedRtLayerSize != underlyingRtLayerSize) + guest.dimensions = underlyingRtDimensions; + } + /* Colour Render Target */ void ColorRenderTargetState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const { - manager.Bind(handle, colorTarget); + manager.Bind(handle, colorTarget, surfaceClip); } ColorRenderTargetState::ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, size_t index) : engine{manager, dirtyHandle, engine}, index{index} {} @@ -145,15 +159,19 @@ namespace skyline::gpu::interconnect::maxwell3d { auto mappings{ctx.channelCtx.asCtx->gmmu.TranslateRange(target.offset, guest.GetSize())}; guest.mappings.assign(mappings.begin(), mappings.end()); - if (guest.MappingsValid()) - view = ctx.executor.AcquireTextureManager().FindOrCreate(guest, ctx.executor.tag); - else + if (guest.MappingsValid()) { + if (guest.tileConfig.mode == gpu::texture::TileMode::Block) + DetermineRenderTargetDimensions(guest, engine->surfaceClip); + + view = ctx.gpu.texture.FindOrCreate(guest, ctx.executor.tag); + } else { view = {}; + } } /* Depth Render Target */ void DepthRenderTargetState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const { - manager.Bind(handle, ztSize, ztOffset, ztFormat, ztBlockSize, ztArrayPitch, ztSelect, ztLayer); + manager.Bind(handle, ztSize, ztOffset, ztFormat, ztBlockSize, ztArrayPitch, ztSelect, ztLayer, surfaceClip); } DepthRenderTargetState::DepthRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {} @@ -212,10 +230,14 @@ namespace skyline::gpu::interconnect::maxwell3d { auto mappings{ctx.channelCtx.asCtx->gmmu.TranslateRange(engine->ztOffset, guest.GetSize())}; guest.mappings.assign(mappings.begin(), mappings.end()); - if (guest.MappingsValid()) - view = ctx.executor.AcquireTextureManager().FindOrCreate(guest, ctx.executor.tag); - else + if (guest.MappingsValid()) { + if (guest.tileConfig.mode == gpu::texture::TileMode::Block) + DetermineRenderTargetDimensions(guest, engine->surfaceClip); + + view = ctx.gpu.texture.FindOrCreate(guest, ctx.executor.tag); + } else { view = {}; + } } /* Pipeline Stages */ diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h index d239f8d9..0b0f1c15 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_state.h @@ -14,6 +14,7 @@ namespace skyline::gpu::interconnect::maxwell3d { public: struct EngineRegisters { const engine::ColorTarget &colorTarget; + const engine::SurfaceClip &surfaceClip; void DirtyBind(DirtyManager &manager, dirty::Handle handle) const; }; @@ -40,6 +41,7 @@ namespace skyline::gpu::interconnect::maxwell3d { const u32 &ztArrayPitch; const engine::ZtSelect &ztSelect; const engine::ZtLayer &ztLayer; + const engine::SurfaceClip &surfaceClip; void DirtyBind(DirtyManager &manager, dirty::Handle handle) const; };