PixelShaderGen: Use subgroup reduction operations for bounding box

This commit is contained in:
Stenzek 2019-03-22 20:39:54 +10:00
parent 6561850f2b
commit d66d778bae
1 changed files with 29 additions and 11 deletions

View File

@ -459,6 +459,17 @@ SSBO_BINDING(0) buffer BBox {
}; };
#endif #endif
void UpdateBoundingBoxBuffer(float2 min_pos, float2 max_pos) {
if (bbox_left > int(min_pos.x))
atomicMin(bbox_left, int(min_pos.x));
if (bbox_right < int(max_pos.x))
atomicMax(bbox_right, int(max_pos.x));
if (bbox_top > int(min_pos.y))
atomicMin(bbox_top, int(min_pos.y));
if (bbox_bottom < int(max_pos.y))
atomicMax(bbox_bottom, int(max_pos.y));
}
void UpdateBoundingBox(float2 rawpos) { void UpdateBoundingBox(float2 rawpos) {
// The pixel center in the GameCube GPU is 7/12, not 0.5 (see VertexShaderGen.cpp) // The pixel center in the GameCube GPU is 7/12, not 0.5 (see VertexShaderGen.cpp)
// Adjust for this by unapplying the offset we added in the vertex shader. // Adjust for this by unapplying the offset we added in the vertex shader.
@ -471,18 +482,25 @@ void UpdateBoundingBox(float2 rawpos) {
#endif #endif
// The bounding box register is exclusive of the right coordinate, hence the +1. // The bounding box register is exclusive of the right coordinate, hence the +1.
int2 pos = iround(rawpos * cefbscale + offset); int2 min_pos = iround(rawpos * cefbscale + offset);
int2 pos_offset = pos + int2(1, 1); int2 max_pos = min_pos + int2(1, 1);
if (bbox_left > pos.x) #ifdef SUPPORTS_SUBGROUP_REDUCTION
atomicMin(bbox_left, pos.x); if (CAN_USE_SUBGROUP_REDUCTION) {
if (bbox_right < pos_offset.x) min_pos = IS_HELPER_INVOCATION ? int2(2147483647, 2147483647) : min_pos;
atomicMax(bbox_right, pos_offset.x); max_pos = IS_HELPER_INVOCATION ? int2(-2147483648, -2147483648) : max_pos;
if (bbox_top > pos.y) SUBGROUP_MIN(min_pos);
atomicMin(bbox_top, pos.y); SUBGROUP_MAX(max_pos);
if (bbox_bottom < pos_offset.y) if (IS_FIRST_ACTIVE_INVOCATION)
atomicMax(bbox_bottom, pos_offset.y); UpdateBoundingBoxBuffer(min_pos, max_pos);
} else {
UpdateBoundingBoxBuffer(min_pos, max_pos);
}
#else
UpdateBoundingBoxBuffer(min_pos, max_pos);
#endif
} }
)"); )");
} }
} }
@ -1332,7 +1350,7 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
if (!uid_data->alpha_test_use_zcomploc_hack) if (!uid_data->alpha_test_use_zcomploc_hack)
{ {
out.Write("\t\tdiscard;\n"); out.Write("\t\tdiscard;\n");
if (ApiType != APIType::D3D) if (ApiType == APIType::D3D)
out.Write("\t\treturn;\n"); out.Write("\t\treturn;\n");
} }