Skip to content

Commit f542bbe

Browse files
TJnotJTTellowKrinkle
authored andcommitted
GS:MTL: Port oneshot ROV to Metal.
1 parent ed91b50 commit f542bbe

4 files changed

Lines changed: 186 additions & 19 deletions

File tree

pcsx2/GS/Renderers/Metal/GSDeviceMTL.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ class GSDeviceMTL final : public GSDevice
250250
// Functions and Pipeline States
251251
MRCOwned<id<MTLComputePipelineState>> m_cas_pipeline[2];
252252
std::vector<MRCOwned<id<MTLRenderPipelineState>>> m_convert_pipeline;
253+
MRCOwned<id<MTLRenderPipelineState>> m_rov_copy_one_pipeline[2]; // [color]
254+
MRCOwned<id<MTLRenderPipelineState>> m_rov_copy_both_pipeline;
253255
MRCOwned<id<MTLRenderPipelineState>> m_present_pipeline[static_cast<int>(PresentShader::Count)];
254256
MRCOwned<id<MTLRenderPipelineState>> m_merge_pipeline[4];
255257
MRCOwned<id<MTLRenderPipelineState>> m_interlace_pipeline[NUM_INTERLACE_SHADERS];
@@ -335,6 +337,8 @@ class GSDeviceMTL final : public GSDevice
335337
GSTexture* m_ds_as_rt_gstexture = nullptr;
336338
MRCOwned<id<MTLTexture>> m_rov_dummy_texture;
337339
struct { u32 w, h; } m_rov_dummy_texture_size = {};
340+
std::unique_ptr<GSTextureMTL> m_rov_rt;
341+
std::unique_ptr<GSTextureMTL> m_rov_ds;
338342

339343
struct DebugEntry
340344
{
@@ -383,6 +387,8 @@ class GSDeviceMTL final : public GSDevice
383387
void BeginRenderPass(NSString* name, GSTexture* color, MTLLoadAction color_load, GSTexture* depth, MTLLoadAction depth_load, GSTexture* stencil = nullptr, MTLLoadAction stencil_load = MTLLoadActionDontCare, bool rt1 = false);
384388
/// Begin a new full-ROV render pass (may reuse existing)
385389
void BeginFullROV(NSString* name, uint32_t width, uint32_t height);
390+
/// Begin a render pass for combined color+depth ROV copy
391+
void BeginROVCopy(GSTexture* color, GSTexture* depth);
386392
/// Call at the end of each frame
387393
void FrameCompleted();
388394

@@ -464,6 +470,7 @@ class GSDeviceMTL final : public GSDevice
464470

465471
// MARK: Render HW
466472

473+
void SetupOneshotROV(const GSHWDrawConfig& config, GSTextureMTL* rt, GSTextureMTL* ds, const std::vector<GSVector4i>& rects, const GSVector2i& size);
467474
void SetupDestinationAlpha(GSTexture* rt, GSTexture* ds, const GSVector4i& r, SetDATM datm);
468475
void PrepareROVTexture(GSTexture** ptex);
469476
void RenderHW(GSHWDrawConfig& config) override;

pcsx2/GS/Renderers/Metal/GSDeviceMTL.mm

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,8 @@ static GSVector4 GetRTLoadInfo(GSTextureMTL* tex, MTLLoadAction* load_action)
505505
color1.texture = GetRT1DepthTexture(md);
506506
if (m_features.framebuffer_fetch)
507507
color1.clearColor = MTLClearColorMake(depth_load == MTLLoadActionClear ? depth_clear.x : -1, 0, 0, 0);
508+
else
509+
color1.loadAction = MTLLoadActionLoad;
508510
}
509511

510512
PrepareBeginRenderPass();
@@ -576,6 +578,25 @@ static GSVector4 GetRTLoadInfo(GSTextureMTL* tex, MTLLoadAction* load_action)
576578
beforeStages:MTLRenderStageVertex];
577579
}
578580

