diff options
author | Brian Paul <[email protected]> | 2013-11-13 11:26:15 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2013-11-15 10:23:48 -0700 |
commit | 79984b9928d4444665ce617a1e4551e53d415bd4 (patch) | |
tree | 0cd60d2e0db97b4a9b0abe47397e1c01bfe77052 /src | |
parent | 491d6397fcbe8eabfdd69500b91dbc6efc4dd894 (diff) |
svga: do primitive trimming in translate_indices()
The index translation code expects the number of indexes to be
consistent with the primitive type (ex: a multiple of 3 for
PIPE_PRIM_TRIANGLES). If it's not, we can write out of bounds
in the destination buffer.
Fixes failed assertions in the pipebuffer debug code found with
Piglit primitive-restart-draw-mode test.
Cc: "10.0" <[email protected]>
Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/svga/svga_draw_elements.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index fb5f1c91b29..f6603be920a 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -24,6 +24,7 @@ **********************************************************/ #include "util/u_inlines.h" +#include "util/u_prim.h" #include "indices/u_indices.h" #include "svga_cmd.h" @@ -37,17 +38,25 @@ static enum pipe_error translate_indices(struct svga_hwtnl *hwtnl, struct pipe_resource *src, - unsigned offset, unsigned nr, unsigned index_size, + unsigned offset, unsigned prim, unsigned nr, + unsigned index_size, u_translate_func translate, struct pipe_resource **out_buf) { struct pipe_context *pipe = &hwtnl->svga->pipe; struct pipe_transfer *src_transfer = NULL; struct pipe_transfer *dst_transfer = NULL; - unsigned size = index_size * nr; + unsigned size; const void *src_map = NULL; struct pipe_resource *dst = NULL; void *dst_map = NULL; + /* Need to trim vertex count to make sure we don't write too much data + * to the dst buffer in the translate() call. + */ + u_trim_pipe_prim(prim, &nr); + + size = index_size * nr; + dst = pipe_buffer_create(pipe->screen, PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STATIC, size); if (dst == NULL) @@ -180,7 +189,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, ret = translate_indices(hwtnl, index_buffer, start * index_size, - gen_nr, gen_size, gen_func, &gen_buf); + gen_prim, gen_nr, gen_size, gen_func, &gen_buf); if (ret != PIPE_OK) goto done; |