r300g: implement FP16 alpha test

This commit is contained in:
Marek Olšák 2011-03-04 17:28:44 +01:00
parent 910bac63df
commit 10a893106b
4 changed files with 55 additions and 8 deletions

View file

@ -194,7 +194,7 @@ static boolean r300_setup_atoms(struct r300_context* r300)
/* ZB (unpipelined), SC. */
R300_INIT_ATOM(ztop_state, 2);
/* ZB, FG. */
R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6);
R300_INIT_ATOM(dsa_state, is_r500 ? (drm_2_6_0 ? 10 : 8) : 6);
/* RB3D. */
R300_INIT_ATOM(blend_state, 8);
R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2);

View file

@ -92,9 +92,24 @@ struct r300_dsa_state {
uint32_t stencil_ref_mask; /* R300_ZB_STENCILREFMASK: 0x4f08 */
uint32_t cb_reg;
uint32_t stencil_ref_bf; /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */
uint32_t cb_reg1;
uint32_t alpha_value; /* R500_FG_ALPHA_VALUE: 0x4be0 */
/* The same, but for FP16 alpha test. */
uint32_t cb_begin_fp16;
uint32_t alpha_function_fp16; /* R300_FG_ALPHA_FUNC: 0x4bd4 */
uint32_t cb_reg_seq_fp16;
uint32_t z_buffer_control_fp16; /* R300_ZB_CNTL: 0x4f00 */
uint32_t z_stencil_control_fp16; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */
uint32_t stencil_ref_mask_fp16; /* R300_ZB_STENCILREFMASK: 0x4f08 */
uint32_t cb_reg_fp16;
uint32_t stencil_ref_bf_fp16; /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */
uint32_t cb_reg1_fp16;
uint32_t alpha_value_fp16; /* R500_FG_ALPHA_VALUE: 0x4be0 */
/* The second command buffer disables zbuffer reads and writes. */
uint32_t cb_no_readwrite[8];
uint32_t cb_zb_no_readwrite[10];
uint32_t cb_fp16_zb_no_readwrite[10];
/* Whether a two-sided stencil is enabled. */
boolean two_sided;

View file

@ -77,9 +77,15 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
CS_LOCALS(r300);
if (fb->zsbuf) {
WRITE_CS_TABLE(&dsa->cb_begin, size);
if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT)
WRITE_CS_TABLE(&dsa->cb_begin_fp16, size);
else
WRITE_CS_TABLE(&dsa->cb_begin, size);
} else {
WRITE_CS_TABLE(dsa->cb_no_readwrite, size);
if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT)
WRITE_CS_TABLE(dsa->cb_fp16_zb_no_readwrite, size);
else
WRITE_CS_TABLE(dsa->cb_zb_no_readwrite, size);
}
}

View file

@ -580,29 +580,54 @@ static void*
r300_translate_alpha_function(state->alpha.func) |
R300_FG_ALPHA_FUNC_ENABLE;
/* We could use 10bit alpha ref but who needs that? */
dsa->alpha_function |= float_to_ubyte(state->alpha.ref_value);
dsa->alpha_value = util_float_to_half(state->alpha.ref_value);
if (caps->is_r500)
if (caps->is_r500) {
dsa->alpha_function_fp16 = dsa->alpha_function |
R500_FG_ALPHA_FUNC_FP16_ENABLE;
dsa->alpha_function |= R500_FG_ALPHA_FUNC_8BIT;
}
}
BEGIN_CB(&dsa->cb_begin, 8);
BEGIN_CB(&dsa->cb_begin, 10);
OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
OUT_CB(dsa->z_buffer_control);
OUT_CB(dsa->z_stencil_control);
OUT_CB(dsa->stencil_ref_mask);
OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf);
OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value);
END_CB;
BEGIN_CB(dsa->cb_no_readwrite, 8);
BEGIN_CB(&dsa->cb_begin_fp16, 10);
OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16);
OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
OUT_CB(dsa->z_buffer_control);
OUT_CB(dsa->z_stencil_control);
OUT_CB(dsa->stencil_ref_mask);
OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf);
OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value);
END_CB;
BEGIN_CB(dsa->cb_zb_no_readwrite, 10);
OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
OUT_CB(0);
OUT_CB(0);
OUT_CB(0);
OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0);
OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value);
END_CB;
BEGIN_CB(dsa->cb_fp16_zb_no_readwrite, 10);
OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16);
OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
OUT_CB(0);
OUT_CB(0);
OUT_CB(0);
OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0);
OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value);
END_CB;
return (void*)dsa;
@ -729,6 +754,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
/* What is marked as dirty depends on the enum r300_fb_state_change. */
if (change == R300_CHANGED_FB_STATE) {
r300_mark_atom_dirty(r300, &r300->aa_state);
r300_mark_atom_dirty(r300, &r300->dsa_state); /* for AlphaRef */
r300_set_blend_color(&r300->context, r300->blend_color_state.state);
}