Mesa (master): r300g: do not abort if a constant buffer is too large

Marek Olšák mareko at kemper.freedesktop.org
Fri May 14 17:02:02 UTC 2010


Module: Mesa
Branch: master
Commit: 93c997a9146e0b50186df684f4847fb0124ada11
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=93c997a9146e0b50186df684f4847fb0124ada11

Author: Marek Olšák <maraeo at gmail.com>
Date:   Fri May 14 18:33:14 2010 +0200

r300g: do not abort if a constant buffer is too large

What else can we do with misbehaving apps?

---

 src/gallium/drivers/r300/r300_state.c |   32 ++++++++++++++++++--------------
 1 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index fd8480f..3fd326a 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1499,7 +1499,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     struct r300_constant_buffer *cbuf;
     struct pipe_transfer *tr;
     void *mapped;
-    int max_size = 0;
+    int max_size = 0, max_size_bytes = 0, clamped_size = 0;
 
     switch (shader) {
         case PIPE_SHADER_VERTEX:
@@ -1518,6 +1518,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             assert(0);
             return;
     }
+    max_size_bytes = max_size * 4 * sizeof(float);
 
     if (buf == NULL || buf->width0 == 0 ||
         (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
@@ -1526,19 +1527,21 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
         return;
     }
 
-    assert((buf->width0 % 4 * sizeof(float)) == 0);
+    if (shader == PIPE_SHADER_FRAGMENT ||
+        (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {
+        assert((buf->width0 % (4 * sizeof(float))) == 0);
 
-    /* Check the size of the constant buffer. */
-    /* XXX Subtract immediates and RC_STATE_* variables. */
-    if (buf->width0 > (sizeof(float) * 4 * max_size)) {
-        fprintf(stderr, "r300: Max size of the constant buffer is "
-                      "%i*4 floats.\n", max_size);
-        abort();
-    }
+        /* Check the size of the constant buffer. */
+        /* XXX Subtract immediates and RC_STATE_* variables. */
+        if (buf->width0 > max_size_bytes) {
+            fprintf(stderr, "r300: Max size of the constant buffer is "
+                          "%i*4 floats.\n", max_size);
+        }
+        clamped_size = MIN2(buf->width0, max_size_bytes);
 
-    memcpy(cbuf->constants, mapped, buf->width0);
-    cbuf->count = buf->width0 / (4 * sizeof(float));
-    pipe_buffer_unmap(pipe, buf, tr);
+        memcpy(cbuf->constants, mapped, clamped_size);
+        cbuf->count = clamped_size / (4 * sizeof(float));
+    }
 
     if (shader == PIPE_SHADER_VERTEX) {
         if (r300->screen->caps.has_tcl) {
@@ -1548,12 +1551,13 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             r300->pvs_flush.dirty = TRUE;
         } else if (r300->draw) {
             draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
-                0, cbuf->constants,
-                buf->width0);
+                0, mapped, buf->width0);
         }
     } else if (shader == PIPE_SHADER_FRAGMENT) {
         r300->fs_constants.dirty = TRUE;
     }
+
+    pipe_buffer_unmap(pipe, buf, tr);
 }
 
 void r300_init_state_functions(struct r300_context* r300)




More information about the mesa-commit mailing list