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 )
{
}
}
- 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
*/
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,
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) {
(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)
{
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,
*/
if (opt & PT_PIPELINE) {
draw_pipeline_run( fpme->draw,
- fpme->prim,
+ fpme->output_prim,
pipeline_verts,
fetch_count,
fpme->vertex_size,
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) {
(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)
{
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,
*/
if (opt & PT_PIPELINE) {
draw_pipeline_run_linear( fpme->draw,
- fpme->prim,
+ fpme->output_prim,
pipeline_verts,
count,
fpme->vertex_size);
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
(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)
{
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,
*/
if (opt & PT_PIPELINE) {
draw_pipeline_run( fpme->draw,
- fpme->prim,
+ fpme->output_prim,
pipeline_verts,
count,
fpme->vertex_size,
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 );
if (!fpme->emit)
goto fail;
+ fpme->so_emit = draw_pt_so_emit_create( draw );
+ if (!fpme->so_emit)
+ goto fail;
+
return &fpme->base;
fail: