draw: add passthrough path to the pipeline
This handles the case where bypass_vs is set, but vertices need to go through the pipeline for some reason - eg unfilled polygon mode. Demonstrates how to drive the pipeline from inside one of these things.
This commit is contained in:
parent
add46fbc8c
commit
d2cb4ba0bb
|
@ -18,6 +18,7 @@ C_SOURCES = \
|
||||||
draw_pt.c \
|
draw_pt.c \
|
||||||
draw_pt_vcache.c \
|
draw_pt_vcache.c \
|
||||||
draw_pt_fetch_emit.c \
|
draw_pt_fetch_emit.c \
|
||||||
|
draw_pt_fetch_pipeline.c \
|
||||||
draw_pt_elts.c \
|
draw_pt_elts.c \
|
||||||
draw_prim.c \
|
draw_prim.c \
|
||||||
draw_pstipple.c \
|
draw_pstipple.c \
|
||||||
|
|
|
@ -17,6 +17,7 @@ draw = env.ConvenienceLibrary(
|
||||||
'draw_pt.c',
|
'draw_pt.c',
|
||||||
'draw_pt_vcache.c',
|
'draw_pt_vcache.c',
|
||||||
'draw_pt_fetch_emit.c',
|
'draw_pt_fetch_emit.c',
|
||||||
|
'draw_pt_fetch_pipeline.c',
|
||||||
'draw_pt_elts.c',
|
'draw_pt_elts.c',
|
||||||
'draw_prim.c',
|
'draw_prim.c',
|
||||||
'draw_pstipple.c',
|
'draw_pstipple.c',
|
||||||
|
|
|
@ -160,6 +160,11 @@ struct draw_vertex_shader {
|
||||||
/* Internal function for vertex fetch.
|
/* Internal function for vertex fetch.
|
||||||
*/
|
*/
|
||||||
typedef void (*fetch_func)(const void *ptr, float *attrib);
|
typedef void (*fetch_func)(const void *ptr, float *attrib);
|
||||||
|
|
||||||
|
fetch_func draw_get_fetch_func( enum pipe_format format );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*full_fetch_func)( struct draw_context *draw,
|
typedef void (*full_fetch_func)( struct draw_context *draw,
|
||||||
struct tgsi_exec_machine *machine,
|
struct tgsi_exec_machine *machine,
|
||||||
const unsigned *elts,
|
const unsigned *elts,
|
||||||
|
@ -211,6 +216,7 @@ struct draw_context
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct draw_pt_middle_end *fetch_emit;
|
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_emit;
|
||||||
struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit;
|
struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit;
|
||||||
} middle;
|
} middle;
|
||||||
|
|
|
@ -73,7 +73,6 @@ draw_pt_arrays(struct draw_context *draw,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!cliptest && !pipeline && !shading) {
|
if (!cliptest && !pipeline && !shading) {
|
||||||
/* This is the 'passthrough' path:
|
/* This is the 'passthrough' path:
|
||||||
*/
|
*/
|
||||||
|
@ -81,6 +80,14 @@ draw_pt_arrays(struct draw_context *draw,
|
||||||
*/
|
*/
|
||||||
middle = draw->pt.middle.fetch_emit;
|
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;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
else if (!cliptest && !pipeline) {
|
else if (!cliptest && !pipeline) {
|
||||||
/* Fetch user verts, run vertex shader, emit hw verts:
|
/* Fetch user verts, run vertex shader, emit hw verts:
|
||||||
*/
|
*/
|
||||||
|
@ -117,10 +124,9 @@ draw_pt_arrays(struct draw_context *draw,
|
||||||
middle = draw->pt.middle.fetch_shade_cliptest_pipeline;
|
middle = draw->pt.middle.fetch_shade_cliptest_pipeline;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (cliptest || pipeline || shading)
|
else {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
middle = draw->pt.middle.fetch_emit;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,6 +196,10 @@ boolean draw_pt_init( struct draw_context *draw )
|
||||||
if (!draw->pt.middle.fetch_emit)
|
if (!draw->pt.middle.fetch_emit)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw );
|
||||||
|
if (!draw->pt.middle.fetch_pipeline)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
draw->pt.front.vcache = draw_pt_vcache( draw );
|
draw->pt.front.vcache = draw_pt_vcache( draw );
|
||||||
if (!draw->pt.front.vcache)
|
if (!draw->pt.front.vcache)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -205,6 +215,11 @@ void draw_pt_destroy( struct draw_context *draw )
|
||||||
draw->pt.middle.fetch_emit = NULL;
|
draw->pt.middle.fetch_emit = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.front.vcache) {
|
if (draw->pt.front.vcache) {
|
||||||
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
|
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
|
||||||
draw->pt.front.vcache = NULL;
|
draw->pt.front.vcache = NULL;
|
||||||
|
|
|
@ -112,6 +112,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw,
|
||||||
*/
|
*/
|
||||||
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
|
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
|
||||||
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
|
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
|
||||||
|
struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,45 +85,6 @@ struct fetch_emit_middle_end {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void fetch_B8G8R8A8_UNORM( const void *from,
|
|
||||||
float *attrib )
|
|
||||||
{
|
|
||||||
ubyte *ub = (ubyte *) from;
|
|
||||||
attrib[2] = UBYTE_TO_FLOAT(ub[0]);
|
|
||||||
attrib[1] = UBYTE_TO_FLOAT(ub[1]);
|
|
||||||
attrib[0] = UBYTE_TO_FLOAT(ub[2]);
|
|
||||||
attrib[3] = UBYTE_TO_FLOAT(ub[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fetch_R32G32B32A32_FLOAT( const void *from,
|
|
||||||
float *attrib )
|
|
||||||
{
|
|
||||||
float *f = (float *) from;
|
|
||||||
attrib[0] = f[0];
|
|
||||||
attrib[1] = f[1];
|
|
||||||
attrib[2] = f[2];
|
|
||||||
attrib[3] = f[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fetch_R32G32B32_FLOAT( const void *from,
|
|
||||||
float *attrib )
|
|
||||||
{
|
|
||||||
float *f = (float *) from;
|
|
||||||
attrib[0] = f[0];
|
|
||||||
attrib[1] = f[1];
|
|
||||||
attrib[2] = f[2];
|
|
||||||
attrib[3] = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fetch_R32G32_FLOAT( const void *from,
|
|
||||||
float *attrib )
|
|
||||||
{
|
|
||||||
float *f = (float *) from;
|
|
||||||
attrib[0] = f[0];
|
|
||||||
attrib[1] = f[1];
|
|
||||||
attrib[2] = 0.0;
|
|
||||||
attrib[3] = 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fetch_R32_FLOAT( const void *from,
|
static void fetch_R32_FLOAT( const void *from,
|
||||||
float *attrib )
|
float *attrib )
|
||||||
|
@ -235,28 +196,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
|
||||||
|
|
||||||
feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch;
|
feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch;
|
||||||
|
|
||||||
switch (draw->vertex_element[src_element].src_format) {
|
feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format);
|
||||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
|
||||||
feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
|
||||||
feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
|
||||||
feme->fetch[i].fetch = fetch_R32G32B32_FLOAT;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R32G32_FLOAT:
|
|
||||||
feme->fetch[i].fetch = fetch_R32G32_FLOAT;
|
|
||||||
break;
|
|
||||||
case PIPE_FORMAT_R32_FLOAT:
|
|
||||||
feme->fetch[i].fetch = fetch_R32_FLOAT;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
feme->fetch[i].fetch = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (vinfo->emit[i]) {
|
switch (vinfo->emit[i]) {
|
||||||
case EMIT_4F:
|
case EMIT_4F:
|
||||||
feme->fetch[i].emit = emit_R32G32B32A32_FLOAT;
|
feme->fetch[i].emit = emit_R32G32B32A32_FLOAT;
|
||||||
|
|
|
@ -0,0 +1,391 @@
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* 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_vertex.h"
|
||||||
|
#include "draw/draw_pt.h"
|
||||||
|
|
||||||
|
/* The simplest 'middle end' in the new vertex code.
|
||||||
|
*
|
||||||
|
* The responsibilities of a middle end are to:
|
||||||
|
* - perform vertex fetch using
|
||||||
|
* - draw vertex element/buffer state
|
||||||
|
* - a list of fetch indices we received as an input
|
||||||
|
* - run the vertex shader
|
||||||
|
* - cliptest,
|
||||||
|
* - clip coord calculation
|
||||||
|
* - viewport transformation
|
||||||
|
* - if necessary, run the primitive pipeline, passing it:
|
||||||
|
* - a linear array of vertex_header vertices constructed here
|
||||||
|
* - a set of draw indices we received as an input
|
||||||
|
* - otherwise, drive the hw backend,
|
||||||
|
* - allocate space for hardware format vertices
|
||||||
|
* - translate the vertex-shader output vertices to hw format
|
||||||
|
* - calling the backend draw functions.
|
||||||
|
*
|
||||||
|
* For convenience, we provide a helper function to drive the hardware
|
||||||
|
* backend given similar inputs to those required to run the pipeline.
|
||||||
|
*
|
||||||
|
* In the case of passthrough mode, many of these actions are disabled
|
||||||
|
* or noops, so we end up doing:
|
||||||
|
*
|
||||||
|
* - perform vertex fetch
|
||||||
|
* - drive the hw backend
|
||||||
|
*
|
||||||
|
* IE, basically just vertex fetch to post-vs-format vertices,
|
||||||
|
* followed by a call to the backend helper function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct fetch_pipeline_middle_end {
|
||||||
|
struct draw_pt_middle_end base;
|
||||||
|
struct draw_context *draw;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const ubyte *ptr;
|
||||||
|
unsigned pitch;
|
||||||
|
void (*fetch)( const void *from, float *attrib);
|
||||||
|
void (*emit)( const float *attrib, float **out );
|
||||||
|
} fetch[PIPE_MAX_ATTRIBS];
|
||||||
|
|
||||||
|
unsigned nr_fetch;
|
||||||
|
unsigned pipeline_vertex_size;
|
||||||
|
unsigned prim;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void fetch_NULL( const void *from,
|
||||||
|
float *attrib )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void emit_R32_FLOAT( const float *attrib,
|
||||||
|
float **out )
|
||||||
|
{
|
||||||
|
(*out)[0] = attrib[0];
|
||||||
|
(*out) += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_R32G32_FLOAT( const float *attrib,
|
||||||
|
float **out )
|
||||||
|
{
|
||||||
|
(*out)[0] = attrib[0];
|
||||||
|
(*out)[1] = attrib[1];
|
||||||
|
(*out) += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_R32G32B32_FLOAT( const float *attrib,
|
||||||
|
float **out )
|
||||||
|
{
|
||||||
|
(*out)[0] = attrib[0];
|
||||||
|
(*out)[1] = attrib[1];
|
||||||
|
(*out)[2] = attrib[2];
|
||||||
|
(*out) += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_R32G32B32A32_FLOAT( const float *attrib,
|
||||||
|
float **out )
|
||||||
|
{
|
||||||
|
(*out)[0] = attrib[0];
|
||||||
|
(*out)[1] = attrib[1];
|
||||||
|
(*out)[2] = attrib[2];
|
||||||
|
(*out)[3] = attrib[3];
|
||||||
|
(*out) += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_header( const float *attrib,
|
||||||
|
float **out )
|
||||||
|
{
|
||||||
|
(*out)[0] = 0;
|
||||||
|
(*out)[1] = 0;
|
||||||
|
(*out)[2] = 0;
|
||||||
|
(*out)[3] = 0;
|
||||||
|
(*out)[3] = 1;
|
||||||
|
(*out) += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General-purpose fetch from user's vertex arrays, emit to driver's
|
||||||
|
* vertex buffer.
|
||||||
|
*
|
||||||
|
* XXX this is totally temporary.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
fetch_store_general( struct fetch_pipeline_middle_end *fpme,
|
||||||
|
void *out_ptr,
|
||||||
|
const unsigned *fetch_elts,
|
||||||
|
unsigned count )
|
||||||
|
{
|
||||||
|
float *out = (float *)out_ptr;
|
||||||
|
uint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
unsigned elt = fetch_elts[i];
|
||||||
|
|
||||||
|
for (j = 0; j < fpme->nr_fetch; j++) {
|
||||||
|
float attrib[4];
|
||||||
|
const ubyte *from = (fpme->fetch[j].ptr +
|
||||||
|
fpme->fetch[j].pitch * elt);
|
||||||
|
|
||||||
|
fpme->fetch[j].fetch( from, attrib );
|
||||||
|
fpme->fetch[j].emit( attrib, &out );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* We aren't running a vertex shader, but are running the pipeline.
|
||||||
|
* That means the vertices we need to build look like:
|
||||||
|
*
|
||||||
|
* dw0: vertex header (zero?)
|
||||||
|
* dw1: clip coord 0
|
||||||
|
* dw2: clip coord 1
|
||||||
|
* dw3: clip coord 2
|
||||||
|
* dw4: clip coord 4
|
||||||
|
* dw5: screen coord 0
|
||||||
|
* dw6: screen coord 0
|
||||||
|
* dw7: screen coord 0
|
||||||
|
* dw8: screen coord 0
|
||||||
|
* dw9: other attribs...
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
||||||
|
unsigned prim )
|
||||||
|
{
|
||||||
|
static const float zero = 0;
|
||||||
|
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
|
||||||
|
struct draw_context *draw = fpme->draw;
|
||||||
|
unsigned i, nr = 0;
|
||||||
|
|
||||||
|
fpme->prim = prim;
|
||||||
|
|
||||||
|
/* Emit the vertex header and empty clipspace coord field:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
fpme->fetch[nr].ptr = NULL;
|
||||||
|
fpme->fetch[nr].pitch = 0;
|
||||||
|
fpme->fetch[nr].fetch = fetch_NULL;
|
||||||
|
fpme->fetch[nr].emit = emit_header;
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Need to look at vertex shader inputs (we know it is a
|
||||||
|
* passthrough shader, so these define the outputs too). If we
|
||||||
|
* were running a shader, we'd still be looking at the inputs at
|
||||||
|
* this point.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) {
|
||||||
|
unsigned buf = draw->vertex_element[i].vertex_buffer_index;
|
||||||
|
enum pipe_format format = draw->vertex_element[i].src_format;
|
||||||
|
|
||||||
|
fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] +
|
||||||
|
draw->vertex_buffer[buf].buffer_offset +
|
||||||
|
draw->vertex_element[i].src_offset);
|
||||||
|
|
||||||
|
fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch;
|
||||||
|
fpme->fetch[nr].fetch = draw_get_fetch_func( format );
|
||||||
|
|
||||||
|
/* Always do this -- somewhat redundant...
|
||||||
|
*/
|
||||||
|
fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT;
|
||||||
|
nr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fpme->nr_fetch = nr;
|
||||||
|
fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a point to the primitive queue.
|
||||||
|
* \param i0 index into user's vertex arrays
|
||||||
|
*/
|
||||||
|
static void do_point( struct draw_context *draw,
|
||||||
|
const char *v0 )
|
||||||
|
{
|
||||||
|
struct prim_header prim;
|
||||||
|
|
||||||
|
prim.reset_line_stipple = 0;
|
||||||
|
prim.edgeflags = 1;
|
||||||
|
prim.pad = 0;
|
||||||
|
prim.v[0] = (struct vertex_header *)v0;
|
||||||
|
|
||||||
|
draw->pipeline.first->point( draw->pipeline.first, &prim );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a line to the primitive queue.
|
||||||
|
* \param i0 index into user's vertex arrays
|
||||||
|
* \param i1 index into user's vertex arrays
|
||||||
|
*/
|
||||||
|
static void do_line( struct draw_context *draw,
|
||||||
|
const char *v0,
|
||||||
|
const char *v1 )
|
||||||
|
{
|
||||||
|
struct prim_header prim;
|
||||||
|
|
||||||
|
prim.reset_line_stipple = 1; /* fixme */
|
||||||
|
prim.edgeflags = 1;
|
||||||
|
prim.pad = 0;
|
||||||
|
prim.v[0] = (struct vertex_header *)v0;
|
||||||
|
prim.v[1] = (struct vertex_header *)v1;
|
||||||
|
|
||||||
|
draw->pipeline.first->line( draw->pipeline.first, &prim );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a triangle to the primitive queue.
|
||||||
|
*/
|
||||||
|
static void do_triangle( struct draw_context *draw,
|
||||||
|
char *v0,
|
||||||
|
char *v1,
|
||||||
|
char *v2 )
|
||||||
|
{
|
||||||
|
struct prim_header prim;
|
||||||
|
|
||||||
|
// _mesa_printf("tri %d %d %d\n", i0, i1, i2);
|
||||||
|
prim.reset_line_stipple = 1;
|
||||||
|
prim.edgeflags = ~0;
|
||||||
|
prim.pad = 0;
|
||||||
|
prim.v[0] = (struct vertex_header *)v0;
|
||||||
|
prim.v[1] = (struct vertex_header *)v1;
|
||||||
|
prim.v[2] = (struct vertex_header *)v2;
|
||||||
|
|
||||||
|
draw->pipeline.first->tri( draw->pipeline.first, &prim );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void run_pipeline( struct fetch_pipeline_middle_end *fpme,
|
||||||
|
char *verts,
|
||||||
|
const ushort *elts,
|
||||||
|
unsigned count )
|
||||||
|
{
|
||||||
|
struct draw_context *draw = fpme->draw;
|
||||||
|
unsigned stride = fpme->pipeline_vertex_size;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
switch (fpme->prim) {
|
||||||
|
case PIPE_PRIM_POINTS:
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
do_point( draw,
|
||||||
|
verts + stride * elts[i] );
|
||||||
|
break;
|
||||||
|
case PIPE_PRIM_LINES:
|
||||||
|
for (i = 0; i+1 < count; i += 2)
|
||||||
|
do_line( draw,
|
||||||
|
verts + stride * elts[i+0],
|
||||||
|
verts + stride * elts[i+1]);
|
||||||
|
break;
|
||||||
|
case PIPE_PRIM_TRIANGLES:
|
||||||
|
for (i = 0; i+2 < count; i += 3)
|
||||||
|
do_triangle( draw,
|
||||||
|
verts + stride * elts[i+0],
|
||||||
|
verts + stride * elts[i+1],
|
||||||
|
verts + stride * elts[i+2]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
|
||||||
|
const unsigned *fetch_elts,
|
||||||
|
unsigned fetch_count,
|
||||||
|
const ushort *draw_elts,
|
||||||
|
unsigned draw_count )
|
||||||
|
{
|
||||||
|
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
|
||||||
|
struct draw_context *draw = fpme->draw;
|
||||||
|
char *pipeline_verts;
|
||||||
|
|
||||||
|
pipeline_verts = MALLOC( fpme->pipeline_vertex_size *
|
||||||
|
fetch_count );
|
||||||
|
if (!pipeline_verts) {
|
||||||
|
assert(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Single routine to fetch vertices and emit pipeline verts.
|
||||||
|
*/
|
||||||
|
fetch_store_general( fpme,
|
||||||
|
pipeline_verts,
|
||||||
|
fetch_elts,
|
||||||
|
fetch_count );
|
||||||
|
|
||||||
|
|
||||||
|
run_pipeline( fpme,
|
||||||
|
pipeline_verts,
|
||||||
|
draw_elts,
|
||||||
|
draw_count );
|
||||||
|
|
||||||
|
|
||||||
|
/* Done -- that was easy, wasn't it:
|
||||||
|
*/
|
||||||
|
FREE( pipeline_verts );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void fetch_pipeline_finish( struct draw_pt_middle_end *middle )
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle )
|
||||||
|
{
|
||||||
|
FREE(middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw )
|
||||||
|
{
|
||||||
|
struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end );
|
||||||
|
|
||||||
|
fetch_pipeline->base.prepare = fetch_pipeline_prepare;
|
||||||
|
fetch_pipeline->base.run = fetch_pipeline_run;
|
||||||
|
fetch_pipeline->base.finish = fetch_pipeline_finish;
|
||||||
|
fetch_pipeline->base.destroy = fetch_pipeline_destroy;
|
||||||
|
|
||||||
|
fetch_pipeline->draw = draw;
|
||||||
|
|
||||||
|
return &fetch_pipeline->base;
|
||||||
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static fetch_func get_fetch_func( enum pipe_format format )
|
fetch_func draw_get_fetch_func( enum pipe_format format )
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
@ -502,7 +502,7 @@ void draw_update_vertex_fetch( struct draw_context *draw )
|
||||||
draw->vertex_element[i].src_offset;
|
draw->vertex_element[i].src_offset;
|
||||||
|
|
||||||
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
|
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
|
||||||
draw->vertex_fetch.fetch[i] = get_fetch_func( format );
|
draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format );
|
||||||
}
|
}
|
||||||
|
|
||||||
draw->vertex_fetch.nr_attrs = nr_attrs;
|
draw->vertex_fetch.nr_attrs = nr_attrs;
|
||||||
|
|
Loading…
Reference in New Issue