Compare commits

..

2 Commits

Author SHA1 Message Date
GPUCode
208e1a0aaf rasterizer_cache: Clear null surface to transparent 2024-01-21 13:22:35 +02:00
GPUCode
1247bff174 glsl_shader_gen: Remove invariant qualifier
* Causes visual regressions in Pokemon with RADV
2024-01-21 11:57:56 +02:00
2 changed files with 34 additions and 16 deletions

View File

@@ -67,6 +67,16 @@ RasterizerCache<T>::RasterizerCache(Memory::MemorySystem& memory_,
.wrap_s = TextureConfig::WrapMode::ClampToBorder,
.wrap_t = TextureConfig::WrapMode::ClampToBorder,
}));
auto& null_surface = slot_surfaces[NULL_SURFACE_ID];
runtime.ClearTexture(null_surface, {
.texture_level = 0,
.texture_rect = null_surface.GetScaledRect(),
.value =
{
.color = {0.f, 0.f, 0.f, 0.f},
},
});
}
template <class T>

View File

@@ -39,19 +39,6 @@ layout (binding = 1, std140) uniform vs_data {
bool enable_clip1;
vec4 clip_coef;
};
const vec2 EPSILON_Z = vec2(0.00000001f, -1.00001f);
vec4 SanitizeVertex(vec4 vtx_pos) {
float ndc_z = vtx_pos.z / vtx_pos.w;
if (ndc_z > 0.f && ndc_z < EPSILON_Z[0]) {
vtx_pos.z = 0.f;
}
if (ndc_z < -1.f && ndc_z > EPSILON_Z[1]) {
vtx_pos.z = -vtx_pos.w;
}
return vtx_pos;
}
)";
static std::string GetVertexInterfaceDeclaration(bool is_output, bool use_clip_planes,
@@ -76,7 +63,13 @@ static std::string GetVertexInterfaceDeclaration(bool is_output, bool use_clip_p
if (is_output && separable_shader) {
// gl_PerVertex redeclaration is required for separate shader object
out += "out gl_PerVertex {\n";
// Apple Silicon GPU drivers optimize more aggressively, which can create
// too much variance and cause visual artifacting in games like Pokemon.
#ifdef __APPLE__
out += " invariant vec4 gl_Position;\n";
#else
out += " vec4 gl_Position;\n";
#endif
if (use_clip_planes) {
out += " float gl_ClipDistance[2];\n";
}
@@ -107,7 +100,13 @@ std::string GenerateTrivialVertexShader(bool use_clip_planes, bool separable_sha
out += GetVertexInterfaceDeclaration(true, use_clip_planes, separable_shader);
out += VSUniformBlockDef;
// Certain games render 2D elements very close to clip plane 0 resulting in very tiny
// negative/positive z values when computing with f32 precision,
// causing some vertices to get erroneously clipped. To workaround this problem,
// we can use a very small epsilon value for clip plane comparison.
out += R"(
const float EPSILON_Z = 0.00000001f;
void main() {
primary_color = vert_color;
texcoord0 = vert_texcoord0;
@@ -116,7 +115,10 @@ void main() {
texcoord0_w = vert_texcoord0_w;
normquat = vert_normquat;
view = vert_view;
vec4 vtx_pos = SanitizeVertex(vert_position);
vec4 vtx_pos = vert_position;
if (abs(vtx_pos.z) < EPSILON_Z) {
vtx_pos.z = 0.f;
}
gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);
)";
if (use_clip_planes) {
@@ -219,6 +221,7 @@ std::string GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& c
return "1.0";
};
out += "const float EPSILON_Z = 0.00000001f;\n\n";
out += "vec4 GetVertexQuaternion() {\n";
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
@@ -231,7 +234,9 @@ std::string GenerateVertexShader(const ShaderSetup& setup, const PicaVSConfig& c
semantic(VSOutputAttributes::POSITION_Y) + ", " +
semantic(VSOutputAttributes::POSITION_Z) + ", " +
semantic(VSOutputAttributes::POSITION_W) + ");\n";
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
out += " if (abs(vtx_pos.z) < EPSILON_Z) {\n";
out += " vtx_pos.z = 0.f;\n";
out += " }\n";
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
if (config.state.use_clip_planes) {
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0
@@ -313,6 +318,7 @@ struct Vertex {
return "1.0";
};
out += "const float EPSILON_Z = 0.00000001f;\n\n";
out += "vec4 GetVertexQuaternion(Vertex vtx) {\n";
out += " return vec4(" + semantic(VSOutputAttributes::QUATERNION_X) + ", " +
semantic(VSOutputAttributes::QUATERNION_Y) + ", " +
@@ -325,7 +331,9 @@ struct Vertex {
semantic(VSOutputAttributes::POSITION_Y) + ", " +
semantic(VSOutputAttributes::POSITION_Z) + ", " +
semantic(VSOutputAttributes::POSITION_W) + ");\n";
out += " vtx_pos = SanitizeVertex(vtx_pos);\n";
out += " if (abs(vtx_pos.z) < EPSILON_Z) {\n";
out += " vtx_pos.z = 0.f;\n";
out += " }\n";
out += " gl_Position = vec4(vtx_pos.x, vtx_pos.y, -vtx_pos.z, vtx_pos.w);\n";
if (state.use_clip_planes) {
out += " gl_ClipDistance[0] = -vtx_pos.z;\n"; // fixed PICA clipping plane z <= 0