diff options
author | Zack Rusin <[email protected]> | 2010-06-15 16:09:30 -0400 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2010-06-15 16:10:18 -0400 |
commit | 215e10ac2615359065cc264c68f08f39533bafd4 (patch) | |
tree | d715b6183f9929726bf76d1a1eabd1073ddfc111 | |
parent | 80dfec3e53fd5b5c8c31fb16376c9910258c91b0 (diff) |
draw/gs: make sure gs works with elts and doesn't overrun the buffer
-rw-r--r-- | src/gallium/auxiliary/draw/draw_gs.c | 53 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_gs_tmp.h | 1 |
2 files changed, 43 insertions, 11 deletions
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 5d8fe10d77f..505622d138b 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -276,6 +276,11 @@ static void gs_flush(struct draw_geometry_shader *shader, out_prim_count = machine->Temps[TGSI_EXEC_TEMP_PRIMITIVE_I].xyzw[TGSI_EXEC_TEMP_PRIMITIVE_C].u[0]; +#if 0 + debug_printf("PRIM emitted prims = %d (verts=%d), cur prim count = %d\n", + shader->emitted_primitives, shader->emitted_vertices, + out_prim_count); +#endif draw_geometry_fetch_outputs(shader, out_prim_count, &shader->tmp_output); } @@ -326,7 +331,21 @@ static void gs_tri(struct draw_geometry_shader *shader, #define LINE(gs,i0,i1) gs_line(gs,i0,i1) #define POINT(gs,i0) gs_point(gs,i0) #define FUNC gs_run +#define LOCAL_VARS +#include "draw_gs_tmp.h" +#undef LOCAL_VARS +#undef FUNC + + +#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2]) +#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1]) +#define POINT(gs,i0) gs_point(gs,elts[i0]) +#define FUNC gs_run_elts +#define LOCAL_VARS \ + const ushort *elts = input_prims->elts; #include "draw_gs_tmp.h" +#undef LOCAL_VARS +#undef FUNC int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], @@ -340,28 +359,34 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, unsigned vertex_size = input_verts->vertex_size; struct tgsi_exec_machine *machine = shader->machine; unsigned int i; - unsigned num_in_primitives = u_gs_prims_for_vertices(input_prim->prim, - input_verts->count); + unsigned num_input_verts = input_prim->linear ? + input_verts->count : + input_prim->count; + unsigned num_in_primitives = + MAX2(u_gs_prims_for_vertices(input_prim->prim, num_input_verts), + u_gs_prims_for_vertices(shader->input_primitive, num_input_verts)); unsigned max_out_prims = u_gs_prims_for_vertices(shader->output_primitive, shader->max_output_vertices) * num_in_primitives; output_verts->vertex_size = input_verts->vertex_size; output_verts->stride = input_verts->vertex_size; - - output_verts->count = draw_max_output_vertices(shader->draw, - input_prim->prim, - input_verts->count); - output_verts->verts = (struct vertex_header *)MALLOC(input_verts->vertex_size * num_in_primitives * shader->max_output_vertices); - - if (0) debug_printf("%s count = %d (prims = %d)\n", __FUNCTION__, - input_verts->count, num_in_primitives); +#if 0 + debug_printf("%s count = %d (in prims # = %d)\n", + __FUNCTION__, num_input_verts, num_in_primitives); + debug_printf("\tlinear = %d, prim_info->count = %d\n", + input_prim->linear, input_prim->count); + debug_printf("\tprimt pipe = %d, shader in = %d, shader out = %d, max out = %d\n", + input_prim->prim, shader->input_primitive, + shader->output_primitive, + shader->max_output_vertices); +#endif shader->emitted_vertices = 0; shader->emitted_primitives = 0; @@ -379,7 +404,12 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, machine->Consts[i] = constants[i]; } - gs_run(shader, input_prim, input_verts, output_prims, output_verts); + if (input_prim->linear) + gs_run(shader, input_prim, input_verts, + output_prims, output_verts); + else + gs_run_elts(shader, input_prim, input_verts, + output_prims, output_verts); /* Update prim_info: */ @@ -389,6 +419,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, output_prims->prim = shader->output_primitive; output_prims->primitive_lengths = shader->primitive_lengths; output_prims->primitive_count = shader->emitted_primitives; + output_verts->count = shader->emitted_vertices; return shader->emitted_vertices; } diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h index ded1c6012eb..61ca347007f 100644 --- a/src/gallium/auxiliary/draw/draw_gs_tmp.h +++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h @@ -11,6 +11,7 @@ static void FUNC( struct draw_geometry_shader *shader, draw->rasterizer->flatshade_first); unsigned i; unsigned count = input_prims->count; + LOCAL_VARS if (0) debug_printf("%s %d\n", __FUNCTION__, count); |