r300g: consolidate common render code into one function
authorMarek Olšák <maraeo@gmail.com>
Fri, 7 May 2010 19:46:09 +0000 (21:46 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 8 May 2010 21:03:44 +0000 (23:03 +0200)
This reduces redundant code by moving:
- CS space reservation
- buffer validation
- dirty state emission
- index bias emission
- AOS emission
into r300_prepare_for_rendering.

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

index e9c8fcdc157baffdc5d6a72e86293498fc64259f..2e91a5b26598cf5e0608a0df908e1f18cf4e86e9 100644 (file)
@@ -331,8 +331,7 @@ struct r300_context {
 
     void (*emit_draw_elements)(
             struct r300_context *r300, struct pipe_resource* indexBuffer,
-            unsigned indexSize, int indexBias,
-            unsigned minIndex, unsigned maxIndex,
+            unsigned indexSize, unsigned minIndex, unsigned maxIndex,
             unsigned mode, unsigned start, unsigned count);
 
 
index 23bbc6a99c86151f23abe6f4fb9d09bea6b76787..f3be274d76cb6748d84bde8a63639d0c1c7e8d18 100644 (file)
@@ -1152,8 +1152,6 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300)
         }
     }
 
-    /* emit_query_end is not atomized. */
-    dwords += 26;
     /* let's reserve some more, just in case */
     dwords += 32;
 
index d04c8ea81e6d24d4a29f396b673ff27cc857832c..4d7699793e367e5952ed8b95a5005fbcc6b27bbe 100644 (file)
@@ -114,16 +114,79 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
     return color_control;
 }
 
+static void r500_emit_index_offset(struct r300_context *r300, int index_bias)
+{
+    CS_LOCALS(r300);
+
+    if (r300->screen->caps.is_r500 &&
+        r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
+        BEGIN_CS(2);
+        OUT_CS_REG(R500_VAP_INDEX_OFFSET,
+                   (index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0));
+        END_CS;
+    } else {
+        if (index_bias) {
+            fprintf(stderr, "r300: Non-zero index bias is unsupported "
+                            "on this hardware.\n");
+            assert(0);
+        }
+    }
+}
+
+enum r300_prepare_flags {
+    PREP_FIRST_DRAW     = (1 << 0),
+    PREP_VALIDATE_VBOS  = (1 << 1),
+    PREP_EMIT_AOS       = (1 << 2),
+    PREP_INDEXED        = (1 << 3)
+};
+
 /* Check if the requested number of dwords is available in the CS and
- * if not, flush. Return TRUE if the flush occured. */
-static boolean r300_reserve_cs_space(struct r300_context *r300,
-                                     unsigned dwords)
+ * if not, flush. Then validate buffers and emit dirty state.
+ * Return TRUE if flush occured. */
+static void r300_prepare_for_rendering(struct r300_context *r300,
+                                       enum r300_prepare_flags flags,
+                                       struct pipe_resource *index_buffer,
+                                       unsigned cs_dwords,
+                                       unsigned aos_offset,
+                                       int index_bias)
 {
-    if (!r300->rws->check_cs(r300->rws, dwords)) {
+    boolean flushed = FALSE;
+    boolean first_draw = flags & PREP_FIRST_DRAW;
+    boolean emit_aos = flags & PREP_EMIT_AOS;
+
+    /* Stencil ref fallback. */
+    if (r300->stencil_ref_bf_fallback) {
+        cs_dwords = cs_dwords * 2 + 10;
+    }
+
+    /* Add dirty state, index offset, and AOS. */
+    if (first_draw) {
+        cs_dwords += r300_get_num_dirty_dwords(r300);
+
+        if (r300->screen->caps.is_r500)
+            cs_dwords += 2; /* emit_index_offset */
+
+        if (emit_aos)
+            cs_dwords += 55; /* emit_aos */
+    }
+
+    /* Emitted in flush. */
+    cs_dwords += 26; /* emit_query_end */
+
+    /* Reserve requested CS space. */
+    if (!r300->rws->check_cs(r300->rws, cs_dwords)) {
         r300->context.flush(&r300->context, 0, NULL);
-        return TRUE;
+        flushed = TRUE;
+    }
+
+    /* Validate buffers and emit dirty state if needed. */
+    if (first_draw || flushed) {
+        r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, index_buffer);
+        r300_emit_dirty_state(r300);
+        r500_emit_index_offset(r300, index_bias);
+        if (emit_aos)
+            r300_emit_aos(r300, aos_offset, flags & PREP_INDEXED);
     }
-    return FALSE;
 }
 
 static boolean immd_is_good_idea(struct r300_context *r300,
@@ -166,24 +229,6 @@ static boolean immd_is_good_idea(struct r300_context *r300,
  * after resolving fallback issues (e.g. stencil ref two-sided).             *
  ****************************************************************************/
 
-static boolean r500_emit_index_offset(struct r300_context *r300, int indexBias)
-{
-    CS_LOCALS(r300);
-
-    if (r300->screen->caps.is_r500 &&
-        r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
-        BEGIN_CS(2);
-        OUT_CS_REG(R500_VAP_INDEX_OFFSET,
-                   (indexBias & 0xFFFFFF) | (indexBias < 0 ? 1<<24 : 0));
-        END_CS;
-    } else {
-        if (indexBias)
-            return FALSE; /* Can't do anything :( */
-    }
-
-    return TRUE;
-}
-
 void r500_emit_draw_arrays_immediate(struct r300_context *r300,
                                      unsigned mode,
                                      unsigned start,
@@ -235,11 +280,7 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300,
 
     dwords = 9 + count * vertex_size;
 
-    r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2 + dwords);
-    r300_emit_buffer_validate(r300, FALSE, NULL);
-    r300_emit_dirty_state(r300);
-
-    r500_emit_index_offset(r300, 0);
+    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
 
     BEGIN_CS(dwords);
     OUT_CS_REG(R300_GA_COLOR_CONTROL,
@@ -291,8 +332,6 @@ void r500_emit_draw_arrays(struct r300_context *r300,
         return;
     }
 
-    r500_emit_index_offset(r300, 0);
-
     BEGIN_CS(7 + (alt_num_verts ? 2 : 0));
     if (alt_num_verts) {
         OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
@@ -312,7 +351,6 @@ void r500_emit_draw_arrays(struct r300_context *r300,
 void r500_emit_draw_elements(struct r300_context *r300,
                              struct pipe_resource* indexBuffer,
                              unsigned indexSize,
-                             int indexBias,
                              unsigned minIndex,
                              unsigned maxIndex,
                              unsigned mode,
@@ -335,12 +373,6 @@ void r500_emit_draw_elements(struct r300_context *r300,
     DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
         count, minIndex, maxIndex);
 
-    if (!r500_emit_index_offset(r300, indexBias)) {
-        fprintf(stderr, "r300: Got a non-zero index bias, "
-                "refusing to render.\n");
-        return;
-    }
-
     BEGIN_CS(13 + (alt_num_verts ? 2 : 0));
     if (alt_num_verts) {
         OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
@@ -457,7 +489,6 @@ void r300_emit_draw_arrays(struct r300_context *r300,
 void r300_emit_draw_elements(struct r300_context *r300,
                              struct pipe_resource* indexBuffer,
                              unsigned indexSize,
-                             int indexBias,
                              unsigned minIndex,
                              unsigned maxIndex,
                              unsigned mode,
@@ -465,14 +496,14 @@ void r300_emit_draw_elements(struct r300_context *r300,
                              unsigned count)
 {
     if (!r300->stencil_ref_bf_fallback) {
-        r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+        r500_emit_draw_elements(r300, indexBuffer, indexSize,
                                 minIndex, maxIndex, mode, start, count);
     } else {
         r300_begin_stencil_ref_fallback(r300);
-        r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+        r500_emit_draw_elements(r300, indexBuffer, indexSize,
                                 minIndex, maxIndex, mode, start, count);
         r300_switch_stencil_ref_side(r300);
-        r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+        r500_emit_draw_elements(r300, indexBuffer, indexSize,
                                 minIndex, maxIndex, mode, start, count);
         r300_end_stencil_ref_fallback(r300);
     }
@@ -576,36 +607,33 @@ void r300_draw_range_elements(struct pipe_context* pipe,
     }
 
     r300_update_derived_state(r300);
-
     r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count);
 
-    /* 128 dwords for emit_aos and emit_draw_elements */
-    r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
-    r300_emit_buffer_validate(r300, TRUE, indexBuffer);
-    r300_emit_dirty_state(r300);
-    r300_emit_aos(r300, 0, TRUE);
+    /* 15 dwords for emit_draw_elements */
+    r300_prepare_for_rendering(r300,
+        PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
+        indexBuffer, 15, 0, indexBias);
 
     u_upload_flush(r300->upload_vb);
     u_upload_flush(r300->upload_ib);
     if (alt_num_verts || count <= 65535) {
-        r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+        r300->emit_draw_elements(r300, indexBuffer, indexSize,
                                  minIndex, maxIndex, mode, start, count);
     } else {
         do {
             short_count = MIN2(count, 65534);
-            r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+            r300->emit_draw_elements(r300, indexBuffer, indexSize,
                                      minIndex, maxIndex,
                                      mode, start, short_count);
 
             start += short_count;
             count -= short_count;
 
-            /* 16 spare dwords are enough for emit_draw_elements.
-             * Also reserve some space for emit_query_end. */
-            if (count && r300_reserve_cs_space(r300, 74)) {
-                r300_emit_buffer_validate(r300, TRUE, indexBuffer);
-                r300_emit_dirty_state(r300);
-                r300_emit_aos(r300, 0, TRUE);
+            /* 15 dwords for emit_draw_elements */
+            if (count) {
+                r300_prepare_for_rendering(r300,
+                    PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
+                    indexBuffer, 15, 0, indexBias);
             }
         } while (count);
     }
@@ -650,30 +678,25 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
     if (immd_is_good_idea(r300, count)) {
         r300->emit_draw_arrays_immediate(r300, mode, start, count);
     } else {
-        /* Make sure there are at least 128 spare dwords in the command buffer.
-         * (most of it being consumed by emit_aos) */
-        r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
-        r300_emit_buffer_validate(r300, TRUE, NULL);
-        r300_emit_dirty_state(r300);
+        /* 9 spare dwords for emit_draw_arrays. */
+        r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
+                               NULL, 9, start, 0);
 
         if (alt_num_verts || count <= 65535) {
-            r300_emit_aos(r300, start, FALSE);
             r300->emit_draw_arrays(r300, mode, count);
         } else {
             do {
                 short_count = MIN2(count, 65535);
-                r300_emit_aos(r300, start, FALSE);
                 r300->emit_draw_arrays(r300, mode, short_count);
 
                 start += short_count;
                 count -= short_count;
 
-                /* Again, we emit both AOS and draw_arrays so there should be
-                 * at least 128 spare dwords.
-                 * Also reserve some space for emit_query_end. */
-                if (count && r300_reserve_cs_space(r300, 186)) {
-                    r300_emit_buffer_validate(r300, TRUE, NULL);
-                    r300_emit_dirty_state(r300);
+                /* 9 spare dwords for emit_draw_arrays. */
+                if (count) {
+                    r300_prepare_for_rendering(r300,
+                        PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
+                        start, 0);
                 }
             } while (count);
         }
@@ -898,14 +921,10 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
 
     CS_LOCALS(r300);
 
-    r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2);
-    r300_emit_buffer_validate(r300, FALSE, NULL);
-    r300_emit_dirty_state(r300);
+    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, 2, 0, 0);
 
     DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
 
-    r500_emit_index_offset(r300, 0);
-
     BEGIN_CS(2);
     OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
     OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
@@ -924,11 +943,7 @@ static void r500_render_draw_elements(struct vbuf_render* render,
 
     CS_LOCALS(r300);
 
-    r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
-    r300_emit_buffer_validate(r300, FALSE, NULL);
-    r300_emit_dirty_state(r300);
-
-    r500_emit_index_offset(r300, 0);
+    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
 
     BEGIN_CS(dwords);
     OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
index 4e78914c1bacd6f67ddecaeff6b4e9533aa05b60..71dea218be6ee72812c6daf0b5d070ef8c7508c6 100644 (file)
@@ -35,7 +35,6 @@ void r500_emit_draw_arrays(struct r300_context *r300,
 void r500_emit_draw_elements(struct r300_context *r300,
                              struct pipe_resource* indexBuffer,
                              unsigned indexSize,
-                             int indexBias,
                              unsigned minIndex,
                              unsigned maxIndex,
                              unsigned mode,
@@ -54,7 +53,6 @@ void r300_emit_draw_arrays(struct r300_context *r300,
 void r300_emit_draw_elements(struct r300_context *r300,
                              struct pipe_resource* indexBuffer,
                              unsigned indexSize,
-                             int indexBias,
                              unsigned minIndex,
                              unsigned maxIndex,
                              unsigned mode,