mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
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 #11692
This commit is contained in:
parent
c546c60324
commit
f3ebd6553d
@ -83,6 +83,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
|
||||
case ShaderStage::Fragment:
|
||||
W(vulkan_glsl_preamble_fs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HLSL_D3D11:
|
||||
@ -99,6 +101,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
|
||||
W(hlsl_d3d11_preamble_fs);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default: // OpenGL
|
||||
@ -125,6 +129,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions
|
||||
}
|
||||
C("#define gl_VertexIndex gl_VertexID\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!lang_.gles) {
|
||||
C("#define lowp\n");
|
||||
@ -293,6 +299,8 @@ void ShaderWriter::DeclareSampler2D(const char *name, int binding) {
|
||||
case HLSL_D3D11:
|
||||
F("SamplerState %s : register(s%d);\n", name, binding);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ std::string VertexShaderDesc(const VShaderID &id) {
|
||||
if (id.Bit(VS_BIT_HAS_TEXCOORD_TESS)) desc << "TessT ";
|
||||
if (id.Bit(VS_BIT_HAS_NORMAL_TESS)) desc << "TessN ";
|
||||
if (id.Bit(VS_BIT_NORM_REVERSE_TESS)) desc << "TessRevN ";
|
||||
if (id.Bit(VS_BIT_VERTEX_RANGE_CULLING)) desc << "Cull ";
|
||||
|
||||
return desc.str();
|
||||
}
|
||||
@ -70,17 +71,20 @@ void ComputeVertexShaderID(VShaderID *id_out, u32 vertType, bool useHWTransform,
|
||||
bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0;
|
||||
bool hasTexcoord = (vertType & GE_VTYPE_TC_MASK) != 0;
|
||||
|
||||
bool doBezier = gstate_c.bezier;
|
||||
bool doSpline = gstate_c.spline;
|
||||
bool doBezier = gstate_c.submitType == SubmitType::HW_BEZIER;
|
||||
bool doSpline = gstate_c.submitType == SubmitType::HW_SPLINE;
|
||||
|
||||
bool enableFog = gstate.isFogEnabled() && !isModeThrough && !gstate.isModeClear();
|
||||
bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled() && !isModeThrough;
|
||||
bool vertexRangeCulling = gstate_c.Supports(GPU_SUPPORTS_VS_RANGE_CULLING) &&
|
||||
!isModeThrough && gstate_c.submitType == SubmitType::DRAW; // neither hw nor sw spline/bezier. See #11692
|
||||
|
||||
VShaderID id;
|
||||
id.SetBit(VS_BIT_LMODE, lmode);
|
||||
id.SetBit(VS_BIT_IS_THROUGH, isModeThrough);
|
||||
id.SetBit(VS_BIT_ENABLE_FOG, enableFog);
|
||||
id.SetBit(VS_BIT_HAS_COLOR, hasColor);
|
||||
id.SetBit(VS_BIT_VERTEX_RANGE_CULLING, vertexRangeCulling);
|
||||
|
||||
if (doTexture) {
|
||||
id.SetBit(VS_BIT_DO_TEXTURE);
|
||||
|
@ -15,7 +15,7 @@ enum VShaderBit : uint8_t {
|
||||
VS_BIT_ENABLE_FOG = 2,
|
||||
VS_BIT_HAS_COLOR = 3,
|
||||
VS_BIT_DO_TEXTURE = 4,
|
||||
// 5 is free.
|
||||
VS_BIT_VERTEX_RANGE_CULLING = 5,
|
||||
// 6 is free,
|
||||
// 7 is free.
|
||||
VS_BIT_USE_HW_TRANSFORM = 8,
|
||||
|
@ -215,7 +215,7 @@ void BaseUpdateUniforms(UB_VS_FS_Base *ub, uint64_t dirtyUniforms, bool flipView
|
||||
const int h = gstate.getTextureHeight(0);
|
||||
const float widthFactor = (float)w * invW;
|
||||
const float heightFactor = (float)h * invH;
|
||||
if (gstate_c.bezier || gstate_c.spline) {
|
||||
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
|
||||
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
|
||||
// However, this is missing a check that we're not getting our UV:s supplied for us in the vertices.
|
||||
ub->uvScaleOffset[0] = gstate_c.uv.uScale * widthFactor;
|
||||
|
@ -207,6 +207,8 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
}
|
||||
bool texCoordInVec3 = false;
|
||||
|
||||
bool vertexRangeCulling = id.Bit(VS_BIT_VERTEX_RANGE_CULLING);
|
||||
|
||||
if (compat.shaderLanguage == GLSL_VULKAN) {
|
||||
WRITE(p, "\n");
|
||||
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
|
||||
WRITE(p, " %sv_fogdepth = (viewPos.z + u_fogcoef.x) * u_fogcoef.y;\n", compat.vsOutPrefix);
|
||||
}
|
||||
|
||||
if (!isModeThrough && gstate_c.Supports(GPU_SUPPORTS_VS_RANGE_CULLING)) {
|
||||
if (vertexRangeCulling) {
|
||||
WRITE(p, " vec3 projPos = outPos.xyz / outPos.w;\n");
|
||||
// Vertex range culling doesn't happen when depth is clamped, so only do this if in range.
|
||||
WRITE(p, " if (u_cullRangeMin.w <= 0.0 || (projPos.z >= u_cullRangeMin.z && projPos.z <= u_cullRangeMax.z)) {\n");
|
||||
|
@ -341,7 +341,7 @@ void DrawEngineD3D11::DoFlush() {
|
||||
ApplyDrawState(prim);
|
||||
|
||||
// Always use software for flat shading to fix the provoking index.
|
||||
bool tess = gstate_c.bezier || gstate_c.spline;
|
||||
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
|
||||
bool useHWTransform = CanUseHardwareTransform(prim) && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
|
||||
|
||||
if (useHWTransform) {
|
||||
|
@ -543,7 +543,7 @@ void ShaderManagerDX9::DirtyLastShader() { // disables vertex arrays
|
||||
|
||||
VSShader *ShaderManagerDX9::ApplyShader(bool useHWTransform, bool useHWTessellation, u32 vertType) {
|
||||
// Always use software for flat shading to fix the provoking index.
|
||||
bool tess = gstate_c.bezier || gstate_c.spline;
|
||||
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
|
||||
useHWTransform = useHWTransform && (tess || gstate.getShadeMode() != GE_SHADE_FLAT);
|
||||
|
||||
VShaderID VSID;
|
||||
|
@ -409,7 +409,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
|
||||
const float widthFactor = (float)w * invW;
|
||||
const float heightFactor = (float)h * invH;
|
||||
float uvscaleoff[4];
|
||||
if (gstate_c.bezier || gstate_c.spline) {
|
||||
if (gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE) {
|
||||
// When we are generating UV coordinates through the bezier/spline, we need to apply the scaling.
|
||||
// However, this is missing a check that we're not getting our UV:s supplied for us in the vertices.
|
||||
uvscaleoff[0] = gstate_c.uv.uScale * widthFactor;
|
||||
|
@ -1830,20 +1830,21 @@ void GPUCommon::Execute_Bezier(u32 op, u32 diff) {
|
||||
|
||||
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.bezier = true;
|
||||
gstate_c.submitType = SubmitType::HW_BEZIER;
|
||||
if (gstate_c.spline_num_points_u != surface.num_points_u) {
|
||||
gstate_c.Dirty(DIRTY_BEZIERSPLINE);
|
||||
gstate_c.spline_num_points_u = surface.num_points_u;
|
||||
}
|
||||
} else {
|
||||
gstate_c.submitType = SubmitType::BEZIER;
|
||||
}
|
||||
|
||||
int bytesRead = 0;
|
||||
UpdateUVScaleOffset();
|
||||
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "bezier");
|
||||
|
||||
if (gstate_c.bezier)
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.bezier = false;
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.submitType = SubmitType::DRAW;
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = surface.num_points_u * surface.num_points_v;
|
||||
@ -1896,20 +1897,21 @@ void GPUCommon::Execute_Spline(u32 op, u32 diff) {
|
||||
|
||||
if (drawEngineCommon_->CanUseHardwareTessellation(surface.primType)) {
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.spline = true;
|
||||
gstate_c.submitType = SubmitType::HW_SPLINE;
|
||||
if (gstate_c.spline_num_points_u != surface.num_points_u) {
|
||||
gstate_c.Dirty(DIRTY_BEZIERSPLINE);
|
||||
gstate_c.spline_num_points_u = surface.num_points_u;
|
||||
}
|
||||
} else {
|
||||
gstate_c.submitType = SubmitType::SPLINE;
|
||||
}
|
||||
|
||||
int bytesRead = 0;
|
||||
UpdateUVScaleOffset();
|
||||
drawEngineCommon_->SubmitCurve(control_points, indices, surface, gstate.vertType, &bytesRead, "spline");
|
||||
|
||||
if (gstate_c.spline)
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.spline = false;
|
||||
gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE);
|
||||
gstate_c.submitType = SubmitType::DRAW;
|
||||
|
||||
// After drawing, we advance pointers - see SubmitPrim which does the same.
|
||||
int count = surface.num_points_u * surface.num_points_v;
|
||||
|
@ -504,6 +504,14 @@ struct KnownVertexBounds {
|
||||
u16 maxV;
|
||||
};
|
||||
|
||||
enum class SubmitType {
|
||||
DRAW,
|
||||
BEZIER,
|
||||
SPLINE,
|
||||
HW_BEZIER,
|
||||
HW_SPLINE,
|
||||
};
|
||||
|
||||
struct GPUStateCache {
|
||||
bool Supports(u32 flags) { return (featureFlags & flags) != 0; } // Return true if ANY of flags are true.
|
||||
bool SupportsAll(u32 flags) { return (featureFlags & flags) == flags; } // Return true if ALL flags are true.
|
||||
@ -602,8 +610,8 @@ struct GPUStateCache {
|
||||
}
|
||||
u32 curRTOffsetX;
|
||||
|
||||
bool bezier;
|
||||
bool spline;
|
||||
// Set if we are doing hardware bezier/spline.
|
||||
SubmitType submitType;
|
||||
int spline_num_points_u;
|
||||
|
||||
bool useShaderDepal;
|
||||
|
@ -598,7 +598,7 @@ void DrawEngineVulkan::DoFlush() {
|
||||
|
||||
FrameData *frame = &frame_[vulkan_->GetCurFrame()];
|
||||
|
||||
bool tess = gstate_c.bezier || gstate_c.spline;
|
||||
bool tess = gstate_c.submitType == SubmitType::HW_BEZIER || gstate_c.submitType == SubmitType::HW_SPLINE;
|
||||
|
||||
bool textureNeedsApply = false;
|
||||
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
|
||||
|
Loading…
Reference in New Issue
Block a user