r300g: don't render if everything is culled by scissoring
authorMarek Olšák <maraeo@gmail.com>
Sat, 5 Dec 2009 19:39:11 +0000 (20:39 +0100)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Sun, 6 Dec 2009 09:13:37 +0000 (01:13 -0800)
Otherwise a CS is refused by kernel 2.6.31 (and maybe all later
versions, not sure).

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

index 23ea32c57ed90e60739f26ac9cf8edfa62c8796a..0be190392a53fae0825d65b466c13883a7e30d12 100644 (file)
@@ -101,6 +101,9 @@ struct r300_sampler_state {
 struct r300_scissor_regs {
     uint32_t top_left;     /* R300_SC_SCISSORS_TL: 0x43e0 */
     uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+
+    /* Whether everything is culled by scissoring. */
+    boolean empty_area;
 };
 
 struct r300_scissor_state {
index 4c5fb405c6a6898c66fe468fe4dba37fcfb1d559..35b335df6a1640100efc3ea3c41c5b590ecdb1dd 100644 (file)
@@ -70,6 +70,12 @@ uint32_t r300_translate_primitive(unsigned prim)
     }
 }
 
+static boolean r300_nothing_to_draw(struct r300_context *r300)
+{
+    return r300->rs_state->rs.scissor &&
+           r300->scissor_state->scissor.empty_area;
+}
+
 static void r300_emit_draw_arrays(struct r300_context *r300,
                                   unsigned mode,
                                   unsigned count)
@@ -173,10 +179,15 @@ boolean r300_draw_range_elements(struct pipe_context* pipe,
         return FALSE;
     }
 
+
     if (count > 65535) {
         return FALSE;
     }
 
+    if (r300_nothing_to_draw(r300)) {
+        return TRUE;
+    }
+
     r300_update_derived_state(r300);
 
     if (!r300_setup_vertex_buffers(r300)) {
@@ -218,6 +229,10 @@ boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
         return FALSE;
     }
 
+    if (r300_nothing_to_draw(r300)) {
+        return TRUE;
+    }
+
     r300_update_derived_state(r300);
 
     if (!r300_setup_vertex_buffers(r300)) {
@@ -251,6 +266,10 @@ boolean r300_swtcl_draw_arrays(struct pipe_context* pipe,
         return FALSE;
     }
 
+    if (r300_nothing_to_draw(r300)) {
+        return TRUE;
+    }
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         void* buf = pipe_buffer_map(pipe->screen,
                                     r300->vertex_buffer[i].buffer,
@@ -292,6 +311,10 @@ boolean r300_swtcl_draw_range_elements(struct pipe_context* pipe,
         return FALSE;
     }
 
+    if (r300_nothing_to_draw(r300)) {
+        return TRUE;
+    }
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         void* buf = pipe_buffer_map(pipe->screen,
                                     r300->vertex_buffer[i].buffer,
index d3233557ceaab6a0fec2a668fdd34d70a1878794..8ef0b3b268a2231edf32473fb015e66540c0813b 100644 (file)
@@ -309,6 +309,9 @@ static void r300_set_scissor_regs(const struct pipe_scissor_state* state,
             (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
             (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
     }
+
+    scissor->empty_area = state->minx >= state->maxx ||
+                          state->miny >= state->maxy;
 }
 
 static void