|
|
|
@@ -1,677 +0,0 @@
|
|
|
|
|
/**************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* 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 );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Prototype fetch, shade, emit-hw-verts all in one go.
|
|
|
|
|
*/
|
|
|
|
|
struct fetch_shade_emit {
|
|
|
|
|
struct draw_pt_front_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 fetch_xyz_rgb_st( const struct fetch_shade_emit *fse,
|
|
|
|
|
unsigned start,
|
|
|
|
|
unsigned count,
|
|
|
|
|
char *buffer )
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
const float *m = fse->constants;
|
|
|
|
|
const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12];
|
|
|
|
|
const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13];
|
|
|
|
|
const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14];
|
|
|
|
|
const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15];
|
|
|
|
|
|
|
|
|
|
const ubyte *xyz = fse->src[0] + start * fse->pitch[0];
|
|
|
|
|
const ubyte *st = fse->src[2] + start * fse->pitch[2];
|
|
|
|
|
|
|
|
|
|
float *out = (float *)buffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(fse->pitch[1] == 0);
|
|
|
|
|
|
|
|
|
|
/* 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] = m0 * ix + m4 * iy + m8 * iz + m12;
|
|
|
|
|
out[1] = m1 * ix + m5 * iy + m9 * iz + m13;
|
|
|
|
|
out[2] = m2 * ix + m6 * iy + m10 * iz + m14;
|
|
|
|
|
out[3] = m3 * ix + m7 * iy + m11 * iz + m15;
|
|
|
|
|
xyz += fse->pitch[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
out[4] = 1.0f;
|
|
|
|
|
out[5] = 1.0f;
|
|
|
|
|
out[6] = 1.0f;
|
|
|
|
|
out[7] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const float *in = (const float *)st; st += fse->pitch[2];
|
|
|
|
|
out[8] = in[0];
|
|
|
|
|
out[9] = in[1];
|
|
|
|
|
out[10] = 0.0f;
|
|
|
|
|
out[11] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out += 12;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void fetch_xyz_rgb( const struct fetch_shade_emit *fse,
|
|
|
|
|
unsigned start,
|
|
|
|
|
unsigned count,
|
|
|
|
|
char *buffer )
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
const float *m = (const float *)fse->constants;
|
|
|
|
|
const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12];
|
|
|
|
|
const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13];
|
|
|
|
|
const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14];
|
|
|
|
|
const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15];
|
|
|
|
|
|
|
|
|
|
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] = m0 * ix + m4 * iy + m8 * iz + m12;
|
|
|
|
|
out[1] = m1 * ix + m5 * iy + m9 * iz + m13;
|
|
|
|
|
out[2] = m2 * ix + m6 * iy + m10 * iz + m14;
|
|
|
|
|
out[3] = m3 * ix + m7 * iy + m11 * iz + m15;
|
|
|
|
|
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 fetch_xyz_rgb_psiz( const struct fetch_shade_emit *fse,
|
|
|
|
|
unsigned start,
|
|
|
|
|
unsigned count,
|
|
|
|
|
char *buffer )
|
|
|
|
|
{
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
const float *m = (const float *)fse->constants;
|
|
|
|
|
const float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12];
|
|
|
|
|
const float m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13];
|
|
|
|
|
const float m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14];
|
|
|
|
|
const float m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15];
|
|
|
|
|
|
|
|
|
|
const ubyte *xyz = fse->src[0] + start * fse->pitch[0];
|
|
|
|
|
const float *rgb = (const float *)(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] = m0 * ix + m4 * iy + m8 * iz + m12;
|
|
|
|
|
out[1] = m1 * ix + m5 * iy + m9 * iz + m13;
|
|
|
|
|
out[2] = m2 * ix + m6 * iy + m10 * iz + m14;
|
|
|
|
|
out[3] = m3 * ix + m7 * iy + m11 * iz + m15;
|
|
|
|
|
xyz += fse->pitch[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
out[4] = rgb[0];
|
|
|
|
|
out[5] = rgb[1];
|
|
|
|
|
out[6] = rgb[2];
|
|
|
|
|
out[7] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
out[8] = psiz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out += 9;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static boolean set_prim( struct fetch_shade_emit *fse,
|
|
|
|
|
unsigned prim,
|
|
|
|
|
unsigned count )
|
|
|
|
|
{
|
|
|
|
|
struct draw_context *draw = fse->draw;
|
|
|
|
|
|
|
|
|
|
fse->prim = prim;
|
|
|
|
|
|
|
|
|
|
switch (prim) {
|
|
|
|
|
case PIPE_PRIM_LINE_LOOP:
|
|
|
|
|
if (count > 1024)
|
|
|
|
|
return FALSE;
|
|
|
|
|
draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PIPE_PRIM_TRIANGLE_FAN:
|
|
|
|
|
case PIPE_PRIM_POLYGON:
|
|
|
|
|
if (count > 1024)
|
|
|
|
|
return FALSE;
|
|
|
|
|
draw->render->set_primitive( draw->render, prim );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PIPE_PRIM_QUADS:
|
|
|
|
|
case PIPE_PRIM_QUAD_STRIP:
|
|
|
|
|
draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
draw->render->set_primitive( draw->render, prim );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void fse_prepare( struct draw_pt_front_end *fe,
|
|
|
|
|
unsigned prim,
|
|
|
|
|
struct draw_pt_middle_end *unused,
|
|
|
|
|
unsigned opt )
|
|
|
|
|
{
|
|
|
|
|
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe;
|
|
|
|
|
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 (!set_prim(fse, prim, /*count*/1022 )) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define INDEX(i) (start + (i))
|
|
|
|
|
static void fse_render_linear( struct vbuf_render *render,
|
|
|
|
|
unsigned prim,
|
|
|
|
|
unsigned start,
|
|
|
|
|
unsigned length )
|
|
|
|
|
{
|
|
|
|
|
ushort *tmp = NULL;
|
|
|
|
|
unsigned i, j;
|
|
|
|
|
|
|
|
|
|
switch (prim) {
|
|
|
|
|
case PIPE_PRIM_LINE_LOOP:
|
|
|
|
|
tmp = MALLOC( sizeof(ushort) * (length + 1) );
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
|
tmp[i] = INDEX(i);
|
|
|
|
|
tmp[length] = 0;
|
|
|
|
|
|
|
|
|
|
render->draw( render,
|
|
|
|
|
tmp,
|
|
|
|
|
length+1 );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case PIPE_PRIM_QUAD_STRIP:
|
|
|
|
|
tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) );
|
|
|
|
|
|
|
|
|
|
for (j = i = 0; i + 3 < length; i += 2, j += 6) {
|
|
|
|
|
tmp[j+0] = INDEX(i+0);
|
|
|
|
|
tmp[j+1] = INDEX(i+1);
|
|
|
|
|
tmp[j+2] = INDEX(i+3);
|
|
|
|
|
|
|
|
|
|
tmp[j+3] = INDEX(i+2);
|
|
|
|
|
tmp[j+4] = INDEX(i+0);
|
|
|
|
|
tmp[j+5] = INDEX(i+3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (j)
|
|
|
|
|
render->draw( render, tmp, j );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PIPE_PRIM_QUADS:
|
|
|
|
|
tmp = MALLOC( sizeof(int) * (length / 4 * 6) );
|
|
|
|
|
|
|
|
|
|
for (j = i = 0; i + 3 < length; i += 4, j += 6) {
|
|
|
|
|
tmp[j+0] = INDEX(i+0);
|
|
|
|
|
tmp[j+1] = INDEX(i+1);
|
|
|
|
|
tmp[j+2] = INDEX(i+3);
|
|
|
|
|
|
|
|
|
|
tmp[j+3] = INDEX(i+1);
|
|
|
|
|
tmp[j+4] = INDEX(i+2);
|
|
|
|
|
tmp[j+5] = INDEX(i+3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (j)
|
|
|
|
|
render->draw( render, tmp, j );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
render->draw_arrays( render,
|
|
|
|
|
start,
|
|
|
|
|
length );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tmp)
|
|
|
|
|
FREE(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static boolean do_draw( struct fetch_shade_emit *fse,
|
|
|
|
|
unsigned start, unsigned count )
|
|
|
|
|
{
|
|
|
|
|
struct draw_context *draw = fse->draw;
|
|
|
|
|
|
|
|
|
|
char *hw_verts =
|
|
|
|
|
draw->render->allocate_vertices( draw->render,
|
|
|
|
|
(ushort)fse->key.output_stride,
|
|
|
|
|
(ushort)count );
|
|
|
|
|
|
|
|
|
|
if (!hw_verts)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* Single routine to fetch vertices, run shader and emit HW verts.
|
|
|
|
|
* Clipping and viewport transformation are done on hardware.
|
|
|
|
|
*/
|
|
|
|
|
fse->active->run_linear( fse,
|
|
|
|
|
start, count,
|
|
|
|
|
hw_verts );
|
|
|
|
|
|
|
|
|
|
/* Draw arrays path to avoid re-emitting index list again and
|
|
|
|
|
* again.
|
|
|
|
|
*/
|
|
|
|
|
fse_render_linear( draw->render,
|
|
|
|
|
fse->prim,
|
|
|
|
|
0,
|
|
|
|
|
count );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draw->render->release_vertices( draw->render,
|
|
|
|
|
hw_verts,
|
|
|
|
|
fse->key.output_stride,
|
|
|
|
|
count );
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fse_run(struct draw_pt_front_end *fe,
|
|
|
|
|
pt_elt_func elt_func,
|
|
|
|
|
const void *elt_ptr,
|
|
|
|
|
unsigned count)
|
|
|
|
|
{
|
|
|
|
|
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe;
|
|
|
|
|
unsigned i = 0;
|
|
|
|
|
unsigned first, incr;
|
|
|
|
|
unsigned start = elt_func(elt_ptr, 0);
|
|
|
|
|
|
|
|
|
|
//debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count);
|
|
|
|
|
|
|
|
|
|
draw_pt_split_prim(fse->prim, &first, &incr);
|
|
|
|
|
|
|
|
|
|
count -= (count - first) % incr;
|
|
|
|
|
|
|
|
|
|
while (i + first <= count) {
|
|
|
|
|
int nr = MIN2( count - i, 1024 );
|
|
|
|
|
|
|
|
|
|
/* snap to prim boundary
|
|
|
|
|
*/
|
|
|
|
|
nr -= (nr - first) % incr;
|
|
|
|
|
|
|
|
|
|
if (!do_draw( fse, start + i, nr )) {
|
|
|
|
|
assert(0);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* increment allowing for repeated vertices
|
|
|
|
|
*/
|
|
|
|
|
i += nr - (first - incr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void fse_finish( struct draw_pt_front_end *frontend )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
fse_destroy( struct draw_pt_front_end *frontend )
|
|
|
|
|
{
|
|
|
|
|
FREE(frontend);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct draw_pt_front_end *draw_pt_fetch_shade_emit( 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.finish = fse_finish;
|
|
|
|
|
fse->base.destroy = fse_destroy;
|
|
|
|
|
fse->draw = draw;
|
|
|
|
|
|
|
|
|
|
fse->shader[0].run_linear = fetch_xyz_rgb_st;
|
|
|
|
|
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 = fetch_xyz_rgb;
|
|
|
|
|
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 = fetch_xyz_rgb_psiz;
|
|
|
|
|
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;
|
|
|
|
|
}
|