mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
draw: make pt run pipeline when need_pipeline is true, not just when clipped
This commit is contained in:
parent
fd6acabd2f
commit
a8582efaca
7 changed files with 84 additions and 164 deletions
|
|
@ -182,6 +182,12 @@ typedef void (*pt_fetch_func)( struct draw_context *draw,
|
|||
|
||||
struct vbuf_render;
|
||||
|
||||
|
||||
#define PT_SHADE 0x1
|
||||
#define PT_CLIPTEST 0x2
|
||||
#define PT_PIPELINE 0x4
|
||||
#define PT_MAX_MIDDLE 0x8
|
||||
|
||||
/**
|
||||
* Private context for the drawing module.
|
||||
*/
|
||||
|
|
@ -219,15 +225,10 @@ struct draw_context
|
|||
unsigned hw_vertex_size; /* XXX: to be removed */
|
||||
|
||||
struct {
|
||||
struct draw_pt_middle_end *fetch_emit;
|
||||
struct draw_pt_middle_end *fetch_pipeline;
|
||||
struct draw_pt_middle_end *fetch_shade_emit;
|
||||
struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit;
|
||||
struct draw_pt_middle_end *opt[PT_MAX_MIDDLE];
|
||||
} middle;
|
||||
|
||||
struct {
|
||||
struct draw_pt_front_end *noop;
|
||||
struct draw_pt_front_end *split_arrays;
|
||||
struct draw_pt_front_end *vcache;
|
||||
} front;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,146 +36,58 @@
|
|||
#include "draw/draw_pt.h"
|
||||
|
||||
|
||||
#if 0
|
||||
static boolean too_many_elts( struct draw_context *draw,
|
||||
unsigned elts )
|
||||
{
|
||||
return elts > (8 * 1024);
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE unsigned reduced_prim(unsigned prim)
|
||||
{
|
||||
/*FIXME*/
|
||||
return prim;
|
||||
}
|
||||
|
||||
static INLINE boolean good_prim(unsigned prim)
|
||||
{
|
||||
/*FIXME*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Overall we split things into:
|
||||
* - frontend -- prepare fetch_elts, draw_elts - eg vcache
|
||||
* - middle -- fetch, shade, cliptest, viewport
|
||||
* - pipeline -- the prim pipeline: clipping, wide lines, etc
|
||||
* - backend -- the vbuf_render provided by the driver.
|
||||
*/
|
||||
boolean
|
||||
draw_pt_arrays(struct draw_context *draw,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
const boolean pipeline = draw_need_pipeline(draw, prim);
|
||||
const boolean cliptest = !draw->rasterizer->bypass_clipping;
|
||||
const boolean shading = !draw->rasterizer->bypass_vs;
|
||||
struct draw_pt_front_end *frontend = NULL;
|
||||
struct draw_pt_middle_end *middle = NULL;
|
||||
unsigned opt = 0;
|
||||
|
||||
if (!draw->render)
|
||||
return FALSE;
|
||||
/*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/
|
||||
|
||||
/* Overall we do:
|
||||
* - frontend -- prepare fetch_elts, draw_elts - eg vcache
|
||||
* - middle -- fetch, shade, cliptest, viewport
|
||||
* - pipeline -- the prim pipeline: clipping, wide lines, etc
|
||||
* - backend -- the vbuf_render provided by the driver.
|
||||
|
||||
if (draw_need_pipeline(draw, prim)) {
|
||||
opt |= PT_PIPELINE;
|
||||
}
|
||||
|
||||
if (!draw->rasterizer->bypass_clipping) {
|
||||
opt |= PT_CLIPTEST;
|
||||
}
|
||||
|
||||
if (!draw->rasterizer->bypass_vs) {
|
||||
opt |= PT_SHADE;
|
||||
|
||||
if (!draw->use_pt_shaders)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (draw->pt.middle.opt[opt] == NULL) {
|
||||
opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE;
|
||||
}
|
||||
|
||||
middle = draw->pt.middle.opt[opt];
|
||||
assert(middle);
|
||||
|
||||
/* May create a short-circuited version of this for small primitives:
|
||||
*/
|
||||
|
||||
if (shading && !draw->use_pt_shaders)
|
||||
return FALSE;
|
||||
|
||||
|
||||
if (!cliptest && !pipeline && !shading) {
|
||||
/* This is the 'passthrough' path:
|
||||
*/
|
||||
/* Fetch user verts, emit hw verts:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_emit;
|
||||
}
|
||||
else if (!cliptest && !shading) {
|
||||
/* This is the 'passthrough' path targetting the pipeline backend.
|
||||
*/
|
||||
/* Fetch user verts, emit pipeline verts, run pipeline:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_pipeline;
|
||||
}
|
||||
else if (!cliptest && !pipeline) {
|
||||
/* Fetch user verts, run vertex shader, emit hw verts:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_emit;
|
||||
}
|
||||
else if (!pipeline) {
|
||||
/* Even though !pipeline, we have to run it to get clipping. We
|
||||
* do know that the pipeline is just the clipping operation, but
|
||||
* that probably doesn't help much.
|
||||
*
|
||||
* This is going to be the most important path for a lot of
|
||||
* swtnl cards.
|
||||
*/
|
||||
/* Fetch user verts,
|
||||
* run vertex shader,
|
||||
* cliptest and viewport trasform
|
||||
* if no clipped vertices,
|
||||
* emit hw verts
|
||||
* else
|
||||
* run pipline
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit;
|
||||
}
|
||||
else {
|
||||
/* This is what we're currently always doing:
|
||||
*/
|
||||
/* Fetch user verts, run vertex shader, cliptest, run pipeline
|
||||
* or
|
||||
* Fetch user verts, run vertex shader, run pipeline
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit;
|
||||
}
|
||||
|
||||
|
||||
/* If !pipeline, need to make sure we respect the driver's limited
|
||||
* capabilites to receive blocks of vertex data and elements.
|
||||
*/
|
||||
#if 0
|
||||
if (!pipeline) {
|
||||
unsigned vertex_mode = passthrough;
|
||||
unsigned nr_verts = count_vertices( draw, start, count );
|
||||
unsigned hw_prim = prim;
|
||||
|
||||
if (is_elts(draw)) {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
#if 0
|
||||
if (too_many_verts(nr_verts)) {
|
||||
/* if (is_verts(draw) && can_split(prim)) {
|
||||
draw = draw_arrays_split;
|
||||
}
|
||||
else */ {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (too_many_elts(count)) {
|
||||
|
||||
/* if (is_elts(draw) && can_split(prim)) {
|
||||
draw = draw_elts_split;
|
||||
}
|
||||
else */ {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
}
|
||||
|
||||
if (!good_prim(hw_prim)) {
|
||||
frontend = draw->pt.front.vcache;
|
||||
}
|
||||
}
|
||||
#else
|
||||
frontend = draw->pt.front.vcache;
|
||||
#endif
|
||||
|
||||
frontend->prepare( frontend, prim, middle );
|
||||
|
||||
frontend->prepare( frontend, prim, middle, opt );
|
||||
|
||||
frontend->run( frontend,
|
||||
draw_pt_elt_func( draw ),
|
||||
|
|
@ -190,44 +102,34 @@ draw_pt_arrays(struct draw_context *draw,
|
|||
|
||||
boolean draw_pt_init( struct draw_context *draw )
|
||||
{
|
||||
draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw );
|
||||
if (!draw->pt.middle.fetch_emit)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw );
|
||||
if (!draw->pt.middle.fetch_pipeline)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit =
|
||||
draw_pt_fetch_pipeline_or_emit( draw );
|
||||
if (!draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.front.vcache = draw_pt_vcache( draw );
|
||||
if (!draw->pt.front.vcache)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw );
|
||||
draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw );
|
||||
// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw );
|
||||
// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw );
|
||||
// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw );
|
||||
draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] =
|
||||
draw_pt_fetch_pipeline_or_emit( draw );
|
||||
|
||||
if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void draw_pt_destroy( struct draw_context *draw )
|
||||
{
|
||||
if (draw->pt.middle.fetch_emit) {
|
||||
draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit );
|
||||
draw->pt.middle.fetch_emit = NULL;
|
||||
}
|
||||
int i;
|
||||
|
||||
if (draw->pt.middle.fetch_pipeline) {
|
||||
draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline );
|
||||
draw->pt.middle.fetch_pipeline = NULL;
|
||||
}
|
||||
|
||||
if (draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) {
|
||||
draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit->destroy(
|
||||
draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit );
|
||||
draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = NULL;
|
||||
}
|
||||
for (i = 0; i < PT_MAX_MIDDLE; i++)
|
||||
if (draw->pt.middle.opt[i]) {
|
||||
draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] );
|
||||
draw->pt.middle.opt[i] = NULL;
|
||||
}
|
||||
|
||||
if (draw->pt.front.vcache) {
|
||||
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ struct draw_context;
|
|||
struct draw_pt_front_end {
|
||||
void (*prepare)( struct draw_pt_front_end *,
|
||||
unsigned prim,
|
||||
struct draw_pt_middle_end * );
|
||||
struct draw_pt_middle_end *,
|
||||
unsigned opt );
|
||||
|
||||
void (*run)( struct draw_pt_front_end *,
|
||||
pt_elt_func elt_func,
|
||||
|
|
@ -90,7 +91,8 @@ struct draw_pt_front_end {
|
|||
*/
|
||||
struct draw_pt_middle_end {
|
||||
void (*prepare)( struct draw_pt_middle_end *,
|
||||
unsigned prim );
|
||||
unsigned prim,
|
||||
unsigned opt );
|
||||
|
||||
void (*run)( struct draw_pt_middle_end *,
|
||||
const unsigned *fetch_elts,
|
||||
|
|
|
|||
|
|
@ -164,7 +164,8 @@ fetch_store_general( struct fetch_emit_middle_end *feme,
|
|||
|
||||
|
||||
static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim )
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
{
|
||||
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
|
||||
struct draw_context *draw = feme->draw;
|
||||
|
|
|
|||
|
|
@ -209,7 +209,8 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme,
|
|||
*
|
||||
*/
|
||||
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim )
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
{
|
||||
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
|
||||
struct draw_context *draw = fpme->draw;
|
||||
|
|
|
|||
|
|
@ -42,11 +42,13 @@ struct fetch_pipeline_middle_end {
|
|||
|
||||
unsigned pipeline_vertex_size;
|
||||
unsigned prim;
|
||||
unsigned opt;
|
||||
};
|
||||
|
||||
|
||||
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim )
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
{
|
||||
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
|
||||
struct draw_context *draw = fpme->draw;
|
||||
|
|
@ -57,6 +59,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
|||
struct translate_key hw_key;
|
||||
|
||||
fpme->prim = prim;
|
||||
fpme->opt = opt;
|
||||
|
||||
ok = draw->render->set_primitive(draw->render, prim);
|
||||
if (!ok) {
|
||||
|
|
@ -157,6 +160,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
|
|||
struct draw_context *draw = fpme->draw;
|
||||
struct draw_vertex_shader *shader = draw->vertex_shader;
|
||||
char *pipeline_verts;
|
||||
unsigned pipeline = PT_PIPELINE;
|
||||
|
||||
pipeline_verts = MALLOC(fpme->pipeline_vertex_size *
|
||||
fetch_count);
|
||||
|
|
@ -170,9 +174,17 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
|
|||
/* Shade
|
||||
*/
|
||||
shader->prepare(shader, draw);
|
||||
|
||||
if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts,
|
||||
fpme->pipeline_vertex_size)) {
|
||||
/* Run the pipeline */
|
||||
fpme->pipeline_vertex_size))
|
||||
{
|
||||
pipeline |= PT_CLIPTEST;
|
||||
}
|
||||
|
||||
|
||||
/* Do we need to run the pipeline?
|
||||
*/
|
||||
if (fpme->opt & pipeline) {
|
||||
draw_pt_run_pipeline( fpme->draw,
|
||||
fpme->prim,
|
||||
pipeline_verts,
|
||||
|
|
|
|||
|
|
@ -448,7 +448,8 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
|||
|
||||
static void vcache_prepare( struct draw_pt_front_end *frontend,
|
||||
unsigned prim,
|
||||
struct draw_pt_middle_end *middle )
|
||||
struct draw_pt_middle_end *middle,
|
||||
unsigned opt )
|
||||
{
|
||||
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
|
||||
|
||||
|
|
@ -464,7 +465,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
|
|||
vcache->output_prim = reduced_prim[prim];
|
||||
|
||||
vcache->middle = middle;
|
||||
middle->prepare( middle, vcache->output_prim );
|
||||
middle->prepare( middle, vcache->output_prim, opt );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue