GS:MTL: Implement InvalidateRenderTarget

This commit is contained in:
TellowKrinkle 2023-05-14 15:47:30 -05:00 committed by lightningterror
parent fd11523cf4
commit 7c97cf4799
3 changed files with 25 additions and 4 deletions

View File

@ -399,9 +399,13 @@ void GSDeviceMTL::BeginRenderPass(NSString* name, GSTexture* color, MTLLoadActio
bool needs_color_clear = false; bool needs_color_clear = false;
bool needs_depth_clear = false; bool needs_depth_clear = false;
bool needs_stencil_clear = false; bool needs_stencil_clear = false;
if (mc) needs_color_clear = mc->GetResetNeedsColorClear(color_clear); // Depth and stencil might be the same, so do all invalidation checks before resetting invalidation
if (md) needs_depth_clear = md->GetResetNeedsDepthClear(depth_clear); if (mc && mc->IsInvalidated()) color_load = MTLLoadActionDontCare;
if (ms) needs_stencil_clear = ms->GetResetNeedsStencilClear(stencil_clear); if (md && md->IsInvalidated()) depth_load = MTLLoadActionDontCare;
if (ms && ms->IsInvalidated()) stencil_load = MTLLoadActionDontCare;
if (mc) { mc->ResetInvalidation(); needs_color_clear = mc->GetResetNeedsColorClear(color_clear); }
if (md) { md->ResetInvalidation(); needs_depth_clear = md->GetResetNeedsDepthClear(depth_clear); }
if (ms) { ms->ResetInvalidation(); needs_stencil_clear = ms->GetResetNeedsStencilClear(stencil_clear); }
if (needs_color_clear && color_load != MTLLoadActionDontCare) color_load = MTLLoadActionClear; if (needs_color_clear && color_load != MTLLoadActionDontCare) color_load = MTLLoadActionClear;
if (needs_depth_clear && depth_load != MTLLoadActionDontCare) depth_load = MTLLoadActionClear; if (needs_depth_clear && depth_load != MTLLoadActionDontCare) depth_load = MTLLoadActionClear;
if (needs_stencil_clear && stencil_load != MTLLoadActionDontCare) stencil_load = MTLLoadActionClear; if (needs_stencil_clear && stencil_load != MTLLoadActionDontCare) stencil_load = MTLLoadActionClear;
@ -1446,7 +1450,8 @@ void GSDeviceMTL::ClearStencil(GSTexture* t, uint8 c)
void GSDeviceMTL::InvalidateRenderTarget(GSTexture* t) void GSDeviceMTL::InvalidateRenderTarget(GSTexture* t)
{ {
// TODO: Implement me if (!t) return;
static_cast<GSTextureMTL*>(t)->Invalidate();
} }
std::unique_ptr<GSDownloadTexture> GSDeviceMTL::CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format) std::unique_ptr<GSDownloadTexture> GSDeviceMTL::CreateDownloadTexture(u32 width, u32 height, GSTexture::Format format)

View File

@ -38,6 +38,7 @@ class GSTextureMTL : public GSTexture
bool m_needs_color_clear = false; bool m_needs_color_clear = false;
bool m_needs_depth_clear = false; bool m_needs_depth_clear = false;
bool m_needs_stencil_clear = false; bool m_needs_stencil_clear = false;
bool m_invalidated = false;
GSVector4 m_clear_color; GSVector4 m_clear_color;
float m_clear_depth; float m_clear_depth;
int m_clear_stencil; int m_clear_stencil;
@ -67,6 +68,12 @@ public:
void FlushClears(); void FlushClears();
/// Marks pending clears as done (e.g. if the whole texture is about to be overwritten) /// Marks pending clears as done (e.g. if the whole texture is about to be overwritten)
void InvalidateClears(); void InvalidateClears();
/// Marks the texture as invalid (will load with DontCare)
void Invalidate();
/// Reads whether the texture has been invalidated, then clears the invalidation
bool IsInvalidated() const { return m_invalidated; };
/// Clears any invalidation requests
void ResetInvalidation() { m_invalidated = false; }
void* GetNativeHandle() const override; void* GetNativeHandle() const override;
bool Update(const GSVector4i& r, const void* data, int pitch, int layer = 0) override; bool Update(const GSVector4i& r, const void* data, int pitch, int layer = 0) override;

View File

@ -42,16 +42,19 @@ GSTextureMTL::~GSTextureMTL()
void GSTextureMTL::RequestColorClear(GSVector4 color) void GSTextureMTL::RequestColorClear(GSVector4 color)
{ {
m_needs_color_clear = true; m_needs_color_clear = true;
m_invalidated = false;
m_clear_color = color; m_clear_color = color;
} }
void GSTextureMTL::RequestDepthClear(float depth) void GSTextureMTL::RequestDepthClear(float depth)
{ {
m_needs_depth_clear = true; m_needs_depth_clear = true;
m_invalidated = false;
m_clear_depth = depth; m_clear_depth = depth;
} }
void GSTextureMTL::RequestStencilClear(int stencil) void GSTextureMTL::RequestStencilClear(int stencil)
{ {
m_needs_stencil_clear = true; m_needs_stencil_clear = true;
m_invalidated = false;
m_clear_stencil = stencil; m_clear_stencil = stencil;
} }
bool GSTextureMTL::GetResetNeedsColorClear(GSVector4& colorOut) bool GSTextureMTL::GetResetNeedsColorClear(GSVector4& colorOut)
@ -108,6 +111,12 @@ void GSTextureMTL::InvalidateClears()
m_needs_stencil_clear = false; m_needs_stencil_clear = false;
} }
void GSTextureMTL::Invalidate()
{
InvalidateClears();
m_invalidated = true;
}
bool GSTextureMTL::Update(const GSVector4i& r, const void* data, int pitch, int layer) bool GSTextureMTL::Update(const GSVector4i& r, const void* data, int pitch, int layer)
{ {
if (void* buffer = MapWithPitch(r, pitch, layer)) if (void* buffer = MapWithPitch(r, pitch, layer))