From a192b5eeafae80f9f9e7e7e442abc5b44d583d1a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 15 Jun 2010 08:05:51 -0400 Subject: [PATCH] draw: finish the new pipeline setup Keith came up with a new way of running the pipeline which involves passing a few info structs around (for fetch, vertices and prims) and allows us to correctly handle cases where we endup with multiple primitives generated by the pipeline itself. --- src/gallium/auxiliary/draw/draw_gs.c | 41 +-- src/gallium/auxiliary/draw/draw_gs.h | 1 + src/gallium/auxiliary/draw/draw_gs_tmp.h | 22 +- src/gallium/auxiliary/draw/draw_private.h | 9 +- src/gallium/auxiliary/draw/draw_pt.h | 4 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 41 ++- .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 292 ++++++++++----------- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 54 ++-- src/gallium/auxiliary/draw/draw_pt_so_emit.c | 19 +- 9 files changed, 238 insertions(+), 245 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 787d93a..5d8fe10 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -171,9 +171,10 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader, /* Unswizzle all output results. */ - shader->emitted_primitives += num_primitives; for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) { unsigned num_verts_per_prim = machine->Primitives[prim_idx]; + shader->primitive_lengths[prim_idx + shader->emitted_primitives] = + machine->Primitives[prim_idx]; shader->emitted_vertices += num_verts_per_prim; for (j = 0; j < num_verts_per_prim; j++) { int idx = (prim_idx * num_verts_per_prim + j) * @@ -199,6 +200,7 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader, } } *p_output = output; + shader->emitted_primitives += num_primitives; } @@ -333,57 +335,60 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, struct draw_vertex_info *output_verts, struct draw_prim_info *output_prims ) { - const float (*input)[4] = input_verts->verts; + const float (*input)[4] = (const float (*)[4])input_verts->verts->data; unsigned input_stride = input_verts->vertex_size; 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 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(draw, + output_verts->count = draw_max_output_vertices(shader->draw, input_prim->prim, input_verts->count); output_verts->verts = - (struct vertex_header *)MALLOC(vert_info.vertex_size * - vert_info.count); + (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__, - count, num_in_primitives); + input_verts->count, num_in_primitives); shader->emitted_vertices = 0; shader->emitted_primitives = 0; shader->vertex_size = vertex_size; - shader->tmp_output = (float (*)[4])input_verts->verts->data; + shader->tmp_output = (float (*)[4])output_verts->verts->data; shader->in_prim_idx = 0; shader->input_vertex_stride = input_stride; shader->input = input; + if (shader->primitive_lengths) { + FREE(shader->primitive_lengths); + } + shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { machine->Consts[i] = constants[i]; } - gs_run(shader, pipe_prim, count); - - if (shader->emitted_vertices > 0) { - memcpy(output, pipeline_verts->data, - shader->info.num_outputs * 4 * sizeof(float) + - vertex_size * (shader->emitted_vertices -1)); - } + gs_run(shader, input_prim, input_verts, output_prims, output_verts); - - /* Update prim_info: + /* Update prim_info: */ output_prims->linear = TRUE; output_prims->elts = NULL; - output_prims->primitive_lengths = machine->foo; - output_prims->primitive_count = machine->bar; + output_prims->start = 0; + output_prims->prim = shader->output_primitive; + output_prims->primitive_lengths = shader->primitive_lengths; + output_prims->primitive_count = shader->emitted_primitives; return shader->emitted_vertices; } diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 2374b12..2cb6348 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -54,6 +54,7 @@ struct draw_geometry_shader { unsigned input_primitive; unsigned output_primitive; + unsigned *primitive_lengths; unsigned emitted_vertices; unsigned emitted_primitives; diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h index eb4a313..ded1c60 100644 --- a/src/gallium/auxiliary/draw/draw_gs_tmp.h +++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h @@ -1,18 +1,22 @@ static void FUNC( struct draw_geometry_shader *shader, - unsigned pipe_prim, - unsigned count ) + const struct draw_prim_info *input_prims, + const struct draw_vertex_info *input_verts, + struct draw_prim_info *output_prims, + struct draw_vertex_info *output_verts) { struct draw_context *draw = shader->draw; boolean flatfirst = (draw->rasterizer->flatshade && draw->rasterizer->flatshade_first); unsigned i; + unsigned count = input_prims->count; if (0) debug_printf("%s %d\n", __FUNCTION__, count); + debug_assert(input_prims->primitive_count == 1); - switch (pipe_prim) { + switch (input_prims->prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i++) { POINT( shader, i + 0 ); @@ -93,16 +97,6 @@ static void FUNC( struct draw_geometry_shader *shader, /* These bitflags look a little odd because we submit the * vertices as (1,2,0) to satisfy flatshade requirements. */ - ushort edge_next, edge_finish; - - if (flatfirst) { - edge_next = DRAW_PIPE_EDGE_FLAG_2; - edge_finish = DRAW_PIPE_EDGE_FLAG_0; - } - else { - edge_next = DRAW_PIPE_EDGE_FLAG_0; - edge_finish = DRAW_PIPE_EDGE_FLAG_1; - } for (i = 0; i+2 < count; i++) { @@ -117,7 +111,7 @@ static void FUNC( struct draw_geometry_shader *shader, break; default: - assert(0); + debug_assert(!"Unsupported primitive in geometry shader"); break; } } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c6dc734..e9c9402 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -266,15 +266,11 @@ struct draw_context }; - - struct draw_fetch_info { boolean linear; unsigned start; - void *elts; + const unsigned *elts; unsigned count; - - }; struct draw_vertex_info { @@ -284,12 +280,11 @@ struct draw_vertex_info { unsigned count; }; - struct draw_prim_info { boolean linear; unsigned start; - ushort *elts; + const ushort *elts; unsigned count; unsigned prim; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 821a73f..739420f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -223,9 +223,7 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ); struct pt_post_vs; boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, - struct vertex_header *pipeline_verts, - unsigned stride, - unsigned count ); + struct draw_vertex_info *info ); void draw_pt_post_vs_prepare( struct pt_post_vs *pvs, boolean bypass_clipping, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 4e39d55..599c495 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -139,7 +139,7 @@ static void fetch( struct pt_fetch *fetch, } else { draw_pt_fetch_run( fetch, - fetch_info->elts, + fetch_info->elts, fetch_info->count, output ); } @@ -207,12 +207,14 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, struct draw_vertex_info vs_vert_info; struct draw_vertex_info gs_vert_info; struct draw_vertex_info *vert_info; + unsigned opt = fpme->opt; fetched_vert_info.count = fetch_info->count; fetched_vert_info.vertex_size = fpme->vertex_size; + fetched_vert_info.stride = fpme->vertex_size; fetched_vert_info.verts = - (struct vertex_header *)MALLOC(fetched_vert_info.vertex_size * - fetch_info->count); + (struct vertex_header *)MALLOC(fpme->vertex_size * + align(fetch_info->count, 4)); if (!fetched_vert_info.verts) { assert(0); return; @@ -230,7 +232,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, /* Run the shader, note that this overwrites the data[] parts of * the pipeline verts. */ - if (fpme->opt & PT_SHADE) { + if (fpme->opt & PT_SHADE) { draw_vertex_shader_run(vshader, draw->pt.user.vs_constants, vert_info, @@ -247,8 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, prim_info, &gs_vert_info, &gs_prim_info); - - + FREE(vert_info->verts); vert_info = &gs_vert_info; prim_info = &gs_prim_info; @@ -273,7 +274,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { - pipeline( fpme->draw, + pipeline( fpme, vert_info, prim_info ); } @@ -282,7 +283,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, vert_info, prim_info ); } - + FREE(vert_info->verts); } static void fetch_pipeline_run( struct draw_pt_middle_end *middle, @@ -291,6 +292,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, const ushort *draw_elts, unsigned draw_count ) { + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_fetch_info fetch_info; struct draw_prim_info prim_info; @@ -303,6 +305,9 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, prim_info.start = 0; prim_info.count = draw_count; prim_info.elts = draw_elts; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &draw_count; fetch_pipeline_generic( middle, &fetch_info, &prim_info ); } @@ -312,6 +317,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, unsigned start, unsigned count) { + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_fetch_info fetch_info; struct draw_prim_info prim_info; @@ -324,6 +330,9 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, prim_info.start = 0; prim_info.count = count; prim_info.elts = NULL; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &count; fetch_pipeline_generic( middle, &fetch_info, &prim_info ); } @@ -331,11 +340,12 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, - unsigned start, - unsigned count, - const ushort *draw_elts, - unsigned draw_count ) + unsigned start, + unsigned count, + const ushort *draw_elts, + unsigned draw_count ) { + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_fetch_info fetch_info; struct draw_prim_info prim_info; @@ -348,8 +358,13 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle prim_info.start = 0; prim_info.count = draw_count; prim_info.elts = draw_elts; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &draw_count; fetch_pipeline_generic( middle, &fetch_info, &prim_info ); + + return TRUE; } @@ -403,7 +418,7 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * goto fail; fpme->emit = draw_pt_emit_create( draw ); - if (!fpme->emit) + if (!fpme->emit) goto fail; fpme->so_emit = draw_pt_so_emit_create( draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 5f6d238..65a9d4e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -28,6 +28,7 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "draw/draw_context.h" +#include "draw/draw_gs.h" #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" @@ -150,72 +151,142 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, } +static void pipeline(struct llvm_middle_end *llvm, + const struct draw_vertex_info *vert_info, + const struct draw_prim_info *prim_info) +{ + if (prim_info->linear) + draw_pipeline_run_linear( llvm->draw, + vert_info, + prim_info); + else + draw_pipeline_run( llvm->draw, + vert_info, + prim_info ); +} -static void llvm_middle_end_run( struct draw_pt_middle_end *middle, - const unsigned *fetch_elts, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) +static void emit(struct pt_emit *emit, + const struct draw_vertex_info *vert_info, + const struct draw_prim_info *prim_info) +{ + if (prim_info->linear) { + draw_pt_emit_linear(emit, vert_info, prim_info); + } + else { + draw_pt_emit(emit, vert_info, prim_info); + } +} + +static void +llvm_pipeline_generic( struct draw_pt_middle_end *middle, + const struct draw_fetch_info *fetch_info, + const struct draw_prim_info *prim_info ) { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; struct draw_context *draw = fpme->draw; + struct draw_geometry_shader *gshader = draw->gs.geometry_shader; + struct draw_prim_info gs_prim_info; + struct draw_vertex_info llvm_vert_info; + struct draw_vertex_info gs_vert_info; + struct draw_vertex_info *vert_info; unsigned opt = fpme->opt; - unsigned alloc_count = align( fetch_count, 4 ); - struct vertex_header *pipeline_verts = - (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); - - if (!pipeline_verts) { - /* Not much we can do here - just skip the rendering. - */ + llvm_vert_info.count = fetch_info->count; + llvm_vert_info.vertex_size = fpme->vertex_size; + llvm_vert_info.stride = fpme->vertex_size; + llvm_vert_info.verts = + (struct vertex_header *)MALLOC(fpme->vertex_size * + align(fetch_info->count, 4)); + if (!llvm_vert_info.verts) { assert(0); return; } - fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, - pipeline_verts, - (const char **)draw->pt.user.vbuffer, - fetch_elts, - fetch_count, - fpme->vertex_size, - draw->pt.vertex_buffer ); + if (fetch_info->linear) + fpme->current_variant->jit_func( &fpme->llvm->jit_context, + llvm_vert_info.verts, + (const char **)draw->pt.user.vbuffer, + fetch_info->start, + fetch_info->count, + fpme->vertex_size, + draw->pt.vertex_buffer ); + else + fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, + llvm_vert_info.verts, + (const char **)draw->pt.user.vbuffer, + fetch_info->elts, + fetch_info->count, + fpme->vertex_size, + draw->pt.vertex_buffer); + + /* Finished with fetch and vs: + */ + fetch_info = NULL; + vert_info = &llvm_vert_info; + + + if ((opt & PT_SHADE) && gshader) { + draw_geometry_shader_run(gshader, + draw->pt.user.gs_constants, + vert_info, + prim_info, + &gs_vert_info, + &gs_prim_info); + + FREE(vert_info->verts); + vert_info = &gs_vert_info; + prim_info = &gs_prim_info; + } /* stream output needs to be done before clipping */ draw_pt_so_emit( fpme->so_emit, - (const float (*)[4])pipeline_verts->data, - fetch_count, - fpme->vertex_size ); - - if (draw_pt_post_vs_run( fpme->post_vs, - pipeline_verts, - fetch_count, - fpme->vertex_size )) - { + vert_info, + prim_info ); + + if (draw_pt_post_vs_run( fpme->post_vs, vert_info )) { opt |= PT_PIPELINE; } /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { - draw_pipeline_run( fpme->draw, - fpme->output_prim, - pipeline_verts, - fetch_count, - fpme->vertex_size, - draw_elts, - draw_count ); + pipeline( fpme, + vert_info, + prim_info ); } else { - draw_pt_emit( fpme->emit, - (const float (*)[4])pipeline_verts->data, - fetch_count, - fpme->vertex_size, - draw_elts, - draw_count ); + emit( fpme->emit, + vert_info, + prim_info ); } + FREE(vert_info->verts); +} - FREE(pipeline_verts); +static void llvm_middle_end_run( struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; + struct draw_fetch_info fetch_info; + struct draw_prim_info prim_info; + + fetch_info.linear = FALSE; + fetch_info.start = 0; + fetch_info.elts = fetch_elts; + fetch_info.count = fetch_count; + + prim_info.linear = FALSE; + prim_info.start = 0; + prim_info.count = draw_count; + prim_info.elts = draw_elts; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &draw_count; + + llvm_pipeline_generic( middle, &fetch_info, &prim_info ); } @@ -224,63 +295,23 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle, unsigned count) { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned opt = fpme->opt; - unsigned alloc_count = align( count, 4 ); - - struct vertex_header *pipeline_verts = - (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); - - if (!pipeline_verts) { - /* Not much we can do here - just skip the rendering. - */ - assert(0); - return; - } - -#if 0 - debug_printf("#### Pipeline = %p (data = %p)\n", - pipeline_verts, pipeline_verts->data); -#endif - fpme->current_variant->jit_func( &fpme->llvm->jit_context, - pipeline_verts, - (const char **)draw->pt.user.vbuffer, - start, - count, - fpme->vertex_size, - draw->pt.vertex_buffer ); - - /* stream output needs to be done before clipping */ - draw_pt_so_emit( fpme->so_emit, - (const float (*)[4])pipeline_verts->data, - count, - fpme->vertex_size ); - - if (draw_pt_post_vs_run( fpme->post_vs, - pipeline_verts, - count, - fpme->vertex_size )) - { - opt |= PT_PIPELINE; - } - - /* Do we need to run the pipeline? - */ - if (opt & PT_PIPELINE) { - draw_pipeline_run_linear( fpme->draw, - fpme->output_prim, - pipeline_verts, - count, - fpme->vertex_size); - } - else { - draw_pt_emit_linear( fpme->emit, - (const float (*)[4])pipeline_verts->data, - fpme->vertex_size, - count ); - } - - FREE(pipeline_verts); + struct draw_fetch_info fetch_info; + struct draw_prim_info prim_info; + + fetch_info.linear = TRUE; + fetch_info.start = start; + fetch_info.count = count; + fetch_info.elts = NULL; + + prim_info.linear = TRUE; + prim_info.start = 0; + prim_info.count = count; + prim_info.elts = NULL; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &count; + + llvm_pipeline_generic( middle, &fetch_info, &prim_info ); } @@ -293,59 +324,24 @@ llvm_middle_end_linear_run_elts( struct draw_pt_middle_end *middle, unsigned draw_count ) { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned opt = fpme->opt; - unsigned alloc_count = align( count, 4 ); + struct draw_fetch_info fetch_info; + struct draw_prim_info prim_info; - struct vertex_header *pipeline_verts = - (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); + fetch_info.linear = TRUE; + fetch_info.start = start; + fetch_info.count = count; + fetch_info.elts = NULL; - if (!pipeline_verts) - return FALSE; - - fpme->current_variant->jit_func( &fpme->llvm->jit_context, - pipeline_verts, - (const char **)draw->pt.user.vbuffer, - start, - count, - fpme->vertex_size, - draw->pt.vertex_buffer ); - - /* stream output needs to be done before clipping */ - draw_pt_so_emit( fpme->so_emit, - (const float (*)[4])pipeline_verts->data, - count, - fpme->vertex_size ); - - if (draw_pt_post_vs_run( fpme->post_vs, - pipeline_verts, - count, - fpme->vertex_size )) - { - opt |= PT_PIPELINE; - } + prim_info.linear = FALSE; + prim_info.start = 0; + prim_info.count = draw_count; + prim_info.elts = draw_elts; + prim_info.prim = fpme->input_prim; + prim_info.primitive_count = 1; + prim_info.primitive_lengths = &draw_count; - /* Do we need to run the pipeline? - */ - if (opt & PT_PIPELINE) { - draw_pipeline_run( fpme->draw, - fpme->output_prim, - pipeline_verts, - count, - fpme->vertex_size, - draw_elts, - draw_count ); - } - else { - draw_pt_emit( fpme->emit, - (const float (*)[4])pipeline_verts->data, - count, - fpme->vertex_size, - draw_elts, - draw_count ); - } + llvm_pipeline_generic( middle, &fetch_info, &prim_info ); - FREE(pipeline_verts); return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index fd33a54..1000cc5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -36,9 +36,7 @@ struct pt_post_vs { struct draw_context *draw; boolean (*run)( struct pt_post_vs *pvs, - struct vertex_header *vertices, - unsigned count, - unsigned stride ); + struct draw_vertex_info *info ); }; @@ -92,20 +90,18 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) * instructions */ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, - struct vertex_header *vertices, - unsigned count, - unsigned stride ) + struct draw_vertex_info *info ) { - struct vertex_header *out = vertices; + struct vertex_header *out = info->verts; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; const unsigned pos = draw_current_shader_position_output(pvs->draw); unsigned clipped = 0; unsigned j; - if (0) debug_printf("%s count, %d\n", __FUNCTION__, count); + if (0) debug_printf("%s count, %d\n", __FUNCTION__, info->count); - for (j = 0; j < count; j++) { + for (j = 0; j < info->count; j++) { float *position = out->data[pos]; #if 0 @@ -143,7 +139,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, #endif } - out = (struct vertex_header *)( (char *)out + stride ); + out = (struct vertex_header *)( (char *)out + info->stride ); } return clipped != 0; @@ -153,29 +149,27 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, /* As above plus edgeflags */ -static boolean +static boolean post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs, - struct vertex_header *vertices, - unsigned count, - unsigned stride ) + struct draw_vertex_info *info) { unsigned j; boolean needpipe; - needpipe = post_vs_cliptest_viewport_gl( pvs, vertices, count, stride); + needpipe = post_vs_cliptest_viewport_gl(pvs, info); /* If present, copy edgeflag VS output into vertex header. * Otherwise, leave header as is. */ if (pvs->draw->vs.edgeflag_output) { - struct vertex_header *out = vertices; + struct vertex_header *out = info->verts; int ef = pvs->draw->vs.edgeflag_output; - for (j = 0; j < count; j++) { + for (j = 0; j < info->count; j++) { const float *edgeflag = out->data[ef]; out->edgeflag = !(edgeflag[0] != 1.0f); needpipe |= !out->edgeflag; - out = (struct vertex_header *)( (char *)out + stride ); + out = (struct vertex_header *)( (char *)out + info->stride ); } } return needpipe; @@ -187,18 +181,16 @@ post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs, /* If bypass_clipping is set, skip cliptest and rhw divide. */ static boolean post_vs_viewport( struct pt_post_vs *pvs, - struct vertex_header *vertices, - unsigned count, - unsigned stride ) + struct draw_vertex_info *info ) { - struct vertex_header *out = vertices; + struct vertex_header *out = info->verts; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; const unsigned pos = draw_current_shader_position_output(pvs->draw); unsigned j; if (0) debug_printf("%s\n", __FUNCTION__); - for (j = 0; j < count; j++) { + for (j = 0; j < info->count; j++) { float *position = out->data[pos]; /* Viewport mapping only, no cliptest/rhw divide @@ -207,9 +199,9 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs, position[1] = position[1] * scale[1] + trans[1]; position[2] = position[2] * scale[2] + trans[2]; - out = (struct vertex_header *)((char *)out + stride); + out = (struct vertex_header *)((char *)out + info->stride); } - + return FALSE; } @@ -218,20 +210,16 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs, * to do. */ static boolean post_vs_none( struct pt_post_vs *pvs, - struct vertex_header *vertices, - unsigned count, - unsigned stride ) + struct draw_vertex_info *info ) { if (0) debug_printf("%s\n", __FUNCTION__); return FALSE; } boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, - struct vertex_header *pipeline_verts, - unsigned count, - unsigned stride ) + struct draw_vertex_info *info ) { - return pvs->run( pvs, pipeline_verts, count, stride ); + return pvs->run( pvs, info ); } @@ -272,7 +260,7 @@ struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ) return NULL; pvs->draw = draw; - + return pvs; } diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index 2bdfef1..f5abb79 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -136,13 +136,14 @@ void draw_pt_so_emit( struct pt_so_emit *emit, const struct draw_vertex_info *vert_info, const struct draw_prim_info *prim_info ) { - const float (*vertex_data)[4] = vert_info->verts; + const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data; unsigned vertex_count = vert_info->count; unsigned stride = vert_info->stride; struct draw_context *draw = emit->draw; struct translate *translate = emit->translate; struct vbuf_render *render = draw->render; void *so_buffer; + unsigned start, i; if (!emit->has_so) return; @@ -168,20 +169,20 @@ void draw_pt_so_emit( struct pt_so_emit *emit, translate->set_buffer(translate, 0, vertex_data, stride, ~0); - - for (start = i = 0; - i < prim_info->primitive_count; + + for (start = i = 0; i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { unsigned count = prim_info->primitive_lengths[i]; - + if (prim_info->linear) { - translate->runXXX(translate, start, count, - draw->instance_id, so_buffer); + translate->run(translate, start, count, + draw->instance_id, so_buffer); } else { - translate->runYYY(translate, start, count, - draw->instance_id, so_buffer); + debug_assert(!"Stream output can't handle non-linear prims yet"); + translate->run(translate, start, count, + draw->instance_id, so_buffer); } } -- 2.7.4