From 7c99d7fe60e7bb0b7cf103a851aeef4614278ca6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 15 May 2008 12:39:08 +0100 Subject: draw: create specialized vs varients incorporating fetch & emit --- src/gallium/auxiliary/draw/draw_vs_varient.c | 229 +++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 src/gallium/auxiliary/draw/draw_vs_varient.c (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c new file mode 100644 index 0000000000..d27b0f6187 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -0,0 +1,229 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + /* + * Authors: + * Keith Whitwell + */ + +#include "pipe/p_util.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; + + /* Basic plan is to run these two translate functions before/after + * the vertex shader's existing run_linear() routine to simulate + * the inclusion of this functionality into the shader... + * + * Next will look at actually including it. + */ + struct translate *fetch; + struct translate *emit; + + const float (*constants)[4]; +}; + + + + +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 ) +{ + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + vsvg->fetch->set_buffer(vsvg->fetch, + buffer, + ptr, + stride); +} + + +static void 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; + + /* Want to do this in small batches for cache locality? + */ + + vsvg->fetch->run_elts( vsvg->fetch, + elts, + 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 ); + } +} + + +static void 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; + + //debug_printf("%s %d %d\n", __FUNCTION__, start, count); + + + 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 ); + } +} + + + +static void vsvg_destroy( struct draw_vs_varient *varient ) +{ + FREE(varient); +} + + +struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, + const struct draw_vs_varient_key *key ) +{ + unsigned i; + struct translate_key fetch, emit; + + 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.run_elts = vsvg_run_elts; + vsvg->base.run_linear = vsvg_run_linear; + vsvg->base.destroy = vsvg_destroy; + + + + /* OK, have to build a new one: + */ + fetch.nr_elements = vs->info.num_inputs; + fetch.output_stride = 0; + for (i = 0; i < vs->info.num_inputs; i++) { + 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].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + fetch.element[i].output_offset = fetch.output_stride; + fetch.output_stride += 4 * sizeof(float); + } + + + emit.nr_elements = vs->info.num_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; + } + + vsvg->fetch = draw_vs_get_fetch( vs->draw, &fetch ); + vsvg->emit = draw_vs_get_emit( vs->draw, &emit ); + + return &vsvg->base; +} + + + + + -- cgit v1.2.3 From 889473b3f5a216bd753c357974d6bae29fe3c41d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 21 May 2008 20:28:56 +0100 Subject: draw: add viewport to varient state --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 9 +++- src/gallium/auxiliary/draw/draw_vs.h | 8 +++- src/gallium/auxiliary/draw/draw_vs_aos.c | 50 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.h | 9 +++- src/gallium/auxiliary/draw/draw_vs_sse.c | 4 +- src/gallium/auxiliary/draw/draw_vs_varient.c | 10 +++++ 6 files changed, 84 insertions(+), 6 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 74945dcfe9..984fbb6767 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -95,10 +95,14 @@ static void fse_prepare( struct draw_pt_middle_end *middle, + fse->key.output_stride = vinfo->size * 4; fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ num_vs_inputs); /* inputs - fetch from api format */ - fse->key.output_stride = vinfo->size * 4; + fse->key.viewport = 1; + fse->key.clip = 0; + fse->key.pad = 0; + memset(fse->key.element, 0, fse->key.nr_elements * sizeof(fse->key.element[0])); @@ -211,6 +215,9 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->active->set_constants( fse->active, (const float (*)[4])draw->pt.user.constants ); + fse->active->set_viewport( fse->active, + &draw->viewport ); + //return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 5a8d0da06d..ff3e19b2a8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -58,7 +58,10 @@ struct draw_vs_element { struct draw_vs_varient_key { unsigned output_stride; - unsigned nr_elements; + unsigned nr_elements:16; + unsigned viewport:1; + unsigned clip:1; + unsigned pad:14; struct draw_vs_element element[PIPE_MAX_ATTRIBS]; }; @@ -88,6 +91,9 @@ struct draw_vs_varient { void (*set_constants)( struct draw_vs_varient *, const float (*constants)[4] ); + void (*set_viewport)( struct draw_vs_varient *, + const struct pipe_viewport_state * ); + void (PIPE_CDECL *run_linear)( struct draw_vs_varient *shader, unsigned start, unsigned count, diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 620f5e3592..b8e66e8b78 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -1401,6 +1401,37 @@ emit_instruction( struct aos_compilation *cp, } } + +static boolean emit_viewport( struct aos_compilation *cp ) +{ + struct x86_reg pos = aos_get_shader_reg(cp, + TGSI_FILE_OUTPUT, + 0); + + struct x86_reg scale = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, scale)); + + struct x86_reg translate = x86_make_disp(cp->machine_EDX, + Offset(struct aos_machine, translate)); + + if (pos.file != file_XMM) { + struct x86_reg dst = aos_get_xmm_reg(cp); + sse_movups(cp->func, dst, pos); + pos = dst; + } + + sse_mulps(cp->func, pos, scale); + sse_addps(cp->func, pos, translate); + + aos_adopt_xmm_reg( cp, + pos, + TGSI_FILE_OUTPUT, + 0, + TRUE ); + return TRUE; +} + + static boolean note_immediate( struct aos_compilation *cp, struct tgsi_full_immediate *imm ) { @@ -1540,6 +1571,10 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.error) goto fail; + if (cp.vaos->base.key.viewport) { + emit_viewport(&cp); + } + /* Emit output... TODO: do this eagerly after the last write to a * given output. */ @@ -1665,11 +1700,25 @@ static void vaos_set_constants( struct draw_vs_varient *varient, } +static void vaos_set_viewport( struct draw_vs_varient *varient, + const struct pipe_viewport_state *viewport ) +{ + struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + + memcpy(vaos->machine->scale, viewport->scale, 4 * sizeof(float)); + memcpy(vaos->machine->translate, viewport->translate, 4 * sizeof(float)); +} + + + static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, const struct draw_vs_varient_key *key ) { struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse); + if (key->clip) + return NULL; + if (!vaos) goto fail; @@ -1677,6 +1726,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.vs = vs; vaos->base.set_input = vaos_set_buffer; vaos->base.set_constants = vaos_set_constants; + vaos->base.set_viewport = vaos_set_viewport; vaos->base.destroy = vaos_destroy; vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index 1d8a055a90..16fef6451c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -68,8 +68,13 @@ struct aos_machine { float immediate[MAX_IMMEDIATES][4]; /* fixme -- should just be a pointer */ float internal [MAX_INTERNALS ][4]; - unsigned fpu_round_nearest; - unsigned fpu_round_neg_inf; + float scale[4]; /* viewport */ + float translate[4]; /* viewport */ + + ushort fpu_round_nearest; + ushort fpu_round_neg_inf; + ushort fpu_restore; + ushort fpucntl; /* one of FPU_* above */ struct { const void *input_ptr; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 0581c3042f..7781782ae8 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -156,8 +156,8 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); vs->base.draw = draw; - vs->base.create_varient = draw_vs_varient_generic; -// vs->base.create_varient = draw_vs_varient_aos_sse; + vs->base.create_varient = draw_vs_varient_aos_sse; +// vs->base.create_varient = draw_vs_varient_generic; vs->base.prepare = vs_sse_prepare; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d27b0f6187..f6f621a748 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -167,6 +167,12 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, + +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 ) { FREE(varient); @@ -179,6 +185,9 @@ 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; @@ -187,6 +196,7 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, 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.run_elts = vsvg_run_elts; vsvg->base.run_linear = vsvg_run_linear; vsvg->base.destroy = vsvg_destroy; -- cgit v1.2.3 From 584a3dcf8e4042cc1a5d48d83ea63d0a3c9706c1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 25 May 2008 11:25:09 +0100 Subject: draw: add viewport support to generic vs varient code --- src/gallium/auxiliary/draw/draw_vs_varient.c | 43 ++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index f6f621a748..c15c648527 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -44,7 +44,7 @@ struct draw_vs_varient_generic { struct draw_vs_varient base; - + struct pipe_viewport_state viewport; struct draw_vertex_shader *shader; struct draw_context *draw; @@ -87,6 +87,30 @@ static void vsvg_set_input( struct draw_vs_varient *varient, } +/* Mainly for debug at this stage: + */ +static void do_viewport( struct draw_vs_varient_generic *vsvg, + unsigned count, + void *output_buffer ) +{ + char *ptr = (char *)output_buffer; + const float *scale = vsvg->viewport.scale; + const float *trans = vsvg->viewport.translate; + unsigned stride = vsvg->base.key.output_stride; + unsigned j; + + 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 vsvg_run_elts( struct draw_vs_varient *varient, const unsigned *elts, unsigned count, @@ -112,6 +136,12 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); + if (vsvg->base.key.viewport) + do_viewport( vsvg, + count, + output_buffer ); + + //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, @@ -152,6 +182,12 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); + if (vsvg->base.key.viewport) + do_viewport( vsvg, + count, + output_buffer ); + + //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, 0, @@ -171,6 +207,9 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, static void vsvg_set_viewport( struct draw_vs_varient *varient, const struct pipe_viewport_state *viewport ) { + struct draw_vs_varient_generic *vsvg = (struct draw_vs_varient_generic *)varient; + + vsvg->viewport = *viewport; } static void vsvg_destroy( struct draw_vs_varient *varient ) @@ -185,7 +224,7 @@ 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) + if (key->clip) return NULL; struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); -- cgit v1.2.3 From a08c574bfcf72c7f7ffbeb35c10347b491ef87fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 12:26:23 +0100 Subject: draw: hook up viewport / rhw emit to varient key state --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 4 +- src/gallium/auxiliary/draw/draw_vs_aos.c | 16 +++---- src/gallium/auxiliary/draw/draw_vs_varient.c | 52 ++++++++++++++++++---- 3 files changed, 53 insertions(+), 19 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 7fefd391a6..2f2e7195b3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -94,8 +94,8 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ num_vs_inputs); /* inputs - fetch from api format */ - fse->key.viewport = 1; - fse->key.clip = 0; + fse->key.viewport = !draw->identity_viewport; + fse->key.clip = !draw->bypass_clipping; fse->key.pad = 0; memset(fse->key.element, 0, diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index d3989fe107..c63553216c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2021,11 +2021,14 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient, if (cp.error) goto fail; - if (cp.vaos->base.key.viewport) { - if (0) - emit_viewport(&cp); - else - emit_rhw_viewport(&cp); + if (cp.vaos->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + emit_rhw_viewport(&cp); + } + else if (cp.vaos->base.key.viewport) { + emit_viewport(&cp); } /* Emit output... TODO: do this eagerly after the last write to a @@ -2188,9 +2191,6 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, { struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse); - if (key->clip) - return NULL; - if (!vaos) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index c15c648527..d4deabfff3 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -89,9 +89,9 @@ static void vsvg_set_input( struct draw_vs_varient *varient, /* Mainly for debug at this stage: */ -static void do_viewport( struct draw_vs_varient_generic *vsvg, - unsigned count, - void *output_buffer ) +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->viewport.scale; @@ -109,6 +109,25 @@ static void do_viewport( struct draw_vs_varient_generic *vsvg, 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->viewport.scale; + const float *trans = vsvg->viewport.translate; + unsigned stride = vsvg->base.key.output_stride; + unsigned j; + + 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 vsvg_run_elts( struct draw_vs_varient *varient, @@ -136,10 +155,20 @@ static void vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); - if (vsvg->base.key.viewport) + + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + output_buffer ); + } + else if (vsvg->base.key.viewport) { do_viewport( vsvg, count, output_buffer ); + } //if (!vsvg->already_in_emit_format) @@ -182,11 +211,19 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.key.output_stride, vsvg->base.key.output_stride); - if (vsvg->base.key.viewport) + if (vsvg->base.key.clip) { + /* not really handling clipping, just do the rhw so we can + * see the results... + */ + do_rhw_viewport( vsvg, + count, + output_buffer ); + } + else if (vsvg->base.key.viewport) { do_viewport( vsvg, count, output_buffer ); - + } //if (!vsvg->already_in_emit_format) vsvg->emit->set_buffer( vsvg->emit, @@ -224,9 +261,6 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, unsigned i; struct translate_key fetch, emit; - if (key->clip) - return NULL; - struct draw_vs_varient_generic *vsvg = CALLOC_STRUCT( draw_vs_varient_generic ); if (vsvg == NULL) return NULL; -- cgit v1.2.3 From f8762ba5234fd1b44e11e76bb5f58d2305c90572 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 14:42:15 +0100 Subject: draw: explicitly list nr_inputs, outputs in varient key --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 14 +++++++++----- src/gallium/auxiliary/draw/draw_vs.h | 6 ++++-- src/gallium/auxiliary/draw/draw_vs_aos.c | 2 +- src/gallium/auxiliary/draw/draw_vs_aos_io.c | 4 ++-- src/gallium/auxiliary/draw/draw_vs_varient.c | 10 +++++----- 5 files changed, 21 insertions(+), 15 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index c6249b4b41..581026dcb0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -72,7 +72,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle; struct draw_context *draw = fse->draw; unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; - unsigned num_vs_outputs = draw->vs.vertex_shader->info.num_outputs; const struct vertex_info *vinfo; unsigned i; boolean need_psize = 0; @@ -91,8 +90,11 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.output_stride = vinfo->size * 4; - fse->key.nr_elements = MAX2(num_vs_outputs, /* outputs - translate to hw format */ - num_vs_inputs); /* inputs - fetch from api format */ + fse->key.nr_outputs = vinfo->num_attribs; + fse->key.nr_inputs = num_vs_inputs; + + fse->key.nr_elements = MAX2(fse->key.nr_outputs, /* outputs - translate to hw format */ + fse->key.nr_inputs); /* inputs - fetch from api format */ fse->key.viewport = !draw->identity_viewport; fse->key.clip = !draw->bypass_clipping; @@ -142,7 +144,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle, need_psize = 1; output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); - vs_output = num_vs_outputs + 1; + vs_output = vinfo->num_attribs + 1; break; case EMIT_4UB: output_format = PIPE_FORMAT_B8G8R8A8_UNORM; @@ -177,7 +179,9 @@ static void fse_prepare( struct draw_pt_middle_end *middle, fse->key.element[i].input_buffer = 0; //nr_buffers + 1; fse->key.element[i].input_offset = 0; - fse->key.nr_elements += 1; + fse->key.nr_inputs += 1; + fse->key.nr_elements = MAX2(fse->key.nr_inputs, + fse->key.nr_outputs); } #endif diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index ff3e19b2a8..17902ab86a 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -58,10 +58,12 @@ struct draw_vs_element { struct draw_vs_varient_key { unsigned output_stride; - unsigned nr_elements:16; + unsigned nr_elements:8; /* max2(nr_inputs, nr_outputs) */ + unsigned nr_inputs:8; + unsigned nr_outputs:8; unsigned viewport:1; unsigned clip:1; - unsigned pad:14; + unsigned pad:5; struct draw_vs_element element[PIPE_MAX_ATTRIBS]; }; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index c63553216c..e2e96470f7 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2095,7 +2095,7 @@ static void vaos_set_buffer( struct draw_vs_varient *varient, struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; unsigned i; - for (i = 0; i < vaos->base.vs->info.num_inputs; i++) { + for (i = 0; i < vaos->base.key.nr_inputs; i++) { if (vaos->base.key.element[i].in.buffer == buf) { vaos->machine->attrib[i].input_ptr = ((char *)ptr + vaos->base.key.element[i].in.offset); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index f39ebb7a17..ef265d61cf 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -180,7 +180,7 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear ) { unsigned i; - for (i = 0; i < cp->vaos->base.vs->info.num_inputs; i++) { + for (i = 0; i < cp->vaos->base.key.nr_inputs; i++) { if (!load_input( cp, i, linear )) return FALSE; cp->insn_counter++; @@ -282,7 +282,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) { unsigned i; - for (i = 0; i < cp->vaos->base.vs->info.num_outputs; i++) { + for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) { unsigned format = cp->vaos->base.key.element[i].out.format; unsigned offset = cp->vaos->base.key.element[i].out.offset; diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index d4deabfff3..dab46e8eed 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -276,11 +276,11 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, - /* OK, have to build a new one: + /* Build free-standing fetch and emit functions: */ - fetch.nr_elements = vs->info.num_inputs; + fetch.nr_elements = key->nr_inputs; fetch.output_stride = 0; - for (i = 0; i < vs->info.num_inputs; i++) { + for (i = 0; i < key->nr_inputs; i++) { 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; @@ -290,9 +290,9 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, } - 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++) { + for (i = 0; i < key->nr_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); -- cgit v1.2.3 From 7b85ea19de09d4e7e077ca147528e90e52683690 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 27 May 2008 19:01:57 +0100 Subject: draw: support psize in vs_varient paths Preserve the vinfo "EMIT_*" format descriptors in the varient key, and deal with PSIZE directly in each implementation. --- .../auxiliary/draw/draw_pt_fetch_shade_emit.c | 35 ++------------------ src/gallium/auxiliary/draw/draw_vertex.h | 21 ++++++++++++ src/gallium/auxiliary/draw/draw_vs_aos.c | 3 ++ src/gallium/auxiliary/draw/draw_vs_aos.h | 1 + src/gallium/auxiliary/draw/draw_vs_aos_io.c | 37 ++++++++++++++-------- src/gallium/auxiliary/draw/draw_vs_varient.c | 24 +++++++++++--- 6 files changed, 71 insertions(+), 50 deletions(-) (limited to 'src/gallium/auxiliary/draw/draw_vs_varient.c') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 85d0bdfcab..729c7db999 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -77,7 +77,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle, unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs; const struct vertex_info *vinfo; unsigned i; - boolean need_psize = 0; if (!draw->render->set_primitive( draw->render, @@ -123,34 +122,24 @@ static void fse_prepare( struct draw_pt_middle_end *middle, for (i = 0; i < vinfo->num_attribs; i++) { unsigned emit_sz = 0; - unsigned output_format = PIPE_FORMAT_NONE; - unsigned vs_output = vinfo->src_index[i]; switch (vinfo->emit[i]) { case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit_sz = 4 * sizeof(float); break; case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; emit_sz = 3 * sizeof(float); break; case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; emit_sz = 2 * sizeof(float); break; case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - need_psize = 1; - output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); - vs_output = vinfo->num_attribs + 1; break; case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); break; default: @@ -162,33 +151,15 @@ static void fse_prepare( struct draw_pt_middle_end *middle, * numbers, not to positions in the hw vertex description -- * that's handled by the output_offset field. */ - fse->key.element[vs_output].out.format = output_format; - fse->key.element[vs_output].out.vs_output = vs_output; - fse->key.element[vs_output].out.offset = dst_offset; + fse->key.element[i].out.format = vinfo->emit[i]; + fse->key.element[i].out.vs_output = vinfo->src_index[i]; + fse->key.element[i].out.offset = dst_offset; dst_offset += emit_sz; assert(fse->key.output_stride >= dst_offset); } } - /* To make psize work, really need to tell the vertex shader to - * copy that value from input->output. For 'translate' this was - * implicit for all elements. - */ -#if 0 - if (need_psize) { - unsigned input = num_vs_inputs + 1; - const struct pipe_vertex_element *src = &draw->pt.vertex_element[i]; - fse->key.element[i].input_format = PIPE_FORMAT_R32_FLOAT; - fse->key.element[i].input_buffer = 0; //nr_buffers + 1; - fse->key.element[i].input_offset = 0; - - fse->key.nr_inputs += 1; - fse->key.nr_elements = MAX2(fse->key.nr_inputs, - fse->key.nr_outputs); - - } -#endif /* Would normally look up a vertex shader and peruse its list of * varients somehow. We omitted that step and put all the diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 6d8bac5138..16c65c4317 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -109,4 +109,25 @@ extern void draw_compute_vertex_size(struct vertex_info *vinfo); void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data); + +static INLINE unsigned draw_translate_vinfo_format(unsigned format ) +{ + switch (format) { + case EMIT_1F: + case EMIT_1F_PSIZE: + return PIPE_FORMAT_R32_FLOAT; + case EMIT_2F: + return PIPE_FORMAT_R32G32_FLOAT; + case EMIT_3F: + return PIPE_FORMAT_R32G32B32_FLOAT; + case EMIT_4F: + return PIPE_FORMAT_R32G32B32A32_FLOAT; + case EMIT_4UB: + return PIPE_FORMAT_R8G8B8A8_UNORM; + default: + return PIPE_FORMAT_NONE; + } +} + + #endif /* DRAW_VERTEX_H */ diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c index 1c63677e6e..d3770b2c53 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos.c @@ -2126,6 +2126,7 @@ static void vaos_run_elts( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; vaos->gen_run_elts( varient, elts, count, @@ -2139,6 +2140,7 @@ static void vaos_run_linear( struct draw_vs_varient *varient, { struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient; + vaos->machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size; vaos->gen_run_linear( varient, start, count, @@ -2204,6 +2206,7 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs, vaos->base.run_linear = vaos_run_linear; vaos->base.run_elts = vaos_run_elts; + vaos->draw = vs->draw; vaos->machine = align_malloc( sizeof(struct aos_machine), 16 ); if (!vaos->machine) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h index fffe2e4658..b47413ff43 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos.h +++ b/src/gallium/auxiliary/draw/draw_vs_aos.h @@ -176,6 +176,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ); #define IMM_255 4 /* 255, 255, 255, 255 */ #define IMM_NEGS 5 /* -1,-1,-1,-1 */ #define IMM_RSQ 6 /* -.5,1.5,_,_ */ +#define IMM_PSIZE 7 /* not really an immediate - updated each run */ struct x86_reg aos_get_internal( struct aos_compilation *cp, unsigned imm ); diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index cebfaf6474..836110f382 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -33,6 +33,7 @@ #include "tgsi/exec/tgsi_exec.h" #include "draw_vs.h" #include "draw_vs_aos.h" +#include "draw_vertex.h" #include "rtasm/rtasm_x86sse.h" @@ -249,24 +250,27 @@ static boolean emit_output( struct aos_compilation *cp, unsigned format ) { switch (format) { - case PIPE_FORMAT_R32_FLOAT: + case EMIT_1F: + case EMIT_1F_PSIZE: emit_store_R32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32_FLOAT: + case EMIT_2F: emit_store_R32G32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32B32_FLOAT: + case EMIT_3F: emit_store_R32G32B32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: + case EMIT_4F: emit_store_R32G32B32A32(cp, ptr, dataXMM); break; - case PIPE_FORMAT_B8G8R8A8_UNORM: - emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + case EMIT_4UB: + if (1) { + emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + } + else { + emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM); + } break; default: ERROR(cp, "unhandled output format"); @@ -287,9 +291,16 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) unsigned offset = cp->vaos->base.key.element[i].out.offset; unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output; - struct x86_reg data = aos_get_shader_reg( cp, - TGSI_FILE_OUTPUT, - vs_output ); + struct x86_reg data; + + if (format == EMIT_1F_PSIZE) { + data = aos_get_internal_xmm( cp, IMM_PSIZE ); + } + else { + data = aos_get_shader_reg( cp, + TGSI_FILE_OUTPUT, + vs_output ); + } if (data.file != file_XMM) { struct x86_reg tmp = aos_get_xmm_reg( cp ); diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index dab46e8eed..119a3a04b5 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -231,6 +231,10 @@ static void vsvg_run_linear( struct draw_vs_varient *varient, output_buffer, vsvg->base.key.output_stride ); + vsvg->emit->set_buffer( vsvg->emit, + 1, + &vsvg->draw->rasterizer->point_size, + 0); vsvg->emit->run( vsvg->emit, 0, count, @@ -293,11 +297,21 @@ struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs, emit.nr_elements = key->nr_outputs; emit.output_stride = key->output_stride; for (i = 0; i < key->nr_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; + if (key->element[i].out.format != EMIT_1F_PSIZE) + { + 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].output_format = draw_translate_vinfo_format(key->element[i].out.format); + emit.element[i].output_offset = key->element[i].out.offset; + } + else { + emit.element[i].input_format = PIPE_FORMAT_R32_FLOAT; + emit.element[i].input_buffer = 1; + emit.element[i].input_offset = 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 ); -- cgit v1.2.3