X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fdraw%2Fdraw_pt_fetch_shade_pipeline.c;h=afc146c602309a03d11f014bd86b1cb7fbfa7abc;hb=d4ef0f6c67aefe06d8dd647acf8d9005df39a709;hp=56b69354b21503ae82034d9f310036a132aab063;hpb=9b346f83a7b672e913a7bb6a089d5dbd7fbdce06;p=mesa.git 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 56b69354b21..afc146c6023 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -40,18 +40,21 @@ struct fetch_pipeline_middle_end { struct draw_context *draw; struct pt_emit *emit; + struct pt_so_emit *so_emit; struct pt_fetch *fetch; struct pt_post_vs *post_vs; unsigned vertex_data_offset; unsigned vertex_size; - unsigned prim; + unsigned input_prim; + unsigned output_prim; unsigned opt; }; static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim, + unsigned in_prim, + unsigned out_prim, unsigned opt, unsigned *max_vertices ) { @@ -76,7 +79,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, } } - fpme->prim = prim; + fpme->input_prim = in_prim; + fpme->output_prim = out_prim; fpme->opt = opt; /* Always leave room for the vertex header whether we need it or @@ -96,14 +100,15 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, */ draw_pt_post_vs_prepare( fpme->post_vs, (boolean)draw->bypass_clipping, - (boolean)(draw->identity_viewport || - draw->rasterizer->bypass_vs_clip_and_viewport), + (boolean)draw->identity_viewport, (boolean)draw->rasterizer->gl_rasterization_rules, - (draw->vs.edgeflag_output ? true : false) ); + (draw->vs.edgeflag_output ? true : false) ); + + draw_pt_so_emit_prepare( fpme->so_emit, out_prim ); if (!(opt & PT_PIPELINE)) { - draw_pt_emit_prepare( fpme->emit, - prim, + draw_pt_emit_prepare( fpme->emit, + out_prim, max_vertices ); *max_vertices = MAX2( *max_vertices, @@ -134,9 +139,15 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_vertex_shader *vshader = draw->vs.vertex_shader; struct draw_geometry_shader *gshader = draw->gs.geometry_shader; unsigned opt = fpme->opt; + struct vertex_header *pipeline_verts; unsigned alloc_count = align( fetch_count, 4 ); - struct vertex_header *pipeline_verts = + if (draw->gs.geometry_shader && + draw->gs.geometry_shader->max_output_vertices > fetch_count) { + alloc_count = align(draw->gs.geometry_shader->max_output_vertices, 4); + } + + pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); if (!pipeline_verts) { @@ -154,9 +165,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, eg if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { @@ -168,15 +177,22 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, fpme->vertex_size, fpme->vertex_size); if (gshader) - draw_geometry_shader_run(gshader, - (const float (*)[4])pipeline_verts->data, - ( float (*)[4])pipeline_verts->data, - draw->pt.user.gs_constants, - fetch_count, - fpme->vertex_size, - fpme->vertex_size); + fetch_count = + draw_geometry_shader_run(gshader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + draw->pt.user.gs_constants, + fetch_count, + fpme->vertex_size, + fpme->vertex_size); } + /* 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, @@ -189,7 +205,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, */ if (opt & PT_PIPELINE) { draw_pipeline_run( fpme->draw, - fpme->prim, + fpme->output_prim, pipeline_verts, fetch_count, fpme->vertex_size, @@ -219,9 +235,14 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, struct draw_vertex_shader *shader = draw->vs.vertex_shader; struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader; unsigned opt = fpme->opt; + struct vertex_header *pipeline_verts; unsigned alloc_count = align( count, 4 ); - struct vertex_header *pipeline_verts = + if (geometry_shader && geometry_shader->max_output_vertices > count) { + alloc_count = align(geometry_shader->max_output_vertices, 4); + } + + pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); if (!pipeline_verts) { @@ -239,9 +260,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, ie if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { @@ -254,15 +273,21 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, fpme->vertex_size); if (geometry_shader) - draw_geometry_shader_run(geometry_shader, - (const float (*)[4])pipeline_verts->data, - ( float (*)[4])pipeline_verts->data, - draw->pt.user.gs_constants, - count, - fpme->vertex_size, - fpme->vertex_size); + count = draw_geometry_shader_run(geometry_shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + draw->pt.user.gs_constants, + count, + fpme->vertex_size, + fpme->vertex_size); } + /* 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, @@ -275,7 +300,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle, */ if (opt & PT_PIPELINE) { draw_pipeline_run_linear( fpme->draw, - fpme->prim, + fpme->output_prim, pipeline_verts, count, fpme->vertex_size); @@ -303,12 +328,18 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle struct draw_vertex_shader *shader = draw->vs.vertex_shader; struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader; unsigned opt = fpme->opt; + struct vertex_header *pipeline_verts; unsigned alloc_count = align( count, 4 ); - struct vertex_header *pipeline_verts = + if (draw->gs.geometry_shader && + draw->gs.geometry_shader->max_output_vertices > count) { + alloc_count = align(draw->gs.geometry_shader->max_output_vertices, 4); + } + + pipeline_verts = (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count); - if (!pipeline_verts) + if (!pipeline_verts) return FALSE; /* Fetch into our vertex buffer @@ -319,9 +350,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of - * the pipeline verts. If there is no shader, ie if - * bypass_vs_clip_and_viewport, then the inputs == outputs, and are - * already in the correct place. + * the pipeline verts. */ if (opt & PT_SHADE) { @@ -334,15 +363,21 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle fpme->vertex_size); if (geometry_shader) - draw_geometry_shader_run(geometry_shader, - (const float (*)[4])pipeline_verts->data, - ( float (*)[4])pipeline_verts->data, - draw->pt.user.gs_constants, - count, - fpme->vertex_size, - fpme->vertex_size); + count = draw_geometry_shader_run(geometry_shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + draw->pt.user.gs_constants, + count, + fpme->vertex_size, + fpme->vertex_size); } + /* 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, @@ -355,7 +390,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle */ if (opt & PT_PIPELINE) { draw_pipeline_run( fpme->draw, - fpme->prim, + fpme->output_prim, pipeline_verts, count, fpme->vertex_size, @@ -392,6 +427,9 @@ static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) if (fpme->emit) draw_pt_emit_destroy( fpme->emit ); + if (fpme->so_emit) + draw_pt_so_emit_destroy( fpme->so_emit ); + if (fpme->post_vs) draw_pt_post_vs_destroy( fpme->post_vs ); @@ -426,6 +464,10 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * if (!fpme->emit) goto fail; + fpme->so_emit = draw_pt_so_emit_create( draw ); + if (!fpme->so_emit) + goto fail; + return &fpme->base; fail: