@@ -318,9 +318,10 @@ void main()
318318#define PS_NO_COLOR 0
319319#define PS_NO_COLOR1 0
320320#define PS_DATE 0
321- #define PS_TEX_IS_FB 0
322321#define PS_COLOR_FEEDBACK 0
323322#define PS_DEPTH_FEEDBACK 0
323+ #define PS_ROV_COLOR 0
324+ #define PS_ROV_DEPTH 0
324325#endif
325326
326327#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
@@ -331,10 +332,21 @@ void main()
331332#define ZTST_NEEDS_DEPTH (PS_ZTST == ZTST_GEQUAL || PS_ZTST == ZTST_GREATER)
332333
333334#define PS_FEEDBACK_LOOP_IS_NEEDED_RT (PS_TEX_IS_FB == 1 || AFAIL_NEEDS_RT || PS_FBMASK || SW_BLEND_NEEDS_RT || SW_AD_TO_HW || (PS_DATE >= 5 ) || PS_COLOR_FEEDBACK)
334- #define PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH (PS_DEPTH_FEEDBACK && (AFAIL_NEEDS_DEPTH || ZTST_NEEDS_DEPTH))
335+ #define PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH (PS_DEPTH_FEEDBACK && (AFAIL_NEEDS_DEPTH || ZTST_NEEDS_DEPTH || PS_ROV_DEPTH))
336+
337+ #define PS_RETURN_COLOR_ROV (! PS_NO_COLOR && PS_ROV_COLOR)
338+ #define PS_RETURN_COLOR (! PS_NO_COLOR && ! PS_ROV_COLOR)
339+ #define PS_RETURN_DEPTH_ROV (PS_ZWRITE && PS_ROV_DEPTH)
340+ #define PS_RETURN_DEPTH (PS_ZWRITE && ! PS_ROV_DEPTH)
341+ #define PS_ROV_EARLYDEPTHSTENCIL (PS_ROV_COLOR && ! PS_ROV_DEPTH && ! PS_ZWRITE)
335342
336343#define NEEDS_TEX (PS_TFX != 4 )
337344
345+ #if PS_ROV_COLOR || PS_ROV_DEPTH
346+ #extension GL_ARB_fragment_shader_interlock : enable
347+ #extension GL_ARB_shader_image_load_store : enable
348+ #endif
349+
338350layout (std140, set = 0 , binding = 1 ) uniform cb1
339351{
340352 vec3 FogColor;
@@ -355,6 +367,9 @@ layout(std140, set = 0, binding = 1) uniform cb1
355367 mat4 DitherMatrix;
356368 float ScaledScaleFactor;
357369 float RcpScaleFactor;
370+ float pad0;
371+ float pad1;
372+ uvec4 ColorMask;
358373};
359374
360375layout (location = 0 ) in VSOutput
@@ -368,11 +383,31 @@ layout(location = 0) in VSOutput
368383 #endif
369384} vsIn;
370385
371- #if ! PS_NO_COLOR && ! PS_NO_COLOR1
372- layout (location = 0 , index = 0 ) out vec4 o_col0;
373- layout (location = 0 , index = 1 ) out vec4 o_col1;
374- #elif ! PS_NO_COLOR
375- layout (location = 0 ) out vec4 o_col0;
386+ #if PS_RETURN_COLOR
387+ #if ! PS_NO_COLOR1
388+ layout (location = 0 , index = 0 ) out vec4 o_col0;
389+ layout (location = 0 , index = 1 ) out vec4 o_col1;
390+ #elif ! PS_NO_COLOR
391+ layout (location = 0 ) out vec4 o_col0;
392+ #endif
393+ #elif PS_RETURN_COLOR_ROV
394+ vec4 o_col0;
395+ #endif
396+
397+ #if PS_ROV_COLOR
398+ layout (set = 1 , binding = 5 , rgba8) uniform restrict coherent image2D RtImageRov;
399+ #if PS_FEEDBACK_LOOP_IS_NEEDED_RT
400+ vec4 cachedRtValue;
401+ vec4 sample_from_rt() { return cachedRtValue; }
402+ #endif
403+ #endif
404+
405+ #if PS_ROV_DEPTH
406+ layout (set = 1 , binding = 6 , r32f) uniform restrict coherent image2D DepthImageRov;
407+ #if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
408+ float cachedDepthValue;
409+ vec4 sample_from_depth() { return vec4 (cachedDepthValue, 0 .0f, 0 .0f, 0 .0f); }
410+ #endif
376411#endif
377412
378413#if NEEDS_TEX
@@ -382,25 +417,25 @@ layout(set = 1, binding = 1) uniform texture2D Palette;
382417
383418#if PS_FEEDBACK_LOOP_IS_NEEDED_RT || PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
384419 #if defined(DISABLE_TEXTURE_BARRIER) || defined(HAS_FEEDBACK_LOOP_LAYOUT)
385- #if PS_FEEDBACK_LOOP_IS_NEEDED_RT
420+ #if ( PS_FEEDBACK_LOOP_IS_NEEDED_RT && ! PS_ROV_COLOR)
386421 layout (set = 1 , binding = 2 ) uniform texture2D RtSampler;
387422 vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2 (gl_FragCoord .xy), 0 ); }
388423 #endif
389- #if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
424+ #if ( PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && ! PS_ROV_DEPTH)
390425 layout (set = 1 , binding = 4 ) uniform texture2D DepthSampler;
391426 vec4 sample_from_depth() { return texelFetch(DepthSampler, ivec2 (gl_FragCoord .xy), 0 ); }
392427 #endif
393428 #else
394429 // Must consider each case separately since the input attachment indices must be consecutive.
395- #if PS_FEEDBACK_LOOP_IS_NEEDED_RT && PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
430+ #if ( PS_FEEDBACK_LOOP_IS_NEEDED_RT && ! PS_ROV_COLOR) && ( PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && ! PS_ROV_DEPTH)
396431 layout (input_attachment_index = 0 , set = 1 , binding = 2 ) uniform subpassInput RtSampler;
397432 layout (input_attachment_index = 1 , set = 1 , binding = 4 ) uniform subpassInput DepthSampler;
398433 vec4 sample_from_rt() { return subpassLoad(RtSampler); }
399434 vec4 sample_from_depth() { return subpassLoad(DepthSampler); }
400- #elif PS_FEEDBACK_LOOP_IS_NEEDED_RT
435+ #elif ( PS_FEEDBACK_LOOP_IS_NEEDED_RT && ! PS_ROV_COLOR)
401436 layout (input_attachment_index = 0 , set = 1 , binding = 2 ) uniform subpassInput RtSampler;
402437 vec4 sample_from_rt() { return subpassLoad(RtSampler); }
403- #elif PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
438+ #elif ( PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && ! PS_ROV_DEPTH)
404439 layout (input_attachment_index = 0 , set = 1 , binding = 4 ) uniform subpassInput DepthSampler;
405440 vec4 sample_from_depth() { return subpassLoad(DepthSampler); }
406441 #endif
@@ -1282,6 +1317,20 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba)
12821317 #endif
12831318}
12841319
1320+ #if PS_ROV_COLOR || PS_ROV_DEPTH
1321+ layout (pixel_interlock_ordered) in ;
1322+ #endif
1323+
1324+ #if PS_ROV_EARLYDEPTHSTENCIL
1325+ layout (early_fragment_tests) in ;
1326+ #endif
1327+
1328+ #if PS_ROV_COLOR || PS_ROV_DEPTH
1329+ #define DISCARD rov_discard = true
1330+ #else
1331+ #define DISCARD discard
1332+ #endif
1333+
12851334void main()
12861335{
12871336 float input_z = gl_FragCoord .z;
@@ -1291,20 +1340,36 @@ void main()
12911340 input_z = floor (input_z * exp2 (32 .0f)) * exp2 (- 32 .0f);
12921341#endif
12931342
1294- #if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && (PS_ZTST == ZTST_GEQUAL || PS_ZTST == ZTST_GREATER)
1343+ #if PS_ROV_COLOR || PS_ROV_DEPTH
1344+ beginInvocationInterlockARB();
1345+ #endif
1346+
1347+ #if PS_ROV_COLOR && PS_FEEDBACK_LOOP_IS_NEEDED_RT
1348+ cachedRtValue = imageLoad(RtImageRov, ivec2 (gl_FragCoord .xy));
1349+ #endif
1350+
1351+ #if PS_ROV_DEPTH && PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
1352+ cachedDepthValue = imageLoad(DepthImageRov, ivec2 (gl_FragCoord .xy)).r;
1353+ #endif
1354+
1355+ #if (PS_ROV_COLOR && PS_FEEDBACK_LOOP_IS_NEEDED_RT) || (PS_ROV_DEPTH && PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH)
1356+ bool rov_discard = gl_HelperInvocation;
1357+ #endif
1358+
1359+ #if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH && ZTST_NEEDS_DEPTH
12951360 #if PS_ZTST == ZTST_GEQUAL
12961361 if (input_z < sample_from_depth().r)
1297- discard ;
1362+ DISCARD ;
12981363 #elif PS_ZTST == ZTST_GREATER
12991364 if (input_z <= sample_from_depth().r)
1300- discard ;
1365+ DISCARD ;
13011366 #endif
13021367#endif // PS_ZTST
13031368
13041369#if PS_SCANMSK & 2
13051370 // fail depth test on prohibited lines
13061371 if ((int (gl_FragCoord .y) & 1 ) == (PS_SCANMSK & 1 ))
1307- discard ;
1372+ DISCARD ;
13081373#endif
13091374#if PS_DATE >= 5
13101375
@@ -1332,7 +1397,7 @@ void main()
13321397#endif
13331398
13341399 if (bad) {
1335- discard ;
1400+ DISCARD ;
13361401 }
13371402
13381403#endif // PS_DATE >= 5
@@ -1343,7 +1408,7 @@ void main()
13431408 // the bad alpha value so we must keep it.
13441409
13451410 if (gl_PrimitiveID > stencil_ceil) {
1346- discard ;
1411+ DISCARD ;
13471412 }
13481413#endif
13491414
@@ -1356,9 +1421,10 @@ void main()
13561421
13571422 bool atst_pass = atst(C);
13581423
1359- #if PS_AFAIL == AFAIL_KEEP
1360- if (! atst_pass)
1361- discard ;
1424+ #if PS_ATST != PS_ATST_NONE && PS_AFAIL == AFAIL_KEEP
1425+ if (! atst_pass) {
1426+ DISCARD;
1427+ }
13621428#endif
13631429
13641430#if SW_AD_TO_HW
@@ -1450,6 +1516,7 @@ void main()
14501516 alpha_blend.a = float (atst_pass);
14511517 #endif
14521518
1519+ // Output color scaling
14531520 #if ! PS_NO_COLOR
14541521 #if PS_RTA_CORRECTION
14551522 o_col0.a = C.a / 128 .0f;
@@ -1489,8 +1556,33 @@ void main()
14891556 input_z = min (input_z, MaxDepthPS);
14901557 #endif
14911558
1492- #if PS_ZWRITE
1559+ // Writing back color (nothing to do for non-ROV)
1560+ #if PS_RETURN_COLOR_ROV
1561+ #if PS_FEEDBACK_LOOP_IS_NEEDED_RT
1562+ vec4 rt_col = sample_from_rt();
1563+
1564+ o_col0.r = bool (ColorMask.r) ? o_col0.r : rt_col.r;
1565+ o_col0.g = bool (ColorMask.g) ? o_col0.g : rt_col.g;
1566+ o_col0.b = bool (ColorMask.b) ? o_col0.b : rt_col.b;
1567+ o_col0.a = bool (ColorMask.a) ? o_col0.a : rt_col.a;
1568+
1569+ o_col0 = rov_discard ? rt_col : o_col0;
1570+ #endif
1571+
1572+ imageStore(RtImageRov, ivec2 (gl_FragCoord .xy), o_col0);
1573+ #endif
1574+
1575+ #if PS_RETURN_DEPTH
14931576 gl_FragDepth = input_z;
1577+ #elif PS_RETURN_DEPTH_ROV
1578+ #if PS_FEEDBACK_LOOP_IS_NEEDED_DEPTH
1579+ input_z = rov_discard ? sample_from_depth().r : input_z;
1580+ #endif
1581+ imageStore(DepthImageRov, ivec2 (gl_FragCoord .xy), vec4 (input_z, 0 , 0 , 1 .0f));
1582+ #endif
1583+
1584+ #if PS_ROV_COLOR || PS_ROV_DEPTH
1585+ endInvocationInterlockARB();
14941586 #endif
14951587#endif // PS_DATE
14961588}
0 commit comments