r300: Writing to result.depth in fragment programs (R3xx; only stub for R5xx)

Setup fg_depth_src for depth writing programs and change early Z (ztop)
semantics.

Piglit's version of glean/fragprog test passes now (unlike Glean, its
dependency on EXT_fog_coord, which we don't support, is optional).

R3xx only at the moment, but should be straightforward to adapt to R5xx
(I don't own an R5xx, and I don't want to break anything.)
This commit is contained in:
Nicolai Haehnle 2008-06-01 19:53:52 +02:00
parent d9c7c5f071
commit c9ea62444c
3 changed files with 54 additions and 30 deletions

View file

@ -794,6 +794,7 @@ struct r300_fragment_program {
int max_temp_idx;
GLboolean WritesDepth;
GLuint optimization;
};
@ -869,7 +870,7 @@ struct r300_state {
*/
struct r300_swtcl_info {
GLuint RenderIndex;
/**
* Size of a hardware vertex. This is calculated when \c ::vertex_attrs is
* installed in the Mesa state vector.

View file

@ -862,6 +862,7 @@ static int t_hw_dst(struct r300_fragment_program *fp,
R300_RGBA_OUT;
break;
case FRAG_RESULT_DEPR:
fp->WritesDepth = GL_TRUE;
fp->node[fp->cur_node].flags |=
R300_W_OUT;
break;
@ -2105,6 +2106,7 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *fp)
fp->translated = GL_FALSE;
fp->error = GL_FALSE;
fp->cs = cs = &(R300_CONTEXT(fp->ctx)->state.pfs_compile);
fp->WritesDepth = GL_FALSE;
fp->tex.length = 0;
fp->cur_node = 0;
fp->first_node_has_tex = 0;

View file

@ -402,42 +402,37 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
}
}
static void r300SetEarlyZState(GLcontext * ctx)
static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
{
/* updates register R300_RB3D_EARLY_Z (0x4F14)
if depth test is not enabled it should be R300_EARLY_Z_DISABLE
if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE
if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE
*/
r300ContextPtr r300 = R300_CONTEXT(ctx);
R300_STATECHANGE(r300, zstencil_format);
switch (ctx->Visual.depthBits) {
case 16:
r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_16BIT_INT_Z;
break;
case 24:
r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
break;
default:
fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits);
_mesa_exit(-1);
if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
struct r300_fragment_program *fp = (struct r300_fragment_program *)
(char *)ctx->FragmentProgram._Current;
return (fp && fp->WritesDepth);
} else {
return GL_FALSE; /* TODO: Verify depth writing works on R5xx */
}
}
static void r300SetEarlyZState(GLcontext * ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
GLuint topZ = R300_ZTOP_ENABLE;
if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS)
/* disable early Z */
r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
else {
if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER)
/* enable early Z */
r300->hw.zstencil_format.cmd[2] = R300_ZTOP_ENABLE;
else
/* disable early Z */
r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
}
topZ = R300_ZTOP_DISABLE;
if (current_fragment_program_writes_depth(ctx))
topZ = R300_ZTOP_DISABLE;
r300->hw.zstencil_format.cmd[3] = 0x00000003;
r300->hw.zstencil_format.cmd[4] = 0x00000000;
if (topZ != r300->hw.zstencil_format.cmd[2]) {
/* Note: This completely reemits the stencil format.
* I have not tested whether this is strictly necessary,
* or if emitting a write to ZB_ZTOP is enough.
*/
R300_STATECHANGE(r300, zstencil_format);
r300->hw.zstencil_format.cmd[2] = topZ;
}
}
static void r300SetAlphaState(GLcontext * ctx)
@ -2346,6 +2341,23 @@ static void r300ResetHwState(r300ContextPtr r300)
r300->hw.zb_depthclearvalue.cmd[1] = 0;
switch (ctx->Visual.depthBits) {
case 16:
r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_16BIT_INT_Z;
break;
case 24:
r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
break;
default:
fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits);
_mesa_exit(-1);
}
r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
r300->hw.zstencil_format.cmd[3] = 0x00000003;
r300->hw.zstencil_format.cmd[4] = 0x00000000;
r300SetEarlyZState(ctx);
r300->hw.unk4F30.cmd[1] = 0;
r300->hw.unk4F30.cmd[2] = 0;
@ -2559,6 +2571,15 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
ctx = rmesa->radeon.glCtx;
r300UpdateTextureState(ctx);
r300SetEarlyZState(ctx);
GLuint fgdepthsrc = R300_FG_DEPTH_SRC_SCAN;
if (current_fragment_program_writes_depth(ctx))
fgdepthsrc = R300_FG_DEPTH_SRC_SHADER;
if (fgdepthsrc != rmesa->hw.fg_depth_src.cmd[1]) {
R300_STATECHANGE(rmesa, fg_depth_src);
rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc;
}
if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
r500SetupPixelShader(rmesa);