quick support for w buffers

This commit is contained in:
espes 2015-10-21 03:45:45 +11:00
parent 32a04b3f38
commit 20264b1df8
5 changed files with 30 additions and 8 deletions

View File

@ -394,6 +394,7 @@
# define NV_PGRAPH_CONTROL_0_ZFUNC_GEQUAL 6
# define NV_PGRAPH_CONTROL_0_ZFUNC_ALWAYS 7
# define NV_PGRAPH_CONTROL_0_DITHERENABLE (1 << 22)
# define NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE (1 << 23)
# define NV_PGRAPH_CONTROL_0_ZWRITEENABLE (1 << 24)
# define NV_PGRAPH_CONTROL_0_STENCIL_WRITE_ENABLE (1 << 25)
# define NV_PGRAPH_CONTROL_0_ALPHA_WRITE_ENABLE (1 << 26)
@ -765,6 +766,7 @@
# define NV097_SET_CONTROL0 0x00970290
# define NV097_SET_CONTROL0_STENCIL_WRITE_ENABLE (1 << 0)
# define NV097_SET_CONTROL0_Z_FORMAT (1 << 12)
# define NV097_SET_CONTROL0_Z_PERSPECTIVE_ENABLE (1 << 16)
# define NV097_SET_FOG_MODE 0x0097029C
# define NV097_SET_FOG_MODE_V_LINEAR 0x2601
# define NV097_SET_FOG_MODE_V_EXP 0x800
@ -2943,20 +2945,20 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
NV_PGRAPH_CONTROL_0_ALPHAFUNC),
},
/* fixed function stuff */
.skinning = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_SKIN),
.lighting = GET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
NV_PGRAPH_CSV0_C_LIGHTING),
.normalization = pg->regs[NV_PGRAPH_CSV0_C]
& NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE,
/* fixed function stuff */
.fixed_function = fixed_function,
/* vertex program stuff */
.vertex_program = vertex_program,
.z_perspective = pg->regs[NV_PGRAPH_CONTROL_0]
& NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE,
/* geometry shader stuff */
.primitive_mode = pg->primitive_mode,
@ -4297,6 +4299,12 @@ static void pgraph_method(NV2AState *d,
uint32_t z_format = GET_MASK(parameter, NV097_SET_CONTROL0_Z_FORMAT);
SET_MASK(pg->regs[NV_PGRAPH_SETUPRASTER],
NV_PGRAPH_SETUPRASTER_Z_FORMAT, z_format);
bool z_perspective =
parameter & NV097_SET_CONTROL0_Z_PERSPECTIVE_ENABLE;
SET_MASK(pg->regs[NV_PGRAPH_CONTROL_0],
NV_PGRAPH_CONTROL_0_Z_PERSPECTIVE_ENABLE,
z_perspective);
break;
}

View File

@ -628,6 +628,7 @@ static QString *generate_vertex_shader(const ShaderState state,
vsh_translate(VSH_VERSION_XVS,
(uint32_t*)state.program_data,
state.program_length,
state.z_perspective,
header, body);
} else {
assert(false);

View File

@ -74,6 +74,7 @@ typedef struct ShaderState {
bool vertex_program;
uint32_t program_data[NV2A_MAX_TRANSFORM_PROGRAM_LENGTH][VSH_TOKEN_SIZE];
int program_length;
bool z_perspective;
/* primitive format for geometry shader */
enum ShaderPolygonMode polygon_front_mode;

View File

@ -690,9 +690,10 @@ static const char* vsh_header =
"}\n";
void vsh_translate(uint16_t version,
const uint32_t *tokens,
unsigned int length,
QString *header, QString *body)
const uint32_t *tokens,
unsigned int length,
bool z_perspective,
QString *header, QString *body)
{
@ -732,7 +733,8 @@ void vsh_translate(uint16_t version,
" vtx.inv_w = 1.0;\n"
" } else {\n"
" vtx.inv_w = 1.0 / oPos.w;\n"
" }\n");
" }\n"
);
qstring_append(body,
/* the shaders leave the result in screen space, while
@ -741,6 +743,16 @@ void vsh_translate(uint16_t version,
*/
" oPos.x = 2.0 * (oPos.x - surfaceSize.x * 0.5) / surfaceSize.x;\n"
" oPos.y = -2.0 * (oPos.y - surfaceSize.y * 0.5) / surfaceSize.y;\n"
);
if (z_perspective) {
qstring_append(body, " oPos.z = oPos.w;\n");
}
qstring_append(body,
/* Map the clip range into clip space so z is clipped correctly.
* Note this makes the values in the depth buffer wrong. This should be
* handled with gl_ClipDistance instead, but that has performance issues
* on OS X.
*/
" if (clipRange.y != clipRange.x) {\n"
" oPos.z = (oPos.z - 0.5 * (clipRange.x + clipRange.y)) / (0.5 * (clipRange.y - clipRange.x));\n"
" }\n"
@ -755,7 +767,6 @@ void vsh_translate(uint16_t version,
* can't multiply by W because it could be meaningless here */
" oPos.w = 1.0;\n"
" }\n"
);
}

View File

@ -134,6 +134,7 @@ uint8_t vsh_get_field(const uint32_t *shader_token, VshFieldName field_name);
void vsh_translate(uint16_t version,
const uint32_t *tokens,
unsigned int length,
bool z_perspective,
QString *header, QString *body);