X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fdraw%2Fdraw_vs_varient.c;h=0abd827b61586e5e80401bfa1b60ca8a7a1ae08f;hb=2a30d3d74a0b87f8066659952628ccd072a4e2b0;hp=f6f621a74816f71bde58be9cf74e8c7d693f5dce;hpb=889473b3f5a216bd753c357974d6bae29fe3c41d;p=mesa.git diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index f6f621a7481..0abd827b615 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -30,22 +30,20 @@ * Keith Whitwell */ -#include "pipe/p_util.h" +#include "util/u_memory.h" +#include "util/u_math.h" #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_vs.h" #include "translate/translate.h" -#include "translate/translate_cache.h" /* A first pass at incorporating vertex fetch/emit functionality into */ struct draw_vs_varient_generic { struct draw_vs_varient base; - - struct draw_vertex_shader *shader; struct draw_context *draw; @@ -58,41 +56,86 @@ struct draw_vs_varient_generic { struct translate *fetch; struct translate *emit; - const float (*constants)[4]; + unsigned temp_vertex_stride; }; -static void vsvg_set_constants( struct draw_vs_varient *varient, - const float (*constants)[4] ) -{ - struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; - vsvg->constants = constants; -} - - -static void vsvg_set_input( struct draw_vs_varient *varient, - unsigned buffer, - const void *ptr, - unsigned stride ) +static void vsvg_set_buffer( struct draw_vs_varient *varient, + unsigned buffer, + const void *ptr, + unsigned stride, + unsigned max_index ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; vsvg->fetch->set_buffer(vsvg->fetch, buffer, ptr, - stride); + stride, + max_index ); } -static void vsvg_run_elts( struct draw_vs_varient *varient, - const unsigned *elts, - unsigned count, - void *output_buffer) +/* Mainly for debug at this stage: + */ +static void do_rhw_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) +{ + char *ptr = (char *)output_buffer; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; + unsigned stride = vsvg->temp_vertex_stride; + unsigned j; + + ptr += vsvg->base.vs->position_output * 4 * sizeof(float); + + for (j = 0; j < count; j++, ptr += stride) { + float *data = (float *)ptr; + float w = 1.0f / data[3]; + + data[0] = data[0] * w * scale[0] + trans[0]; + data[1] = data[1] * w * scale[1] + trans[1]; + data[2] = data[2] * w * scale[2] + trans[2]; + data[3] = w; + } +} + +static void do_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) +{ + char *ptr = (char *)output_buffer; + const float *scale = vsvg->base.vs->draw->viewport.scale; + const float *trans = vsvg->base.vs->draw->viewport.translate; + unsigned stride = vsvg->temp_vertex_stride; + unsigned j; + + ptr += vsvg->base.vs->position_output * 4 * sizeof(float); + + for (j = 0; j < count; j++, ptr += stride) { + float *data = (float *)ptr; + + data[0] = data[0] * scale[0] + trans[0]; + data[1] = data[1] * scale[1] + trans[1]; + data[2] = data[2] * scale[2] + trans[2]; + } +} + + +static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, + const unsigned *elts, + unsigned count, + void *output_buffer) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + unsigned temp_vertex_stride = vsvg->temp_vertex_stride; + void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride ); + + if (0) debug_printf("%s %d \n", __FUNCTION__, count); /* Want to do this in small batches for cache locality? */ @@ -100,78 +143,119 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, vsvg->fetch->run_elts( vsvg->fetch, elts, count, - output_buffer ); + vsvg->draw->instance_id, + temp_buffer ); + + vsvg->base.vs->run_linear( vsvg->base.vs, + temp_buffer, + temp_buffer, + vsvg->base.vs->draw->pt.user.vs_constants, + count, + temp_vertex_stride, + temp_vertex_stride); + + /* FIXME: geometry shading? */ + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + temp_buffer ); + } + else if (vsvg->base.key.viewport) { + do_viewport( vsvg, + count, + temp_buffer ); + } - //if (!vsvg->base.vs->is_passthrough) - { - vsvg->base.vs->run_linear( vsvg->base.vs, - output_buffer, - output_buffer, - vsvg->constants, - count, - vsvg->base.key.output_stride, - vsvg->base.key.output_stride); - //if (!vsvg->already_in_emit_format) + vsvg->emit->set_buffer( vsvg->emit, + 0, + temp_buffer, + temp_vertex_stride, + ~0 ); - vsvg->emit->set_buffer( vsvg->emit, - 0, - output_buffer, - vsvg->base.key.output_stride ); + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0, + ~0 ); + vsvg->emit->run( vsvg->emit, + 0, count, + vsvg->draw->instance_id, + output_buffer ); - vsvg->emit->run( vsvg->emit, - 0, count, - output_buffer ); - } + FREE(temp_buffer); } -static void vsvg_run_linear( struct draw_vs_varient *varient, - unsigned start, - unsigned count, - void *output_buffer ) +static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, + unsigned start, + unsigned count, + void *output_buffer ) { struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + unsigned temp_vertex_stride = vsvg->temp_vertex_stride; + void *temp_buffer = MALLOC( align(count,4) * temp_vertex_stride ); - //debug_printf("%s %d %d\n", __FUNCTION__, start, count); - - + if (0) debug_printf("%s %d %d (sz %d, %d)\n", __FUNCTION__, start, count, + vsvg->base.key.output_stride, + temp_vertex_stride); + vsvg->fetch->run( vsvg->fetch, start, count, - output_buffer ); - - //if (!vsvg->base.vs->is_passthrough) - { - vsvg->base.vs->run_linear( vsvg->base.vs, - output_buffer, - output_buffer, - vsvg->constants, - count, - vsvg->base.key.output_stride, - vsvg->base.key.output_stride); - - //if (!vsvg->already_in_emit_format) - vsvg->emit->set_buffer( vsvg->emit, - 0, - output_buffer, - vsvg->base.key.output_stride ); - - - vsvg->emit->run( vsvg->emit, - 0, count, - output_buffer ); + vsvg->draw->instance_id, + temp_buffer ); + + vsvg->base.vs->run_linear( vsvg->base.vs, + temp_buffer, + temp_buffer, + vsvg->base.vs->draw->pt.user.vs_constants, + count, + temp_vertex_stride, + temp_vertex_stride); + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + temp_buffer ); + } + else if (vsvg->base.key.viewport) { + do_viewport( vsvg, + count, + temp_buffer ); } + + vsvg->emit->set_buffer( vsvg->emit, + 0, + temp_buffer, + temp_vertex_stride, + ~0 ); + + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0, + ~0 ); + + vsvg->emit->run( vsvg->emit, + 0, count, + vsvg->draw->instance_id, + output_buffer ); + + FREE(temp_buffer); } -static void vsvg_set_viewport( struct draw_vs_varient *varient, - const struct pipe_viewport_state *viewport ) -{ -} static void vsvg_destroy( struct draw_vs_varient *varient ) { @@ -185,46 +269,61 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, unsigned i; struct translate_key fetch, emit; - if (key->viewport || key->clip) - return NULL; - struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); if (vsvg == NULL) return NULL; vsvg->base.key = *key; vsvg->base.vs = vs; - vsvg->base.set_input = vsvg_set_input; - vsvg->base.set_constants = vsvg_set_constants; - vsvg->base.set_viewport = vsvg_set_viewport; + vsvg->base.set_buffer = vsvg_set_buffer; vsvg->base.run_elts = vsvg_run_elts; vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; + vsvg->draw = vs->draw; + vsvg->temp_vertex_stride = MAX2(key->nr_inputs, + vsvg->base.vs->info.num_outputs) * 4 * sizeof(float); - /* OK, have to build a new one: + /* Build free-standing fetch and emit functions: */ - fetch.nr_elements = vs->info.num_inputs; - fetch.output_stride = 0; - for (i = 0; i < vs->info.num_inputs; i++) { + fetch.nr_elements = key->nr_inputs; + fetch.output_stride = vsvg->temp_vertex_stride; + for (i = 0; i < key->nr_inputs; i++) { + fetch.element[i].type = TRANSLATE_ELEMENT_NORMAL; fetch.element[i].input_format = key->element[i].in.format; fetch.element[i].input_buffer = key->element[i].in.buffer; fetch.element[i].input_offset = key->element[i].in.offset; + fetch.element[i].instance_divisor = 0; fetch.element[i].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - fetch.element[i].output_offset = fetch.output_stride; - fetch.output_stride += 4 * sizeof(float); + fetch.element[i].output_offset = i * 4 * sizeof(float); + assert(fetch.element[i].output_offset < fetch.output_stride); } - emit.nr_elements = vs->info.num_outputs; + emit.nr_elements = key->nr_outputs; emit.output_stride = key->output_stride; - for (i = 0; i < vs->info.num_outputs; i++) { - emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit.element[i].input_buffer = 0; - emit.element[i].input_offset = i * 4 * sizeof(float); - emit.element[i].output_format = key->element[i].out.format; - emit.element[i].output_offset = key->element[i].out.offset; + for (i = 0; i < key->nr_outputs; i++) { + if (key->element[i].out.format != EMIT_1F_PSIZE) + { + emit.element[i].type = TRANSLATE_ELEMENT_NORMAL; + emit.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit.element[i].input_buffer = 0; + emit.element[i].input_offset = key->element[i].out.vs_output * 4 * sizeof(float); + emit.element[i].instance_divisor = 0; + emit.element[i].output_format = draw_translate_vinfo_format(key->element[i].out.format); + emit.element[i].output_offset = key->element[i].out.offset; + assert(emit.element[i].input_offset <= fetch.output_stride); + } + else { + emit.element[i].type = TRANSLATE_ELEMENT_NORMAL; + emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + emit.element[i].input_buffer = 1; + emit.element[i].input_offset = 0; + emit.element[i].instance_divisor = 0; + emit.element[i].output_format = PIPE_FORMAT_R32_FLOAT; + emit.element[i].output_offset = key->element[i].out.offset; + } } vsvg->fetch = draw_vs_get_fetch( vs->draw, &fetch );