diff options
author | Marek Olšák <maraeo@gmail.com> | 2010-05-14 18:33:14 +0200 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2010-05-14 19:00:55 +0200 |
commit | 93c997a9146e0b50186df684f4847fb0124ada11 (patch) | |
tree | 8b3a220c71069e8861c5dfc5e35ef4ea0c1ee781 | |
parent | fc11653c2befa60358ca8661c6c6168db01824a9 (diff) |
r300g: do not abort if a constant buffer is too large
What else can we do with misbehaving apps?
-rw-r--r-- | 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 fd8480fa71..3fd326a63f 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) |