r300g: simplify DSA state, add ability to patch FG_ALPHA_FUNC while emitting
authorMarek Olšák <maraeo@gmail.com>
Sun, 6 Jan 2013 00:47:24 +0000 (01:47 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sun, 6 Jan 2013 13:44:12 +0000 (14:44 +0100)
Preparation for MSAA and alpha-to-coverage.

src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c

index 5f9c2493cec3a77ef18bbe18f700b78e64670fdc..cddd91d7ab80c1237299d82ffadc69d3e6bc2c0a 100644 (file)
@@ -98,8 +98,6 @@ struct r300_dsa_state {
 
     /* This is actually a command buffer with named dwords. */
     uint32_t cb_begin;
-    uint32_t alpha_function;    /* R300_FG_ALPHA_FUNC: 0x4bd4 */
-    uint32_t cb_reg_seq;
     uint32_t z_buffer_control;  /* R300_ZB_CNTL: 0x4f00 */
     uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */
     uint32_t stencil_ref_mask;  /* R300_ZB_STENCILREFMASK: 0x4f08 */
@@ -108,21 +106,11 @@ struct r300_dsa_state {
     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_zb_no_readwrite[10];
-    uint32_t cb_fp16_zb_no_readwrite[10];
+    /* Same, but without ZB reads and writes. */
+    uint32_t cb_zb_no_readwrite[8]; /* ZB not bound */
+
+    /* Emitted separately: */
+    uint32_t alpha_function;
 
     /* Whether a two-sided stencil is enabled. */
     boolean two_sided;
index 51c14b43e4176f44cbfe07e56f222d3c6445a0ef..1b9de40afaad197e4c74b7145627af6bb910adca 100644 (file)
@@ -79,19 +79,22 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
     struct r300_dsa_state* dsa = (struct r300_dsa_state*)state;
     struct pipe_framebuffer_state* fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
+    boolean is_r500 = r300->screen->caps.is_r500;
     CS_LOCALS(r300);
+    uint32_t alpha_func = dsa->alpha_function;
 
-    if (fb->zsbuf) {
-        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 {
-        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);
+    /* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and
+     * 16-bit (FG_ALPHA_VALUE). */
+    if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) {
+        if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
+            alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE;
+        } else {
+            alpha_func |= R500_FG_ALPHA_FUNC_8BIT;
+        }
     }
+
+    OUT_CS_REG(R300_FG_ALPHA_FUNC, alpha_func);
+    WRITE_CS_TABLE(fb->zsbuf ? &dsa->cb_begin : dsa->cb_zb_no_readwrite, size-2);
 }
 
 static void get_rc_constant_state(
index 29e28b4dfb1cd25375cac3a20d8795dbc7dcaa30..a5f968310813bf4f603200ccb9483d47a435a2cf 100644 (file)
@@ -565,33 +565,37 @@ r300_set_sample_mask(struct pipe_context *pipe,
  * This contains the depth buffer, stencil buffer, alpha test, and such.
  * On the Radeon, depth and stencil buffer setup are intertwined, which is
  * the reason for some of the strange-looking assignments across registers. */
-static void*
-        r300_create_dsa_state(struct pipe_context* pipe,
-                              const struct pipe_depth_stencil_alpha_state* state)
+static void* r300_create_dsa_state(struct pipe_context* pipe,
+                          const struct pipe_depth_stencil_alpha_state* state)
 {
-    struct r300_capabilities *caps = &r300_screen(pipe->screen)->caps;
+    boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
     CB_LOCALS;
+    uint32_t alpha_value_fp16 = 0;
+    uint32_t z_buffer_control = 0;
+    uint32_t z_stencil_control = 0;
+    uint32_t stencil_ref_mask = 0;
+    uint32_t stencil_ref_bf = 0;
 
     dsa->dsa = *state;
 
     /* Depth test setup. - separate write mask depth for decomp flush */
     if (state->depth.writemask) {
-        dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
+        z_buffer_control |= R300_Z_WRITE_ENABLE;
     }
 
     if (state->depth.enabled) {
-        dsa->z_buffer_control |= R300_Z_ENABLE;
+        z_buffer_control |= R300_Z_ENABLE;
 
-        dsa->z_stencil_control |=
+        z_stencil_control |=
             (r300_translate_depth_stencil_function(state->depth.func) <<
                 R300_Z_FUNC_SHIFT);
     }
 
     /* Stencil buffer setup. */
     if (state->stencil[0].enabled) {
-        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
-        dsa->z_stencil_control |=
+        z_buffer_control |= R300_STENCIL_ENABLE;
+        z_stencil_control |=
             (r300_translate_depth_stencil_function(state->stencil[0].func) <<
                 R300_S_FRONT_FUNC_SHIFT) |
             (r300_translate_stencil_op(state->stencil[0].fail_op) <<
@@ -601,15 +605,15 @@ static void*
             (r300_translate_stencil_op(state->stencil[0].zfail_op) <<
                 R300_S_FRONT_ZFAIL_OP_SHIFT);
 
-        dsa->stencil_ref_mask =
+        stencil_ref_mask =
                 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |
                 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
 
         if (state->stencil[1].enabled) {
             dsa->two_sided = TRUE;
 
-            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
-            dsa->z_stencil_control |=
+            z_buffer_control |= R300_STENCIL_FRONT_BACK;
+            z_stencil_control |=
             (r300_translate_depth_stencil_function(state->stencil[1].func) <<
                 R300_S_BACK_FUNC_SHIFT) |
             (r300_translate_stencil_op(state->stencil[1].fail_op) <<
@@ -619,12 +623,12 @@ static void*
             (r300_translate_stencil_op(state->stencil[1].zfail_op) <<
                 R300_S_BACK_ZFAIL_OP_SHIFT);
 
-            dsa->stencil_ref_bf =
+            stencil_ref_bf =
                 (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
                 (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
 
-            if (caps->is_r500) {
-                dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
+            if (is_r500) {
+                z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
             } else {
                 dsa->two_sided_stencil_ref =
                   (state->stencil[0].valuemask != state->stencil[1].valuemask ||
@@ -640,53 +644,25 @@ static void*
             R300_FG_ALPHA_FUNC_ENABLE;
 
         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) {
-            dsa->alpha_function_fp16 = dsa->alpha_function |
-                                       R500_FG_ALPHA_FUNC_FP16_ENABLE;
-            dsa->alpha_function |= R500_FG_ALPHA_FUNC_8BIT;
-        }
+        alpha_value_fp16 = util_float_to_half(state->alpha.ref_value);
     }
 
-    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);
+    BEGIN_CB(&dsa->cb_begin, 8);
     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);
+    OUT_CB(z_buffer_control);
+    OUT_CB(z_stencil_control);
+    OUT_CB(stencil_ref_mask);
+    OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, stencil_ref_bf);
+    OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16);
     END_CB;
 
-    BEGIN_CB(dsa->cb_fp16_zb_no_readwrite, 10);
-    OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16);
+    BEGIN_CB(dsa->cb_zb_no_readwrite, 8);
     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);
+    OUT_CB_REG(R500_FG_ALPHA_VALUE, alpha_value_fp16);
     END_CB;
 
     return (void*)dsa;