r300g: implement FP16 alpha test
authorMarek Olšák <maraeo@gmail.com>
Fri, 4 Mar 2011 16:28:44 +0000 (17:28 +0100)
committerMarek Olšák <maraeo@gmail.com>
Fri, 4 Mar 2011 16:47:56 +0000 (17:47 +0100)
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c

index 166d965aa5bb2118cca46c983fa2c5b8046624ad..a17be17383535995c91479fab15a18525a6ad3d2 100644 (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);
index b0a67e01225bc2cc1e8210c316db2443324790ee..446973696fc72d4660d228684245cfa81f7c83a1 100644 (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;
index 24c82a3efd262a8ff0799ca584e4d4fd52319e76..e3945b72d7a35fce9cda82fda95873cce9d6589a 100644 (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);
     }
 }
 
index 64fd7136b30ea591382f52d0a0621b8ef2617a33..187829358fc16921a038563db5f8ae9738e60a64 100644 (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_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_no_readwrite, 8);
+    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);
     }