mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Apply a small depth bias to simulate rounding of Z. Fix min/max clip plane math
This commit is contained in:
@@ -36,6 +36,8 @@ const char * const hlsl_preamble_fs =
|
||||
"#define fract frac\n"
|
||||
"#define mod(x, y) fmod(x, y)\n"
|
||||
"#define inversesqrt rsqrt\n"
|
||||
"#define floatBitsToUint asuint\n"
|
||||
"#define uintBitsToFloat asfloat\n"
|
||||
"\n";
|
||||
|
||||
static const char * const hlsl_d3d11_preamble_fs =
|
||||
@@ -65,6 +67,8 @@ static const char * const hlsl_preamble_gs =
|
||||
"#define mediump\n"
|
||||
"#define highp\n"
|
||||
"#define inversesqrt rsqrt\n"
|
||||
"#define floatBitsToUint asuint\n"
|
||||
"#define uintBitsToFloat asfloat\n"
|
||||
"\n";
|
||||
|
||||
static const char * const vulkan_glsl_preamble_gs =
|
||||
@@ -92,6 +96,8 @@ static const char * const hlsl_preamble_vs =
|
||||
"#define fract frac\n"
|
||||
"#define mod(x, y) fmod(x, y)\n"
|
||||
"#define inversesqrt rsqrt\n"
|
||||
"#define floatBitsToUint asuint\n"
|
||||
"#define uintBitsToFloat asfloat\n"
|
||||
"\n";
|
||||
|
||||
static const char * const semanticNames[] = {
|
||||
|
||||
@@ -368,7 +368,8 @@ void SoftwareTransform::Transform(const float projMtx[16], Lin::Vec3 vpScale, Li
|
||||
Vec3ByMatrix44(xyzw, v, projMtx);
|
||||
|
||||
// Here we also need to apply the viewport.
|
||||
Lin::Vec3 xyz = vpOffset + vpScale.scaledBy(Lin::Vec3(xyzw[0] / xyzw[3], xyzw[1] / xyzw[3], xyzw[2] / xyzw[3]));
|
||||
float recip = 1.0f / xyzw[3];
|
||||
Lin::Vec3 xyz = vpOffset + vpScale.scaledBy(Lin::Vec3(xyzw[0] * recip, xyzw[1] * recip, xyzw[2] * recip));
|
||||
transformed[index].x = xyz.x;
|
||||
transformed[index].y = xyz.y;
|
||||
transformed[index].z = xyz.z;
|
||||
|
||||
@@ -355,9 +355,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
zClipPlaneSuffix = ".x";
|
||||
minZClipPlaneSuffix = ".y";
|
||||
maxZClipPlaneSuffix = ".z";
|
||||
bool clipRange = gstate_c.Use(GPU_USE_CLIP_DISTANCE);
|
||||
WRITE(p, " float3 gl_ClipDistance : SV_ClipDistance;\n");
|
||||
WRITE(p, " float2 gl_CullDistance : SV_CullDistance0;\n");
|
||||
if (gstate_c.Use(GPU_USE_CLIP_DISTANCE)) {
|
||||
WRITE(p, " float3 gl_ClipDistance : SV_ClipDistance;\n");
|
||||
WRITE(p, " float2 gl_CullDistance : SV_CullDistance0;\n");
|
||||
}
|
||||
}
|
||||
WRITE(p, "};\n");
|
||||
} else {
|
||||
@@ -734,16 +735,9 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
if (isModeThrough) {
|
||||
WRITE(p, " vec4 outPos = position;\n");
|
||||
WRITE(p, " outPos.z *= 65536.0;\n"); // TODO: This multiplication should be moved to the vertex decoders for through mode.
|
||||
WRITE(p, " outPos.w = 1.0;\n");
|
||||
} else {
|
||||
// The viewport is used in this case, so need to compensate for that.
|
||||
if (gstate_c.Use(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(position);\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = position;\n");
|
||||
}
|
||||
|
||||
// Here we need to apply the viewport and also range culling, just like with the hardware transform below.
|
||||
// The viewport has already been applied here.
|
||||
WRITE(p, " vec4 outPos = position;\n");
|
||||
}
|
||||
} else {
|
||||
// Step 1: World Transform / Skinning
|
||||
@@ -822,20 +816,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
}
|
||||
|
||||
// Final view and projection transforms.
|
||||
if (gstate_c.Use(GPU_ROUND_DEPTH_TO_16BIT)) {
|
||||
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(mul(u_proj_lens, viewPos));\n");
|
||||
WRITE(p, " vec4 orgPos = depthRoundZVP(mul(u_proj, viewPos));\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = depthRoundZVP(mul(u_proj, viewPos));\n");
|
||||
}
|
||||
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
|
||||
WRITE(p, " vec4 outPos = mul(u_proj_lens, viewPos);\n");
|
||||
WRITE(p, " vec4 orgPos = mul(u_proj, viewPos);\n");
|
||||
} else {
|
||||
if (gstate_c.Use(GPU_USE_VIRTUAL_REALITY)) {
|
||||
WRITE(p, " vec4 outPos = mul(u_proj_lens, viewPos);\n");
|
||||
WRITE(p, " vec4 orgPos = mul(u_proj, viewPos);\n");
|
||||
} else {
|
||||
WRITE(p, " vec4 outPos = mul(u_proj, viewPos);\n");
|
||||
}
|
||||
WRITE(p, " vec4 outPos = mul(u_proj, viewPos);\n");
|
||||
}
|
||||
|
||||
// We're in clip space, so here we check for clipping. We check if the actual hardware will clip.
|
||||
@@ -856,7 +841,6 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
// In software transform mode, this is performed in on the CPU.
|
||||
WRITE(p, " outPos.xyz = (outPos.xyz / outPos.w) * u_vpScale.xyz + u_vpOffset.xyz;\n");
|
||||
|
||||
|
||||
// TODO: Declare variables for dots for shade mapping if needed.
|
||||
|
||||
const char *srcCol = "color0";
|
||||
@@ -1227,11 +1211,13 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag
|
||||
WRITE(p, " outPos.xy -= u_rasterOffset.xy;\n");
|
||||
|
||||
if (gstate_c.Use(GPU_USE_CLIP_DISTANCE)) {
|
||||
// We use clipping to implement min/max Z.
|
||||
// 1.0 effectively disables the clip plane.
|
||||
// TODO: Should we move this to homogenous coordinates after the multiplication by w?
|
||||
WRITE(p, " gl_ClipDistance%s = u_minZmaxZ.x > 0.0 ? outPos.z - u_minZmaxZ.x : 1.0;\n", minZClipPlaneSuffix);
|
||||
WRITE(p, " gl_ClipDistance%s = u_minZmaxZ.y < 65535.0 ? u_minZmaxZ.y - outPos.z : 1.0;\n", maxZClipPlaneSuffix);
|
||||
// We use clipping, where available, to implement min/max Z.
|
||||
// 1.0 is used to disable the clip plane (should we generate more shaders instead? how costly are they?)
|
||||
// Note: outPos.z need to be multiplied by outPos.w to undo the division, which shouldn't be in effect here.
|
||||
// We should probably store the undivided outPos in a variable.
|
||||
// We apply a small offset here, it's needed to break some ties, like in the map in Test Drive Unlimited.
|
||||
WRITE(p, " gl_ClipDistance%s = u_minZmaxZ.x > 0.0 ? (outPos.z + 0.5 - u_minZmaxZ.x) * outPos.w : 1.0;\n", minZClipPlaneSuffix);
|
||||
WRITE(p, " gl_ClipDistance%s = u_minZmaxZ.y < 65535.0 ? (u_minZmaxZ.y - (outPos.z + 0.5)) * outPos.w : 1.0;\n", maxZClipPlaneSuffix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,18 @@ inline unsigned int toFloat24(float f) {
|
||||
return i >> 8;
|
||||
}
|
||||
|
||||
// TODO: Not completely sure about the exact mechanics here, or where we need to use this.
|
||||
// Useful to experiment with.
|
||||
inline float roundToFloat24(float f) {
|
||||
unsigned int i;
|
||||
memcpy(&i, &f, 4);
|
||||
i &= 0xFFFFFF00;
|
||||
i += 0x80;
|
||||
float retval;
|
||||
memcpy(&retval, &i, 4);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// TODO: Possibly use macros to disable expensive parts of stats tracking in release builds.
|
||||
struct GPUStatsPerFrame {
|
||||
// Per frame statistics
|
||||
|
||||
Reference in New Issue
Block a user