Skip to content

Commit ba79de0

Browse files
hrydgardkonistehrad
authored andcommitted
Turn off vertex range culling in bezier/spline calls.
When we do lower res tess than the real PSP, we cant trust the game to not cause range culling to kick in. Fixes hrydgard#11692
1 parent 8fea940 commit ba79de0

11 files changed

+43
-19
lines changed

Common/GPU/ShaderWriter.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
8383
case ShaderStage::Fragment:
8484
W(vulkan_glsl_preamble_fs);
8585
break;
86+
default:
87+
break;
8688
}
8789
break;
8890
case HLSL_D3D11:
@@ -99,6 +101,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
99101
W(hlsl_d3d11_preamble_fs);
100102
}
101103
break;
104+
default:
105+
break;
102106
}
103107
break;
104108
default: // OpenGL
@@ -125,6 +129,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
125129
}
126130
C("#define gl_VertexIndex gl_VertexID\n");
127131
break;
132+
default:
133+
break;
128134
}
129135
if (!lang_.gles) {
130136
C("#define lowp\n");
@@ -293,6 +299,8 @@ void ShaderWriter::DeclareSampler2D(const char *name, int binding) {
293299
case HLSL_D3D11:
294300
F("SamplerState %s : register(s%d);\n", name, binding);
295301
break;
302+
default:
303+
break;
296304
}
297305
}
298306

GPU/Common/ShaderId.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ std::string VertexShaderDesc(const VShaderID &id) {
5656
if (id.Bit(VS_BIT_HAS_TEXCOORD_TESS)) desc << "TessT ";
5757
if (id.Bit(VS_BIT_HAS_NORMAL_TESS)) desc << "TessN ";
5858
if (id.Bit(VS_BIT_NORM_REVERSE_TESS)) desc << "TessRevN ";
59+
if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc << "Cull ";
5960

6061
return desc.str();
6162
}
@@ -70,17 +71,20 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
7071
bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0;
7172
bool hasTexcoord = (vertType & GE_VTYPE_TC_MASK) != 0;
7273

73-
bool doBezier = gstate_c.bezier;
74-
bool doSpline = gstate_c.spline;
74+
bool doBezier = gstate_c.submitType == SubmitType::HW_BEZIER;
75+
bool doSpline = gstate_c.submitType == SubmitType::HW_SPLINE;
7576

7677
bool enableFog = gstate.isFogEnabled() && !isModeThrough && !gstate.isModeClear();
7778
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !isModeThrough;
79+
bool vertexRangeCulling = gstate_c.Supports(GPU_SUPPORTS_VS_RANGE_CULLING) &&
80+
!isModeThrough && gstate_c.submitType == SubmitType::DRAW; // neither hw nor sw spline/bezier. See #11692
7881

7982
VShaderID id;
8083
id.SetBit(VS_BIT_LMODE, lmode);
8184
id.SetBit(VS_BIT_IS_THROUGH, isModeThrough);
8285
id.SetBit(VS_BIT_ENABLE_FOG, enableFog);
8386
id.SetBit(VS_BIT_HAS_COLOR, hasColor);
87+
id.SetBit(VS_BIT_VERTEX_RANGE_CULLING, vertexRangeCulling);
8488

