static void llvm_pipeline_generic(struct draw_pt_middle_end *middle, const struct draw_fetch_info *fetch_info, const struct draw_prim_info *in_prim_info) { struct llvm_middle_end *fpme = 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; struct draw_prim_info ia_prim_info; struct draw_vertex_info ia_vert_info; const struct draw_prim_info *prim_info = in_prim_info; boolean free_prim_info = FALSE; unsigned opt = fpme->opt; unsigned clipped = 0; 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, lp_native_vector_width / 32)); if (!llvm_vert_info.verts) { assert(0); return; } if (draw->collect_statistics) { draw->statistics.ia_vertices += prim_info->count; draw->statistics.ia_primitives += u_decomposed_prims_for_vertices(prim_info->prim, prim_info->count); draw->statistics.vs_invocations += fetch_info->count; } if (fetch_info->linear) clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context, llvm_vert_info.verts, draw->pt.user.vbuffer, fetch_info->start, fetch_info->count, fpme->vertex_size, draw->pt.vertex_buffer, draw->instance_id, draw->start_index, draw->start_instance); else clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, llvm_vert_info.verts, draw->pt.user.vbuffer, fetch_info->elts, draw->pt.user.eltMax, fetch_info->count, fpme->vertex_size, draw->pt.vertex_buffer, draw->instance_id, draw->pt.user.eltBias, draw->start_instance); /* Finished with fetch and vs: */ fetch_info = NULL; vert_info = &llvm_vert_info; if ((opt & PT_SHADE) && gshader) { struct draw_vertex_shader *vshader = draw->vs.vertex_shader; draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, draw->pt.user.gs_constants_size, vert_info, prim_info, &vshader->info, &gs_vert_info, &gs_prim_info); FREE(vert_info->verts); vert_info = &gs_vert_info; prim_info = &gs_prim_info; } else { if (draw_prim_assembler_is_required(draw, prim_info, vert_info)) { draw_prim_assembler_run(draw, prim_info, vert_info, &ia_prim_info, &ia_vert_info); if (ia_vert_info.count) { FREE(vert_info->verts); vert_info = &ia_vert_info; prim_info = &ia_prim_info; free_prim_info = TRUE; } } } if (prim_info->count == 0) { debug_printf("GS/IA didn't emit any vertices!\n"); FREE(vert_info->verts); if (free_prim_info) { FREE(prim_info->primitive_lengths); } return; } /* stream output needs to be done before clipping */ draw_pt_so_emit( fpme->so_emit, vert_info, prim_info ); draw_stats_clipper_primitives(draw, prim_info); /* * if there's no position, need to stop now, or the latter stages * will try to access non-existent position output. */ if (draw_current_shader_position_output(draw) != -1) { if ((opt & PT_SHADE) && gshader) { clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info ); } if (clipped) { opt |= PT_PIPELINE; } /* Do we need to run the pipeline? Now will come here if clipped */ if (opt & PT_PIPELINE) { pipeline( fpme, vert_info, prim_info ); } else { emit( fpme->emit, vert_info, prim_info ); } } FREE(vert_info->verts); if (free_prim_info) { FREE(prim_info->primitive_lengths); } }
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 clipped = 0; 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; } if (fetch_info->linear) clipped = 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, draw->instance_id); else clipped = 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, draw->instance_id); /* 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, draw->pt.user.gs_constants_size, vert_info, prim_info, &gs_vert_info, &gs_prim_info); FREE(vert_info->verts); vert_info = &gs_vert_info; prim_info = &gs_prim_info; clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info ); } /* stream output needs to be done before clipping */ draw_pt_so_emit( fpme->so_emit, vert_info, prim_info ); if (clipped) { opt |= PT_PIPELINE; } /* Do we need to run the pipeline? Now will come here if clipped */ if (opt & PT_PIPELINE) { pipeline( fpme, vert_info, prim_info ); } else { emit( fpme->emit, vert_info, prim_info ); } FREE(vert_info->verts); }
static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle, 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_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vs.vertex_shader; struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader; 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) return FALSE; /* Fetch into our vertex buffer */ draw_pt_fetch_run_linear( fpme->fetch, start, count, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of * the pipeline verts. */ if (opt & PT_SHADE) { shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, draw->pt.user.vs_constants, count, fpme->vertex_size, 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); } 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( fpme->draw, fpme->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 ); } FREE(pipeline_verts); return TRUE; }
static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, const struct draw_fetch_info *fetch_info, const struct draw_prim_info *prim_info ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vshader = draw->vs.vertex_shader; struct draw_geometry_shader *gshader = draw->gs.geometry_shader; struct draw_prim_info gs_prim_info; struct draw_vertex_info fetched_vert_info; 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(fpme->vertex_size * align(fetch_info->count, 4)); if (!fetched_vert_info.verts) { assert(0); return; } /* Fetch into our vertex buffer. */ fetch( fpme->fetch, fetch_info, (char *)fetched_vert_info.verts ); /* Finished with fetch: */ fetch_info = NULL; vert_info = &fetched_vert_info; /* Run the shader, note that this overwrites the data[] parts of * the pipeline verts. */ if (fpme->opt & PT_SHADE) { draw_vertex_shader_run(vshader, draw->pt.user.vs_constants, draw->pt.user.vs_constants_size, vert_info, &vs_vert_info); FREE(vert_info->verts); vert_info = &vs_vert_info; } if ((fpme->opt & PT_SHADE) && gshader) { draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, draw->pt.user.gs_constants_size, 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. * * XXX: Stream output surely needs to respect the prim_info->elt * lists. */ draw_pt_so_emit( fpme->so_emit, 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) { pipeline( fpme, vert_info, prim_info ); } else { emit( fpme->emit, vert_info, prim_info ); } FREE(vert_info->verts); }
static void fetch_pipeline_run( struct draw_pt_middle_end *middle, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, unsigned draw_count ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vshader = draw->vs.vertex_shader; struct draw_geometry_shader *gshader = draw->gs.geometry_shader; 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. */ assert(0); return; } /* Fetch into our vertex buffer */ draw_pt_fetch_run( fpme->fetch, fetch_elts, fetch_count, (char *)pipeline_verts ); /* Run the shader, note that this overwrites the data[] parts of * the pipeline verts. */ if (opt & PT_SHADE) { vshader->run_linear(vshader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, draw->pt.user.vs_constants, fetch_count, 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); } if (draw_pt_post_vs_run( fpme->post_vs, pipeline_verts, fetch_count, fpme->vertex_size )) { opt |= PT_PIPELINE; } /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { draw_pipeline_run( fpme->draw, fpme->prim, pipeline_verts, fetch_count, fpme->vertex_size, draw_elts, draw_count ); } else { draw_pt_emit( fpme->emit, (const float (*)[4])pipeline_verts->data, fetch_count, fpme->vertex_size, draw_elts, draw_count ); } FREE(pipeline_verts); }