Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / r300 / r300_emit.c
index 2ea9fab015de316deea8e87bfe9443c0df2f110f..badbf3715c77536642c37af8eab21b04635ce173 100644 (file)
@@ -587,8 +587,11 @@ void r300_emit_rs_state(struct r300_context* r300, void* state)
     float scale, offset;
     CS_LOCALS(r300);
 
-    BEGIN_CS(18 + (rs->polygon_offset_enable ? 5 : 0));
+    BEGIN_CS(20 + (rs->polygon_offset_enable ? 5 : 0));
     OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
+
+    OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config);
+
     OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
     OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
     OUT_CS(rs->point_minmax);
@@ -683,6 +686,22 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state)
         maxy = MIN2(maxy, scissor->maxy);
     }
 
+    /* Special case for zero-area scissor.
+     *
+     * We can't allow the variables maxx and maxy to be zero because they are
+     * subtracted from later in the code, which would cause emitting ~0 and
+     * making the kernel checker angry.
+     *
+     * Let's consider we change maxx and maxy to 1, which is effectively
+     * a one-pixel area. We must then change minx and miny to a number which is
+     * greater than 1 to get the zero area back. */
+    if (!maxx || !maxy) {
+        minx = 2;
+        miny = 2;
+        maxx = 1;
+        maxy = 1;
+    }
+
     if (r300screen->caps->is_r500) {
         top_left =
             (minx << R300_SCISSORS_X_SHIFT) |
@@ -753,22 +772,6 @@ void r300_emit_texture(struct r300_context* r300,
     END_CS;
 }
 
-static boolean r300_validate_aos(struct r300_context *r300)
-{
-    struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
-    struct pipe_vertex_element *velem = r300->vertex_element;
-    int i;
-
-    /* Check if formats and strides are aligned to the size of DWORD. */
-    for (i = 0; i < r300->vertex_element_count; i++) {
-        if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
-            util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
-            return FALSE;
-        }
-    }
-    return TRUE;
-}
-
 void r300_emit_aos(struct r300_context* r300, unsigned offset)
 {
     struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
@@ -778,12 +781,6 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
     unsigned packet_size = (aos_count * 3 + 1) / 2;
     CS_LOCALS(r300);
 
-    /* XXX Move this checking to a more approriate place. */
-    if (!r300_validate_aos(r300)) {
-        /* XXX We should fallback using Draw. */
-        assert(0);
-    }
-
     BEGIN_CS(2 + packet_size + aos_count * 2);
     OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
     OUT_CS(aos_count);
@@ -1011,32 +1008,12 @@ static void r300_flush_pvs(struct r300_context* r300)
     END_CS;
 }
 
-/* Emit all dirty state. */
-void r300_emit_dirty_state(struct r300_context* r300)
+void r300_emit_buffer_validate(struct r300_context *r300)
 {
-    struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct r300_texture* tex;
-    struct r300_atom* atom;
-    unsigned i, dwords = 1024;
-    int dirty_tex = 0;
+    unsigned i;
     boolean invalid = FALSE;
 
-    /* Check the required number of dwords against the space remaining in the
-     * current CS object. If we need more, then flush. */
-
-    foreach(atom, &r300->atom_list) {
-        if (atom->dirty || atom->always_dirty) {
-            dwords += atom->size;
-        }
-    }
-
-    /* Make sure we have at least 2*1024 spare dwords. */
-    /* XXX It would be nice to know the number of dwords we really need to
-     * XXX emit. */
-    if (!r300->winsys->check_cs(r300->winsys, dwords)) {
-        r300->context.flush(&r300->context, 0, NULL);
-    }
-
     /* Clean out BOs. */
     r300->winsys->reset_bos(r300->winsys);
 
@@ -1100,6 +1077,31 @@ validate:
         invalid = TRUE;
         goto validate;
     }
+}
+
+/* Emit all dirty state. */
+void r300_emit_dirty_state(struct r300_context* r300)
+{
+    struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    struct r300_atom* atom;
+    unsigned i, dwords = 1024;
+    int dirty_tex = 0;
+
+    /* Check the required number of dwords against the space remaining in the
+     * current CS object. If we need more, then flush. */
+
+    foreach(atom, &r300->atom_list) {
+        if (atom->dirty || atom->always_dirty) {
+            dwords += atom->size;
+        }
+    }
+
+    /* Make sure we have at least 2*1024 spare dwords. */
+    /* XXX It would be nice to know the number of dwords we really need to
+     * XXX emit. */
+    while (!r300->winsys->check_cs(r300->winsys, dwords)) {
+        r300->context.flush(&r300->context, 0, NULL);
+    }
 
     if (r300->dirty_state & R300_NEW_QUERY) {
         r300_emit_query_start(r300);