8589
if (doTexture) {
8690
id.SetBit(VS_BIT_DO_TEXTURE);

GPU/Common/ShaderId.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ enum VShaderBit : uint8_t {
1515
VS_BIT_ENABLE_FOG = 2,
1616
VS_BIT_HAS_COLOR = 3,
1717
VS_BIT_DO_TEXTURE = 4,
18-
// 5 is free.
18+
VS_BIT_VERTEX_RANGE_CULLING = 5,
1919
// 6 is free,
2020
// 7 is free.
2121
VS_BIT_USE_HW_TRANSFORM = 8,

GPU/Common/ShaderUniforms.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
215215
const int h = gstate.getTextureHeight(0);
216216
const float widthFactor = (float)w * invW;
217217
const float heightFactor = (float)h * invH;
218-
if (gstate_c.bezier || gstate_c.spline) {
218+
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
219219
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
220220
// However, this is missing a check that we're not getting our UV:s supplied for us in the vertices.
221221
ub->uvScaleOffset[0] = gstate_c.uv.uScale * widthFactor;

GPU/Common/VertexShaderGenerator.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
207207
}
208208
bool texCoordInVec3 = false;
209209

210+
bool vertexRangeCulling = id.Bit(VS_BIT_VERTEX_RANGE_CULLING);
211+
210212
if (compat.shaderLanguage == GLSL_VULKAN) {
211213
WRITE(p, "\n");
212214
WRITE(p, "layout (std140, set = 0, binding = 3) uniform baseVars {\n%s};\n", ub_baseStr);
@@ -1086,7 +1088,7 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
10861088
WRITE(p, " %sv_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;\n", compat.vsOutPrefix);
10871089
}
10881090

1089-
if (!isModeThrough && gstate_c.Supports(GPU_SUPPORTS_VS_RANGE_CULLING)) {
1091+
if (vertexRangeCulling) {
10901092
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
10911093
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
10921094
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");

GPU/D3D11/DrawEngineD3D11.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ void DrawEngineD3D11::DoFlush() {
341341
ApplyDrawState(prim);
342342

343343
// Always use software for flat shading to fix the provoking index.
344-
bool tess = gstate_c.bezier || gstate_c.spline;
344+
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
345345
bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
346346

347347
if (useHWTransform) {

GPU/Directx9/ShaderManagerDX9.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
543543

544544
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType) {
545545
// Always use software for flat shading to fix the provoking index.
546-
bool tess = gstate_c.bezier || gstate_c.spline;
546+
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
547547
useHWTransform = useHWTransform && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
548548

549549
VShaderID VSID;

GPU/GLES/ShaderManagerGLES.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
409409
const float widthFactor = (float)w * invW;
410410
const float heightFactor = (float)h * invH;
411411
float uvscaleoff[4];
412-
if (gstate_c.bezier || gstate_c.spline) {
412+
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
413413
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
414414
// However, this is missing a check that we're not getting our UV:s supplied for us in the vertices.
415415
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;

GPU/GPUCommon.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -1830,20 +1830,21 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) {
18301830

18311831
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
18321832
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1833-
gstate_c.bezier = true;
1833+
gstate_c.submitType = SubmitType::HW_BEZIER;
18341834
if (gstate_c.spline_num_points_u != surface.num_points_u) {
18351835
gstate_c.Dirty(DIRTY_BEZIERSPLINE);
18361836
gstate_c.spline_num_points_u = surface.num_points_u;
18371837
}
1838+
} else {
1839+
gstate_c.submitType = SubmitType::BEZIER;
18381840
}
18391841

18401842
int bytesRead = 0;
18411843
UpdateUVScaleOffset();
18421844
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "bezier");
18431845

1844-
if (gstate_c.bezier)
1845-
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1846-
gstate_c.bezier = false;
1846+
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1847+
gstate_c.submitType = SubmitType::DRAW;
18471848

18481849
// After drawing, we advance pointers - see SubmitPrim which does the same.
18491850
int count = surface.num_points_u * surface.num_points_v;
@@ -1896,20 +1897,21 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) {
18961897

18971898
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
18981899
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1899-
gstate_c.spline = true;
1900+
gstate_c.submitType = SubmitType::HW_SPLINE;
19001901
if (gstate_c.spline_num_points_u != surface.num_points_u) {
19011902
gstate_c.Dirty(DIRTY_BEZIERSPLINE);
19021903
gstate_c.spline_num_points_u = surface.num_points_u;
19031904
}
1905+
} else {
1906+
gstate_c.submitType = SubmitType::SPLINE;
19041907
}
19051908

19061909
int bytesRead = 0;
19071910
UpdateUVScaleOffset();
19081911
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "spline");
19091912

1910-
if (gstate_c.spline)
1911-
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1912-
gstate_c.spline = false;
1913+
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
1914+
gstate_c.submitType = SubmitType::DRAW;
19131915

19141916
// After drawing, we advance pointers - see SubmitPrim which does the same.
19151917
int count = surface.num_points_u * surface.num_points_v;

GPU/GPUState.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,14 @@ struct KnownVertexBounds {
504504
u16 maxV;
505505
};
506506

507+
enum class SubmitType {
508+
DRAW,
509+
BEZIER,
510+
SPLINE,
511+
HW_BEZIER,
512+
HW_SPLINE,
513+
};
514+
507515
struct GPUStateCache {
508516
bool Supports(u32 flags) { return (featureFlags & flags) != 0; } // Return true if ANY of flags are true.
509517
bool SupportsAll(u32 flags) { return (featureFlags & flags) == flags; } // Return true if ALL flags are true.
@@ -602,8 +610,8 @@ struct GPUStateCache {
602610
}
603611
u32 curRTOffsetX;
604612

605-
bool bezier;
606-
bool spline;
613+
// Set if we are doing hardware bezier/spline.
614+
SubmitType submitType;
607615
int spline_num_points_u;
608616

609617
bool useShaderDepal;

GPU/Vulkan/DrawEngineVulkan.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ void DrawEngineVulkan::DoFlush() {
598598

599599
FrameData *frame = &frame_[vulkan_->GetCurFrame()];
600600

601-
bool tess = gstate_c.bezier || gstate_c.spline;
601+
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
602602

603603
bool textureNeedsApply = false;
604604
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {

0 commit comments

Comments
 (0)