Skip to content

Commit

Permalink
GS:MTL: Properly handle hdr rendering to cleared textures
Browse files Browse the repository at this point in the history
  • Loading branch information
TellowKrinkle authored and stenzek committed Jan 12, 2024
1 parent 6f2be7b commit 40ead58
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pcsx2/GS/Renderers/Metal/GSDeviceMTL.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ class GSDeviceMTL final : public GSDevice
MRCOwned<id<MTLRenderPipelineState>> m_stencil_clear_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_primid_init_pipeline[2][2];
MRCOwned<id<MTLRenderPipelineState>> m_hdr_init_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_hdr_clear_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_hdr_resolve_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_fxaa_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_shadeboost_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_imgui_pipeline;
MRCOwned<id<MTLRenderPipelineState>> m_imgui_pipeline_a8;

MRCOwned<id<MTLFunction>> m_hw_vs[1 << 5];
std::unordered_map<PSSelector, MRCOwned<id<MTLFunction>>> m_hw_ps;
Expand Down
27 changes: 22 additions & 5 deletions pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,7 @@ static void OnMainThread(Fn&& fn)
m_clut_pipeline[1] = MakePipeline(pdesc, fs_triangle, LoadShader(@"ps_convert_clut_8"), @"8-bit CLUT Update");
pdesc.colorAttachments[0].pixelFormat = ConvertPixelFormat(GSTexture::Format::HDRColor);
m_hdr_init_pipeline = MakePipeline(pdesc, fs_triangle, LoadShader(@"ps_hdr_init"), @"HDR Init");
m_hdr_clear_pipeline = MakePipeline(pdesc, fs_triangle, LoadShader(@"ps_clear"), @"HDR Clear");
pdesc.colorAttachments[0].pixelFormat = MTLPixelFormatInvalid;
pdesc.stencilAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8;
m_datm_pipeline[0] = MakePipeline(pdesc, fs_triangle, LoadShader(@"ps_datm0"), @"datm0");
Expand Down Expand Up @@ -2139,11 +2140,27 @@ static bool usesStencil(GSHWDrawConfig::DestinationAlphaMode dstalpha)
if (config.ps.hdr)
{
GSVector2i size = config.rt->GetSize();
hdr_rt = CreateRenderTarget(size.x, size.y, GSTexture::Format::HDRColor);
BeginRenderPass(@"HDR Init", hdr_rt, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare);
RenderCopy(config.rt, m_hdr_init_pipeline, config.drawarea);
rt = hdr_rt;
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
rt = hdr_rt = CreateRenderTarget(size.x, size.y, GSTexture::Format::HDRColor, false);
switch (config.rt->GetState())
{
case GSTexture::State::Dirty:
BeginRenderPass(@"HDR Init", hdr_rt, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare);
RenderCopy(config.rt, m_hdr_init_pipeline, config.drawarea);
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
break;

case GSTexture::State::Cleared:
{
BeginRenderPass(@"HDR Clear", hdr_rt, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare);
GSVector4 color = GSVector4::rgba32(config.rt->GetClearColor()) / GSVector4::cxpr(65535, 65535, 65535, 255);
[m_current_render.encoder setFragmentBytes:&color length:sizeof(color) atIndex:GSMTLBufferIndexUniforms];
RenderCopy(nullptr, m_hdr_clear_pipeline, config.drawarea);
break;
}

case GSTexture::State::Invalidated:
break;
}
}

// Try to reduce render pass restarts
Expand Down
5 changes: 5 additions & 0 deletions pcsx2/GS/Renderers/Metal/convert.metal
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ fragment float4 ps_copy_fs(float4 p [[position]], DirectReadTextureIn<float> tex
return tex.read(p);
}

fragment float4 ps_clear(float4 p [[position]], constant float4& color [[buffer(GSMTLBufferIndexUniforms)]])
{
return color;
}

fragment void ps_datm1(float4 p [[position]], DirectReadTextureIn<float> tex)
{
if (tex.read(p).a < (127.5f / 255.f))
Expand Down

0 comments on commit 40ead58

Please sign in to comment.