581+
void GSDeviceMTL::BeginROVCopy(GSTexture* color, GSTexture* depth)
582+
{
583+
pxAssert(!m_features.framebuffer_fetch);
584+
MTLRenderPassDescriptor* desc = m_render_pass_desc[1 | 8];
585+
MTLRenderPassColorAttachmentDescriptor* color0 = desc.colorAttachments[0];
586+
color0.loadAction = MTLLoadActionDontCare;
587+
color0.texture = static_cast<GSTextureMTL*>(color)->GetTexture();
588+
MTLRenderPassColorAttachmentDescriptor* color1 = desc.colorAttachments[1];
589+
color1.loadAction = MTLLoadActionDontCare;
590+
color1.storeAction = MTLStoreActionStore;
591+
color1.texture = static_cast<GSTextureMTL*>(depth)->GetTexture();
592+
PrepareBeginRenderPass();
593+
m_current_render.encoder = MRCRetain([GetRenderCmdBuf() renderCommandEncoderWithDescriptor:desc]);
594+
[m_current_render.encoder setLabel:@"ROV Clear"];
595+
if (!m_dev.features.unified_memory)
596+
[m_current_render.encoder waitForFence:m_draw_sync_fence
597+
beforeStages:MTLRenderStageVertex];
598+
}
599+
579600
void GSDeviceMTL::FrameCompleted()
580601
{
581602
if (m_spin_timer)
@@ -1125,11 +1146,11 @@ static bool ConvertShaderNotNeeded(ShaderConvert shader)
11251146
auto desc = MRCTransfer([MTLRenderPassDescriptor new]);
11261147
[[desc depthAttachment] setStoreAction:MTLStoreActionStore];
11271148
[[desc stencilAttachment] setStoreAction:MTLStoreActionStore];
1128-
if (rt1)
1149+
if (rt1 && m_features.framebuffer_fetch)
11291150
{
11301151
MTLRenderPassColorAttachmentDescriptor* color1 = [[desc colorAttachments] objectAtIndexedSubscript:1];
11311152
[color1 setStoreAction:MTLStoreActionDontCare];
1132-
[color1 setLoadAction:m_features.framebuffer_fetch ? MTLLoadActionClear : MTLLoadActionLoad];
1153+
[color1 setLoadAction:MTLLoadActionClear];
11331154
}
11341155
m_render_pass_desc[i] = desc;
11351156
}
@@ -1304,8 +1325,22 @@ static bool ConvertShaderNotNeeded(ShaderConvert shader)
13041325
setFnConstantB(m_fn_constants, shader.DepthOutput(), GSMTLConstantIndex_DEPTH_OUT);
13051326
m_convert_pipeline[shader.Index()] = MakePipeline(pdesc, vs_convert, LoadShader(shader_name), name);
13061327
}
1328+
13071329
pdesc.colorAttachments[0].writeMask = MTLColorWriteMaskAll;
13081330
pdesc.depthAttachmentPixelFormat = MTLPixelFormatInvalid;
1331+
pdesc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid;
1332+
1333+
if (m_features.rov)
1334+
{
1335+
pdesc.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm;
1336+
pdesc.colorAttachments[1].pixelFormat = MTLPixelFormatR32Float;
1337+
m_rov_copy_both_pipeline = MakePipeline(pdesc, vs_convert, LoadShader(@"ps_rov_copy_both"), @"ROV Copy Both");
1338+
pdesc.colorAttachments[1].pixelFormat = MTLPixelFormatInvalid;
1339+
m_rov_copy_one_pipeline[1] = MakePipeline(pdesc, vs_convert, LoadShader(@"ps_rov_copy_color"), @"ROV Copy Color");
1340+
pdesc.colorAttachments[0].pixelFormat = MTLPixelFormatR32Float;
1341+
m_rov_copy_one_pipeline[0] = MakePipeline(pdesc, vs_convert, LoadShader(@"ps_rov_copy_depth"), @"ROV Copy Depth");
1342+
}
1343+
13091344
for (size_t i = 0; i < std::size(m_present_pipeline); i++)
13101345
{
13111346
PresentShader conv = static_cast<PresentShader>(i);
@@ -1845,6 +1880,101 @@ static bool ConvertShaderNotNeeded(ShaderConvert shader)
18451880
flush(num_rects);
18461881
}}
18471882

1883+
void GSDeviceMTL::SetupOneshotROV(const GSHWDrawConfig& config, GSTextureMTL* rt, GSTextureMTL* ds, const std::vector<GSVector4i>& rects, const GSVector2i& size_i)
1884+
{
1885+
g_perfmon.Put(GSPerfMon::TextureCopies, 1);
1886+
g_perfmon.Put(GSPerfMon::TextureCopiesROV, 1);
1887+
g_perfmon.Put(GSPerfMon::DrawCallsROV, 1);
1888+
1889+
bool rt_copy = config.ps.HasOneshotColorROV();
1890+
bool ds_copy = config.ps.HasOneshotDepthROV();
1891+
1892+
// Create ROV textures
1893+
if (rt_copy && (!m_rov_rt || m_rov_rt->GetSize() != size_i))
1894+
{
1895+
if (m_rov_rt)
1896+
Recycle(m_rov_rt.release());
1897+
m_rov_rt.reset(static_cast<GSTextureMTL*>(CreateShaderWriteTarget(size_i, GSTexture::Format::Color, false)));
1898+
#if PCSX2_DEVBUILD
1899+
m_rov_rt->SetDebugName(fmt::format("RT for oneshot ROV {}x{}", size_i.x, size_i.y));
1900+
#endif
1901+
}
1902+
if (ds_copy && (!m_rov_ds || m_rov_ds->GetSize() != size_i))
1903+
{
1904+
if (m_rov_ds)
1905+
Recycle(m_rov_ds.release());
1906+
m_rov_ds.reset(static_cast<GSTextureMTL*>(CreateShaderWriteTarget(size_i, GSTexture::Format::DepthColor, false)));
1907+
#if PCSX2_DEVBUILD
1908+
m_rov_ds->SetDebugName(fmt::format("DS for oneshot ROV {}x{}", size_i.x, size_i.y));
1909+
#endif
1910+
}
1911+
1912+
// Avoid copies if the original is cleared.
1913+
if (rt_copy && rt->GetState() == GSTexture::State::Cleared)
1914+
{
1915+
m_rov_rt->SetClearColor(rt->GetClearColor());
1916+
m_rov_rt->FlushClears();
1917+
rt_copy = false;
1918+
}
1919+
if (ds_copy && ds->GetState() == GSTexture::State::Cleared)
1920+
{
1921+
m_rov_ds->SetClearDepth(ds->GetClearDepth());
1922+
m_rov_ds->FlushClears();
1923+
ds_copy = false;
1924+
}
1925+
1926+
if (!(rt_copy || ds_copy))
1927+
return; // Copy handled with clear.
1928+
1929+
// Vertices / IA
1930+
const u32 num_rects = static_cast<u32>(rects.size());
1931+
const Map allocation = Allocate(m_vertex_upload_buf, sizeof(ConvertShaderVertex) * 4 * num_rects);
1932+
std::array<GSVector4, 4>* write = static_cast<std::array<GSVector4, 4>*>(allocation.cpu_buffer);
1933+
const id<MTLRenderCommandEncoder> enc = m_current_render.encoder;
1934+
[enc setVertexBuffer:allocation.gpu_buffer
1935+
offset:allocation.gpu_offset
1936+
atIndex:GSMTLBufferIndexVertices];
1937+
1938+
const GSVector2 size(static_cast<float>(size_i.x), static_cast<float>(size_i.y));
1939+
for (const GSVector4i& rect_i : rects)
1940+
{
1941+
GSVector4 rect(rect_i);
1942+
*write++ = CalcStrechRectPoints(rect, rect, size);
1943+
}
1944+
1945+
// Render pass
1946+
if (rt_copy && ds_copy)
1947+
{
1948+
BeginROVCopy(m_rov_rt.get(), m_rov_ds.get());
1949+
MRESetTexture(rt, 0);
1950+
MRESetTexture(ds, 1);
1951+
MRESetPipeline(m_rov_copy_both_pipeline);
1952+
}
1953+
else
1954+
{
1955+
GSTextureMTL* src = rt_copy ? rt : ds;
1956+
GSTextureMTL* dst = rt_copy ? m_rov_rt.get() : m_rov_ds.get();
1957+
BeginRenderPass(@"ROV Copy", dst, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare, nullptr, MTLLoadActionDontCare, false);
1958+
MRESetTexture(src, GSMTLTextureIndexNonHW);
1959+
MRESetPipeline(m_rov_copy_one_pipeline[rt_copy]);
1960+
}
1961+
1962+
FlushDebugEntries(m_current_render.encoder);
1963+
MREClearScissor();
1964+
MRESetDSS(DepthStencilSelector::NoDepth());
1965+
1966+
[enc drawIndexedPrimitives:MTLPrimitiveTypeTriangle
1967+
indexCount:num_rects * 6
1968+
indexType:MTLIndexTypeUInt16
1969+
indexBuffer:m_expand_index_buffer
1970+
indexBufferOffset:0
1971+
instanceCount:1
1972+
baseVertex:0
1973+
baseInstance:0];
1974+
1975+
EndRenderPass();
1976+
}
1977+
18481978
void GSDeviceMTL::UpdateCLUTTexture(GSTexture* sTex, float sScale, u32 offsetX, u32 offsetY, GSTexture* dTex, u32 dOffset, u32 dSize)
18491979
{
18501980
GSMTLCLUTConvertPSUniform uniform = { sScale, {offsetX, offsetY}, dOffset };
@@ -2060,7 +2190,7 @@ static MTLBlendOperation ConvertBlendOp(GSDevice::BlendOp generic)
20602190
setFnConstantI(m_fn_constants, pssel.aa1, GSMTLConstantIndex_PS_AA1);
20612191
setFnConstantB(m_fn_constants, pssel.abe, GSMTLConstantIndex_PS_ABE);
20622192
setFnConstantI(m_fn_constants, pssel.sw_aniso, GSMTLConstantIndex_PS_SW_ANISO);
2063-
setFnConstantB(m_fn_constants, pssel.rov_color, GSMTLConstantIndex_PS_ROV_COLOR);
2193+
setFnConstantI(m_fn_constants, pssel.rov_color, GSMTLConstantIndex_PS_ROV_COLOR);
20642194
setFnConstantI(m_fn_constants, pssel.rov_depth, GSMTLConstantIndex_PS_ROV_DEPTH);
20652195
bool eft = pssel.HasColorROV() && !pssel.HasDepthROV() && !pssel.HasDepthOutput();
20662196
auto newps = LoadShader(eft ? @"ps_main_rov_eft" : @"ps_main");
@@ -2347,6 +2477,14 @@ static bool usesStencil(GSHWDrawConfig::DestinationAlphaMode dstalpha)
23472477

23482478
void GSDeviceMTL::RenderHW(GSHWDrawConfig& config)
23492479
{ @autoreleasepool {
2480+
if (config.ps.HasOneshotROV())
2481+
{
2482+
// Do this first since it requires a different vertex upload from the main draw.
2483+
const GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
2484+
SetupOneshotROV(config, static_cast<GSTextureMTL*>(config.rt), static_cast<GSTextureMTL*>(config.ds),
2485+
*config.draw_coarse_rasterize, rtsize);
2486+
}
2487+
23502488
if (config.tex && (config.ds == config.tex || config.rt == config.tex))
23512489
EndRenderPass(); // Barrier
23522490

pcsx2/GS/Renderers/Metal/convert.metal

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,23 @@ fragment float4 ps_shadeboost(float4 p [[position]], DirectReadTextureIn<float>
564564

565565
return float4(csb, 1);
566566
}
567+
568+
struct ROVCopyBothOut
569+
{
570+
float4 color [[color(0)]];
571+
float depth [[color(1)]];
572+
};
573+
574+
fragment float4 ps_rov_copy_color(float4 p [[position]], texture2d<float> tex [[texture(GSMTLTextureIndexNonHW)]])
575+
{
576+
return tex.read(uint2(p.xy));
577+
}
578+
fragment float ps_rov_copy_depth(float4 p [[position]], depth2d<float> tex [[texture(GSMTLTextureIndexNonHW)]])
579+
{
580+
return tex.read(uint2(p.xy));
581+
}
582+
fragment ROVCopyBothOut ps_rov_copy_both(float4 p [[position]], texture2d<float> ctex [[texture(0)]], depth2d<float> dtex [[texture(1)]])
583+
{
584+
uint2 pos = uint2(p.xy);
585+
return { ctex.read(pos), dtex.read(pos) };
586+
}

pcsx2/GS/Renderers/Metal/tfx.metal

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,22 @@ constant uint PS_SCANMSK [[function_constant(GSMTLConstantIndex_PS_SC
7676
constant uint PS_AA1_RAW [[function_constant(GSMTLConstantIndex_PS_AA1)]];
7777
constant bool PS_ABE [[function_constant(GSMTLConstantIndex_PS_ABE)]];
7878
constant uint PS_SW_ANISO [[function_constant(GSMTLConstantIndex_PS_SW_ANISO)]];
79-
constant bool PS_ROV_COLOR [[function_constant(GSMTLConstantIndex_PS_ROV_COLOR)]];
79+
constant uint PS_ROV_COLOR_RAW [[function_constant(GSMTLConstantIndex_PS_ROV_COLOR)]];
8080
constant uint PS_ROV_DEPTH_RAW [[function_constant(GSMTLConstantIndex_PS_ROV_DEPTH)]];
8181

8282
using GSShader::VSExpand;
8383
using AFAIL = GSShader::PS_AFAIL;
8484
using ATST = GSShader::PS_ATST;
8585
using GSShader::ZTST;
8686
using AA1 = GSShader::PS_AA1;
87+
using ROV_COLOR = GSShader::PS_ROV_COLOR;
8788
using ROV_DEPTH = GSShader::PS_ROV_DEPTH;
8889
constant VSExpand VS_EXPAND_TYPE = static_cast<VSExpand>(VS_EXPAND_TYPE_RAW);
8990
constant AFAIL PS_AFAIL = static_cast<AFAIL>(PS_AFAIL_RAW);
9091
constant ATST PS_ATST = static_cast<ATST>(PS_ATST_RAW);
9192
constant ZTST PS_ZTST = static_cast<ZTST>(PS_ZTST_RAW);
9293
constant AA1 PS_AA1 = static_cast<AA1>(PS_AA1_RAW);
94+
constant ROV_COLOR PS_ROV_COLOR = static_cast<ROV_COLOR>(PS_ROV_COLOR_RAW);
9395
constant ROV_DEPTH PS_ROV_DEPTH = static_cast<ROV_DEPTH>(PS_ROV_DEPTH_RAW);
9496

9597
#if defined(__METAL_MACOS__) && __METAL_VERSION__ >= 220
@@ -124,9 +126,9 @@ constant bool NEEDS_DEPTH_FOR_ZTST = PS_ZTST == ZTST::GEQUAL || PS_ZTST == ZTST
124126
constant bool NEEDS_DEPTH_FOR_AA1 = PS_AA1 == AA1::TRIANGLE_SW_Z;
125127
constant bool SW_DEPTH = NEEDS_DEPTH_FOR_AFAIL || NEEDS_DEPTH_FOR_ZTST || NEEDS_DEPTH_FOR_AA1;
126128

127-
constant bool PS_OUTPUT_COLOR0 = !PS_NO_COLOR && !PS_ROV_COLOR;
128-
constant bool PS_OUTPUT_COLOR1 = !PS_NO_COLOR1 && !PS_ROV_COLOR;
129-
constant bool PS_ZOUTPUT = (PS_ZCLAMP || PS_ZFLOOR || SW_DEPTH) && PS_ROV_DEPTH == ROV_DEPTH::NONE;
129+
constant bool PS_OUTPUT_COLOR0 = !PS_NO_COLOR && (PS_ROV_COLOR != ROV_COLOR::ENABLED);
130+
constant bool PS_OUTPUT_COLOR1 = !PS_NO_COLOR1 && (PS_ROV_COLOR != ROV_COLOR::NONE);
131+
constant bool PS_ZOUTPUT = (PS_ZCLAMP || PS_ZFLOOR || SW_DEPTH) && PS_ROV_DEPTH != ROV_DEPTH::READ_WRITE && PS_ROV_DEPTH != ROV_DEPTH::READ_ONLY;
130132
constant bool PS_ZOUTPUT_LESS = PS_ZOUTPUT && !SW_DEPTH;
131133
constant bool PS_ZOUTPUT_ANY = PS_ZOUTPUT && SW_DEPTH;
132134
constant bool PS_ZOUTPUT_COLOR = PS_ZOUTPUT_ANY && !DEPTH_FEEDBACK;
@@ -583,23 +585,23 @@ struct PSMain
583585

584586
void discard()
585587
{
586-
if (PS_ROV_COLOR || PS_ROV_DEPTH != ROV_DEPTH::NONE)
588+
if (PS_ROV_COLOR != ROV_COLOR::NONE || PS_ROV_DEPTH != ROV_DEPTH::NONE)
587589
color_discarded = depth_discarded = true;
588590
else
589591
discard_fragment();
590592
}
591593

592594
void discard_color(thread float4& output)
593595
{
594-
if (PS_ROV_COLOR)
596+
if (PS_ROV_COLOR != ROV_COLOR::NONE)
595597
color_discarded = true;
596598
else
597599
output = current_color;
598600
}
599601

600602
void discard_depth(thread float& output)
601603
{
602-
if (PS_ROV_DEPTH == ROV_DEPTH::READ_WRITE)
604+
if (PS_ROV_DEPTH == ROV_DEPTH::READ_WRITE || PS_ROV_DEPTH == ROV_DEPTH::ONESHOT_READ_WRITE)
603605
depth_discarded = true;
604606
else
605607
output = current_depth;
@@ -1693,18 +1695,18 @@ fragment float4 fbfetch_test(float4 in [[color(0), raster_order_group(0)]])
16931695
return in * 2;
16941696
}
16951697

1696-
constant bool NEEDS_RT_TEX = NEEDS_RT && !HAS_FBFETCH && !PS_ROV_COLOR;
1697-
constant bool NEEDS_RT_FBF = NEEDS_RT && HAS_FBFETCH && !PS_ROV_COLOR;
1698+
constant bool NEEDS_RT_TEX = NEEDS_RT && !HAS_FBFETCH && (PS_ROV_COLOR != ROV_COLOR::NONE);
1699+
constant bool NEEDS_RT_FBF = NEEDS_RT && HAS_FBFETCH && (PS_ROV_COLOR != ROV_COLOR::NONE);
16981700
constant bool NEEDS_DS_FBF = SW_DEPTH && HAS_FBFETCH && !DEPTH_FEEDBACK && PS_ROV_DEPTH == ROV_DEPTH::NONE;
16991701
#else
1700-
constant bool NEEDS_RT_TEX = NEEDS_RT && !PS_ROV_COLOR;
1702+
constant bool NEEDS_RT_TEX = NEEDS_RT && (PS_ROV_COLOR != ROV_COLOR::NONE);
17011703
constant bool NEEDS_DS_FBF = false;
17021704
constant float ds_fbf = 0;
17031705
#endif
17041706
constant bool NEEDS_DS_TEX = SW_DEPTH && !DEPTH_FEEDBACK && !NEEDS_DS_FBF && PS_ROV_DEPTH == ROV_DEPTH::NONE;
17051707
constant bool NEEDS_DS_DEPTH = (SW_DEPTH && DEPTH_FEEDBACK || NEEDS_DS_FBF) && PS_ROV_DEPTH == ROV_DEPTH::NONE;
1706-
constant bool NEEDS_RT_ROV = PS_ROV_COLOR && !ROV_NEEDS_R32;
1707-
constant bool NEEDS_RT_U32 = PS_ROV_COLOR && ROV_NEEDS_R32;
1708+
constant bool NEEDS_RT_ROV = (PS_ROV_COLOR != ROV_COLOR::NONE) && !ROV_NEEDS_R32;
1709+
constant bool NEEDS_RT_U32 = (PS_ROV_COLOR != ROV_COLOR::NONE) && ROV_NEEDS_R32;
17081710
constant bool NEEDS_DS_ROV = PS_ROV_DEPTH != ROV_DEPTH::NONE;
17091711

17101712
fragment MainPSOut ps_main(
@@ -1758,9 +1760,9 @@ fragment MainPSOut ps_main(
17581760
main.current_depth = ds_tex.read(coord).x;
17591761
}
17601762

1761-
if (NEEDS_RT || (PS_ROV_COLOR && any(cb.fbmask == 0xff)))
1763+
if (NEEDS_RT || (PS_ROV_COLOR != ROV_COLOR::NONE && any(cb.fbmask == 0xff)))
17621764
{
1763-
if (PS_ROV_COLOR)
1765+
if (PS_ROV_COLOR != ROV_COLOR::NONE)
17641766
{
17651767
if (ROV_NEEDS_R32)
17661768
main.current_color = unpack_unorm4x8_to_float(rt_u32.read(coord).x);
@@ -1782,9 +1784,9 @@ fragment MainPSOut ps_main(
17821784
}
17831785

17841786
MainResult out = main.ps_main();
1785-
if (PS_ROV_DEPTH == ROV_DEPTH::READ_WRITE && !main.depth_discarded)
1787+
if ((PS_ROV_DEPTH == ROV_DEPTH::READ_WRITE || PS_ROV_DEPTH == ROV_DEPTH::ONESHOT_READ_WRITE) && !main.depth_discarded)
17861788
ds_rov.write(out.depth, coord);
1787-
if (PS_ROV_COLOR && !main.color_discarded)
1789+
if ((PS_ROV_COLOR != ROV_COLOR::NONE) && !main.color_discarded)
17881790
{
17891791
if (!PS_FBMASK)
17901792
out.c0 = select(out.c0, main.current_color, cb.fbmask == 0xff);

0 commit comments

Comments
 (0)