diff options
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.h | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_fragprog.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_state.c | 79 |
3 files changed, 54 insertions, 30 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 53e5d181a4..817f783dff 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -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. diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index ac45da4404..54b80d20a1 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -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; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index df4573d6b2..f0a5176949 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -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; + + 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; } - - r300->hw.zstencil_format.cmd[3] = 0x00000003; - r300->hw.zstencil_format.cmd[4] = 0x00000000; } 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); |