mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-15 02:20:29 +01:00
draw: turn fse path into a middle end
Also add some util functions in pt_util.c
This commit is contained in:
parent
44463b2997
commit
bbda45ec76
11 changed files with 847 additions and 118 deletions
|
|
@ -27,8 +27,10 @@ C_SOURCES = \
|
|||
draw_pt_fetch.c \
|
||||
draw_pt_fetch_emit.c \
|
||||
draw_pt_fetch_shade_emit.c \
|
||||
draw_pt_middle_fse.c \
|
||||
draw_pt_fetch_shade_pipeline.c \
|
||||
draw_pt_post_vs.c \
|
||||
draw_pt_util.c \
|
||||
draw_pt_varray.c \
|
||||
draw_pt_vcache.c \
|
||||
draw_vertex.c \
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ struct draw_context
|
|||
struct {
|
||||
struct {
|
||||
struct draw_pt_middle_end *fetch_emit;
|
||||
/*struct draw_pt_middle_end *fetch_shade_emit;*/
|
||||
struct draw_pt_middle_end *fetch_shade_emit;
|
||||
struct draw_pt_middle_end *general;
|
||||
} middle;
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ draw_pt_arrays(struct draw_context *draw,
|
|||
|
||||
if (opt == 0)
|
||||
middle = draw->pt.middle.fetch_emit;
|
||||
else if (opt == PT_SHADE && draw->pt.test_fse)
|
||||
middle = draw->pt.middle.fetch_shade_emit;
|
||||
else
|
||||
middle = draw->pt.middle.general;
|
||||
|
||||
|
|
@ -83,9 +85,11 @@ draw_pt_arrays(struct draw_context *draw,
|
|||
*/
|
||||
if (draw->pt.user.elts || (opt & PT_PIPELINE)) {
|
||||
frontend = draw->pt.front.vcache;
|
||||
#if 0
|
||||
} else if (opt == PT_SHADE && draw->pt.test_fse) {
|
||||
/* should be a middle end.. */
|
||||
frontend = draw->pt.front.fetch_shade_emit;
|
||||
#endif
|
||||
} else {
|
||||
frontend = draw->pt.front.varray;
|
||||
}
|
||||
|
|
@ -105,6 +109,8 @@ draw_pt_arrays(struct draw_context *draw,
|
|||
|
||||
boolean draw_pt_init( struct draw_context *draw )
|
||||
{
|
||||
draw->pt.test_fse = GETENV("DRAW_FSE") != NULL;
|
||||
|
||||
draw->pt.front.vcache = draw_pt_vcache( draw );
|
||||
if (!draw->pt.front.vcache)
|
||||
return FALSE;
|
||||
|
|
@ -117,8 +123,11 @@ boolean draw_pt_init( struct draw_context *draw )
|
|||
if (!draw->pt.middle.fetch_emit)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.test_fse = GETENV("DRAW_FSE") != NULL;
|
||||
if (draw->pt.test_fse) {
|
||||
draw->pt.middle.fetch_shade_emit = draw_pt_middle_fse( draw );
|
||||
if (!draw->pt.middle.fetch_shade_emit)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.front.fetch_shade_emit = draw_pt_fetch_shade_emit( draw );
|
||||
if (!draw->pt.front.fetch_shade_emit)
|
||||
return FALSE;
|
||||
|
|
@ -145,6 +154,11 @@ void draw_pt_destroy( struct draw_context *draw )
|
|||
draw->pt.middle.fetch_emit = NULL;
|
||||
}
|
||||
|
||||
if (draw->pt.middle.fetch_shade_emit) {
|
||||
draw->pt.middle.fetch_shade_emit->destroy( draw->pt.middle.fetch_shade_emit );
|
||||
draw->pt.middle.fetch_shade_emit = NULL;
|
||||
}
|
||||
|
||||
if (draw->pt.front.fetch_shade_emit) {
|
||||
draw->pt.front.fetch_shade_emit->destroy( draw->pt.front.fetch_shade_emit );
|
||||
draw->pt.front.fetch_shade_emit = NULL;
|
||||
|
|
@ -163,19 +177,6 @@ void draw_pt_destroy( struct draw_context *draw )
|
|||
|
||||
|
||||
|
||||
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw vertex arrays
|
||||
|
|
@ -188,9 +189,10 @@ void
|
|||
draw_arrays(struct draw_context *draw, unsigned prim,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
if (reduced_prim[prim] != draw->reduced_prim) {
|
||||
unsigned reduced_prim = draw_pt_reduced_prim(prim);
|
||||
if (reduced_prim != draw->reduced_prim) {
|
||||
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
||||
draw->reduced_prim = reduced_prim[prim];
|
||||
draw->reduced_prim = reduced_prim;
|
||||
}
|
||||
|
||||
/* drawing done here: */
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw );
|
|||
* vertex_elements.
|
||||
*/
|
||||
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
|
||||
//struct draw_pt_middle_end *draw_pt_fetch_shade_emit( struct draw_context *draw );
|
||||
struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw );
|
||||
struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw);
|
||||
|
||||
|
||||
|
|
@ -213,4 +213,11 @@ struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw );
|
|||
void draw_pt_post_vs_destroy( struct pt_post_vs *pvs );
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Utils:
|
||||
*/
|
||||
void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr);
|
||||
unsigned draw_pt_reduced_prim(unsigned prim);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -434,43 +434,6 @@ static void fse_prepare( struct draw_pt_front_end *fe,
|
|||
}
|
||||
|
||||
|
||||
static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
|
||||
{
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
*first = 1;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINES:
|
||||
*first = 2;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
*first = 2;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
*first = 3;
|
||||
*incr = 3;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUADS:
|
||||
*first = 4;
|
||||
*incr = 4;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
*first = 4;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
default:
|
||||
*first = 0;
|
||||
*incr = 1; /* set to one so that count % incr works */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -596,7 +559,7 @@ fse_run(struct draw_pt_front_end *fe,
|
|||
|
||||
//debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count);
|
||||
|
||||
split_prim_inplace(fse->prim, &first, &incr);
|
||||
draw_pt_split_prim(fse->prim, &first, &incr);
|
||||
|
||||
count -= (count - first) % incr;
|
||||
|
||||
|
|
|
|||
705
src/gallium/auxiliary/draw/draw_pt_middle_fse.c
Normal file
705
src/gallium/auxiliary/draw/draw_pt_middle_fse.c
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#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_pt.h"
|
||||
#include "draw/draw_vs.h"
|
||||
|
||||
#include "translate/translate.h"
|
||||
|
||||
struct fetch_shade_emit;
|
||||
|
||||
struct fse_shader {
|
||||
struct translate_key key;
|
||||
|
||||
void (*run_linear)( const struct fetch_shade_emit *fse,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
char *buffer );
|
||||
|
||||
void (*run_elts)( const struct fetch_shade_emit *fse,
|
||||
const unsigned *fetch_elts,
|
||||
unsigned fetch_count,
|
||||
char *buffer );
|
||||
|
||||
};
|
||||
|
||||
/* Prototype fetch, shade, emit-hw-verts all in one go.
|
||||
*/
|
||||
struct fetch_shade_emit {
|
||||
struct draw_pt_middle_end base;
|
||||
struct draw_context *draw;
|
||||
|
||||
struct translate_key key;
|
||||
|
||||
/* Temporaries:
|
||||
*/
|
||||
const float *constants;
|
||||
unsigned pitch[PIPE_MAX_ATTRIBS];
|
||||
const ubyte *src[PIPE_MAX_ATTRIBS];
|
||||
unsigned prim;
|
||||
|
||||
/* Points to one of the three hardwired example shaders, below:
|
||||
*/
|
||||
struct fse_shader *active;
|
||||
|
||||
/* Temporary: A list of hard-wired shaders. Of course the plan
|
||||
* would be to generate these for a given (vertex-shader,
|
||||
* translate-key) pair...
|
||||
*/
|
||||
struct fse_shader shader[10];
|
||||
int nr_shaders;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Not quite passthrough yet -- we're still running the 'shader' here,
|
||||
* inlined into the vertex fetch function.
|
||||
*/
|
||||
static void shader0_run_linear( const struct fetch_shade_emit *fse,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
const float *m = fse->constants;
|
||||
const ubyte *xyz = fse->src[0] + start * fse->pitch[0];
|
||||
const ubyte *rgb = fse->src[1] + start * fse->pitch[1];
|
||||
const ubyte *st = fse->src[2] + start * fse->pitch[2];
|
||||
|
||||
float *out = (float *)buffer;
|
||||
|
||||
/* loop over vertex attributes (vertex shader inputs)
|
||||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
{
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
xyz += fse->pitch[0];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)rgb;
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = 1.0f;
|
||||
rgb += fse->pitch[1];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)st;
|
||||
out[8] = in[0];
|
||||
out[9] = in[1];
|
||||
out[10] = 0.0f;
|
||||
out[11] = 1.0f;
|
||||
st += fse->pitch[2];
|
||||
}
|
||||
|
||||
out += 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void shader1_run_linear( const struct fetch_shade_emit *fse,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
const float *m = (const float *)fse->constants;
|
||||
const ubyte *xyz = fse->src[0] + start * fse->pitch[0];
|
||||
const ubyte *rgb = fse->src[1] + start * fse->pitch[1];
|
||||
float *out = (float *)buffer;
|
||||
|
||||
// debug_printf("rgb %f %f %f\n", rgb[0], rgb[1], rgb[2]);
|
||||
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
{
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
xyz += fse->pitch[0];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)rgb;
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = 1.0f;
|
||||
rgb += fse->pitch[1];
|
||||
}
|
||||
|
||||
out += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void shader2_run_linear( const struct fetch_shade_emit *fse,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
const float *m = (const float *)fse->constants;
|
||||
const ubyte *xyz = fse->src[0] + start * fse->pitch[0];
|
||||
const ubyte *rgb = fse->src[1] + start * fse->pitch[1];
|
||||
const float psiz = 1.0;
|
||||
float *out = (float *)buffer;
|
||||
|
||||
|
||||
assert(fse->pitch[1] == 0);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
{
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
xyz += fse->pitch[0];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)rgb;
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = 1.0f;
|
||||
rgb += fse->pitch[1];
|
||||
}
|
||||
|
||||
{
|
||||
out[8] = psiz;
|
||||
}
|
||||
|
||||
out += 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void shader0_run_elts( const struct fetch_shade_emit *fse,
|
||||
const unsigned *elts,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
const float *m = fse->constants;
|
||||
float *out = (float *)buffer;
|
||||
|
||||
|
||||
/* loop over vertex attributes (vertex shader inputs)
|
||||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned elt = elts[i];
|
||||
{
|
||||
const ubyte *xyz = fse->src[0] + elt * fse->pitch[0];
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
}
|
||||
|
||||
{
|
||||
const ubyte *rgb = fse->src[1] + elt * fse->pitch[1];
|
||||
const float *in = (const float *)rgb;
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = 1.0f;
|
||||
}
|
||||
|
||||
{
|
||||
const ubyte *st = fse->src[2] + elt * fse->pitch[2];
|
||||
const float *in = (const float *)st;
|
||||
out[8] = in[0];
|
||||
out[9] = in[1];
|
||||
out[10] = 0.0f;
|
||||
out[11] = 1.0f;
|
||||
}
|
||||
|
||||
out += 12;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void shader1_run_elts( const struct fetch_shade_emit *fse,
|
||||
const unsigned *elts,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
const float *m = (const float *)fse->constants;
|
||||
float *out = (float *)buffer;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned elt = elts[i];
|
||||
|
||||
{
|
||||
const ubyte *xyz = fse->src[0] + elt * fse->pitch[0];
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
xyz += fse->pitch[0];
|
||||
}
|
||||
|
||||
{
|
||||
const ubyte *rgb = fse->src[1] + elt * fse->pitch[1];
|
||||
const float *in = (const float *)rgb;
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = 1.0f;
|
||||
rgb += fse->pitch[1];
|
||||
}
|
||||
|
||||
out += 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void shader2_run_elts( const struct fetch_shade_emit *fse,
|
||||
const unsigned *elts,
|
||||
unsigned count,
|
||||
char *buffer )
|
||||
{
|
||||
unsigned i;
|
||||
const float *m = (const float *)fse->constants;
|
||||
const float psiz = 1.0;
|
||||
float *out = (float *)buffer;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned elt = elts[i];
|
||||
{
|
||||
const ubyte *xyz = fse->src[0] + elt * fse->pitch[0];
|
||||
const float *in = (const float *)xyz;
|
||||
const float ix = in[0], iy = in[1], iz = in[2];
|
||||
|
||||
out[0] = m[0] * ix + m[4] * iy + m[8] * iz + m[12];
|
||||
out[1] = m[1] * ix + m[5] * iy + m[9] * iz + m[13];
|
||||
out[2] = m[2] * ix + m[6] * iy + m[10] * iz + m[14];
|
||||
out[3] = m[3] * ix + m[7] * iy + m[11] * iz + m[15];
|
||||
}
|
||||
|
||||
{
|
||||
const ubyte *rgb = fse->src[1] + elt * fse->pitch[1];
|
||||
out[4] = rgb[0];
|
||||
out[5] = rgb[1];
|
||||
out[6] = rgb[2];
|
||||
out[7] = 1.0f;
|
||||
}
|
||||
|
||||
{
|
||||
out[8] = psiz;
|
||||
}
|
||||
|
||||
out += 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void fse_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
unsigned num_vs_inputs = draw->vertex_shader->info.num_inputs;
|
||||
unsigned num_vs_outputs = draw->vertex_shader->info.num_outputs;
|
||||
const struct vertex_info *vinfo;
|
||||
unsigned i;
|
||||
boolean need_psize = 0;
|
||||
|
||||
|
||||
if (draw->pt.user.elts) {
|
||||
assert(0);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!draw->render->set_primitive( draw->render,
|
||||
prim )) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Must do this after set_primitive() above:
|
||||
*/
|
||||
vinfo = draw->render->get_vertex_info(draw->render);
|
||||
|
||||
|
||||
|
||||
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;
|
||||
memset(fse->key.element, 0,
|
||||
fse->key.nr_elements * sizeof(fse->key.element[0]));
|
||||
|
||||
for (i = 0; i < num_vs_inputs; i++) {
|
||||
const struct pipe_vertex_element *src = &draw->pt.vertex_element[i];
|
||||
fse->key.element[i].input_format = src->src_format;
|
||||
|
||||
/* Consider ignoring these at this point, ie make generated
|
||||
* programs independent of this state:
|
||||
*/
|
||||
fse->key.element[i].input_buffer = 0; //src->vertex_buffer_index;
|
||||
fse->key.element[i].input_offset = 0; //src->src_offset;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
unsigned dst_offset = 0;
|
||||
|
||||
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 = num_vs_outputs + 1;
|
||||
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The elements in the key correspond to vertex shader output
|
||||
* numbers, not to positions in the hw vertex description --
|
||||
* that's handled by the output_offset field.
|
||||
*/
|
||||
fse->key.element[vs_output].output_format = output_format;
|
||||
fse->key.element[vs_output].output_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_elements += 1;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
fse->constants = draw->pt.user.constants;
|
||||
|
||||
/* Would normally look up a vertex shader and peruse its list of
|
||||
* varients somehow. We omitted that step and put all the
|
||||
* hardcoded "shaders" into an array. We're just making the
|
||||
* assumption that this happens to be a matching shader... ie
|
||||
* you're running isosurf, aren't you?
|
||||
*/
|
||||
fse->active = NULL;
|
||||
for (i = 0; i < fse->nr_shaders; i++) {
|
||||
if (translate_key_compare( &fse->key, &fse->shader[i].key) == 0)
|
||||
fse->active = &fse->shader[i];
|
||||
}
|
||||
|
||||
if (!fse->active) {
|
||||
assert(0);
|
||||
return ;
|
||||
}
|
||||
|
||||
/* Now set buffer pointers:
|
||||
*/
|
||||
for (i = 0; i < num_vs_inputs; i++) {
|
||||
unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index;
|
||||
|
||||
fse->src[i] = ((const ubyte *) draw->pt.user.vbuffer[buf] +
|
||||
draw->pt.vertex_buffer[buf].buffer_offset +
|
||||
draw->pt.vertex_element[i].src_offset);
|
||||
|
||||
fse->pitch[i] = draw->pt.vertex_buffer[buf].pitch;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void fse_run_linear( struct draw_pt_middle_end *middle,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
|
||||
char *hw_verts;
|
||||
|
||||
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
|
||||
*/
|
||||
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
|
||||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)fse->key.output_stride,
|
||||
(ushort)count );
|
||||
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Single routine to fetch vertices, run shader and emit HW verts.
|
||||
* Clipping and viewport transformation are done elsewhere --
|
||||
* either by the API or on hardware, or for some other reason not
|
||||
* required...
|
||||
*/
|
||||
fse->active->run_linear( fse,
|
||||
start, count,
|
||||
hw_verts );
|
||||
|
||||
/* Draw arrays path to avoid re-emitting index list again and
|
||||
* again.
|
||||
*/
|
||||
draw->render->draw_arrays( draw->render,
|
||||
0,
|
||||
count );
|
||||
|
||||
|
||||
draw->render->release_vertices( draw->render,
|
||||
hw_verts,
|
||||
fse->key.output_stride,
|
||||
count );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fse_run(struct draw_pt_middle_end *middle,
|
||||
const unsigned *fetch_elts,
|
||||
unsigned fetch_count,
|
||||
const ushort *draw_elts,
|
||||
unsigned draw_count )
|
||||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
void *hw_verts;
|
||||
|
||||
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
|
||||
*/
|
||||
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
|
||||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)fse->key.output_stride,
|
||||
(ushort)fetch_count );
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Single routine to fetch vertices, run shader and emit HW verts.
|
||||
*/
|
||||
fse->active->run_elts( fse,
|
||||
fetch_elts,
|
||||
fetch_count,
|
||||
hw_verts );
|
||||
|
||||
draw->render->draw( draw->render,
|
||||
draw_elts,
|
||||
draw_count );
|
||||
|
||||
draw->render->release_vertices( draw->render,
|
||||
hw_verts,
|
||||
fse->key.output_stride,
|
||||
fetch_count );
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void fse_finish( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fse_destroy( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
FREE(middle);
|
||||
}
|
||||
|
||||
struct draw_pt_middle_end *draw_pt_middle_fse( struct draw_context *draw )
|
||||
{
|
||||
struct fetch_shade_emit *fse = CALLOC_STRUCT(fetch_shade_emit);
|
||||
if (!fse)
|
||||
return NULL;
|
||||
|
||||
fse->base.prepare = fse_prepare;
|
||||
fse->base.run = fse_run;
|
||||
fse->base.run_linear = fse_run_linear;
|
||||
fse->base.finish = fse_finish;
|
||||
fse->base.destroy = fse_destroy;
|
||||
fse->draw = draw;
|
||||
|
||||
fse->shader[0].run_linear = shader0_run_linear;
|
||||
fse->shader[0].run_elts = shader0_run_elts;
|
||||
fse->shader[0].key.nr_elements = 3;
|
||||
fse->shader[0].key.output_stride = 12 * sizeof(float);
|
||||
|
||||
fse->shader[0].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[0].key.element[0].input_buffer = 0;
|
||||
fse->shader[0].key.element[0].input_offset = 0;
|
||||
fse->shader[0].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[0].key.element[0].output_offset = 0;
|
||||
|
||||
fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[0].key.element[1].input_buffer = 0;
|
||||
fse->shader[0].key.element[1].input_offset = 0;
|
||||
fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[0].key.element[1].output_offset = 16;
|
||||
|
||||
fse->shader[0].key.element[1].input_format = PIPE_FORMAT_R32G32_FLOAT;
|
||||
fse->shader[0].key.element[1].input_buffer = 0;
|
||||
fse->shader[0].key.element[1].input_offset = 0;
|
||||
fse->shader[0].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[0].key.element[1].output_offset = 32;
|
||||
|
||||
fse->shader[1].run_linear = shader1_run_linear;
|
||||
fse->shader[1].run_elts = shader1_run_elts;
|
||||
fse->shader[1].key.nr_elements = 2;
|
||||
fse->shader[1].key.output_stride = 8 * sizeof(float);
|
||||
|
||||
fse->shader[1].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[1].key.element[0].input_buffer = 0;
|
||||
fse->shader[1].key.element[0].input_offset = 0;
|
||||
fse->shader[1].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[1].key.element[0].output_offset = 0;
|
||||
|
||||
fse->shader[1].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[1].key.element[1].input_buffer = 0;
|
||||
fse->shader[1].key.element[1].input_offset = 0;
|
||||
fse->shader[1].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[1].key.element[1].output_offset = 16;
|
||||
|
||||
fse->shader[2].run_linear = shader2_run_linear;
|
||||
fse->shader[2].run_elts = shader2_run_elts;
|
||||
fse->shader[2].key.nr_elements = 3;
|
||||
fse->shader[2].key.output_stride = 9 * sizeof(float);
|
||||
|
||||
fse->shader[2].key.element[0].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[2].key.element[0].input_buffer = 0;
|
||||
fse->shader[2].key.element[0].input_offset = 0;
|
||||
fse->shader[2].key.element[0].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[2].key.element[0].output_offset = 0;
|
||||
|
||||
fse->shader[2].key.element[1].input_format = PIPE_FORMAT_R32G32B32_FLOAT;
|
||||
fse->shader[2].key.element[1].input_buffer = 0;
|
||||
fse->shader[2].key.element[1].input_offset = 0;
|
||||
fse->shader[2].key.element[1].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
fse->shader[2].key.element[1].output_offset = 16;
|
||||
|
||||
/* psize is special
|
||||
* -- effectively add it here as another input!?!
|
||||
* -- who knows how to add it as a buffer?
|
||||
*/
|
||||
fse->shader[2].key.element[2].input_format = PIPE_FORMAT_R32_FLOAT;
|
||||
fse->shader[2].key.element[2].input_buffer = 0;
|
||||
fse->shader[2].key.element[2].input_offset = 0;
|
||||
fse->shader[2].key.element[2].output_format = PIPE_FORMAT_R32_FLOAT;
|
||||
fse->shader[2].key.element[2].output_offset = 32;
|
||||
|
||||
fse->nr_shaders = 3;
|
||||
|
||||
return &fse->base;
|
||||
}
|
||||
103
src/gallium/auxiliary/draw/draw_pt_util.c
Normal file
103
src/gallium/auxiliary/draw/draw_pt_util.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_private.h"
|
||||
#include "draw/draw_pt.h"
|
||||
|
||||
void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
|
||||
{
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
*first = 1;
|
||||
*incr = 1;
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
*first = 2;
|
||||
*incr = 2;
|
||||
break;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
*first = 2;
|
||||
*incr = 1;
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
*first = 3;
|
||||
*incr = 3;
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
case PIPE_PRIM_POLYGON:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
break;
|
||||
case PIPE_PRIM_QUADS:
|
||||
*first = 4;
|
||||
*incr = 4;
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
*first = 4;
|
||||
*incr = 2;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
*first = 0;
|
||||
*incr = 1; /* set to one so that count % incr works */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned draw_pt_reduced_prim(unsigned prim)
|
||||
{
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
return PIPE_PRIM_POINTS;
|
||||
case PIPE_PRIM_LINES:
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
return PIPE_PRIM_LINES;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
case PIPE_PRIM_POLYGON:
|
||||
case PIPE_PRIM_QUADS:
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
default:
|
||||
assert(0);
|
||||
return PIPE_PRIM_POINTS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -106,51 +106,6 @@ static INLINE void fetch_init(struct varray_frontend *varray,
|
|||
}
|
||||
|
||||
|
||||
static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
|
||||
{
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
*first = 1;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINES:
|
||||
*first = 2;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
*first = 2;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
*first = 3;
|
||||
*incr = 3;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUADS:
|
||||
*first = 4;
|
||||
*incr = 4;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
*first = 4;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_POLYGON:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
default:
|
||||
*first = 0;
|
||||
*incr = 1; /* set to one so that count % incr works */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE void add_draw_el(struct varray_frontend *varray,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
|
||||
varray->fetch_start = start;
|
||||
|
||||
split_prim_inplace(varray->input_prim, &first, &incr);
|
||||
draw_pt_split_prim(varray->input_prim, &first, &incr);
|
||||
|
||||
#if 0
|
||||
debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,13 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
|
||||
varray->fetch_start = start;
|
||||
|
||||
split_prim_inplace(varray->input_prim, &first, &incr);
|
||||
draw_pt_split_prim(varray->input_prim, &first, &incr);
|
||||
|
||||
/* Sanitize primitive length:
|
||||
*/
|
||||
count = trim(count, first, incr);
|
||||
if (count < first)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
|
||||
|
|
@ -32,7 +38,6 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
case PIPE_PRIM_QUADS:
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
|
||||
for (j = 0; j < count;) {
|
||||
unsigned remaining = count - j;
|
||||
unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr );
|
||||
|
|
|
|||
|
|
@ -204,19 +204,6 @@ static void vcache_ef_quad( struct vcache_frontend *vcache,
|
|||
|
||||
|
||||
|
||||
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void vcache_prepare( struct draw_pt_front_end *frontend,
|
||||
|
|
@ -236,7 +223,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
|
|||
}
|
||||
|
||||
vcache->input_prim = prim;
|
||||
vcache->output_prim = reduced_prim[prim];
|
||||
vcache->output_prim = draw_pt_reduced_prim(prim);
|
||||
|
||||
vcache->middle = middle;
|
||||
middle->prepare( middle, vcache->output_prim, opt );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue