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_pt_middle_end base;
struct draw_context *draw;
- struct translate_key key;
/* Temporaries:
*/
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;
-}
+ struct draw_vs_varient_key key;
+ struct draw_vs_varient *active;
+ const struct vertex_info *vinfo;
+};
-static void fse_prepare( struct draw_pt_front_end *fe,
- unsigned prim,
- struct draw_pt_middle_end *unused,
- unsigned opt )
+static void fse_prepare( struct draw_pt_middle_end *middle,
+ unsigned prim,
+ unsigned opt )
{
- struct fetch_shade_emit *fse = (struct fetch_shade_emit *)fe;
+ 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;
+ unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs;
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 )) {
+ if (!draw->render->set_primitive( draw->render,
+ prim )) {
assert(0);
- return ;
+ return;
}
/* Must do this after set_primitive() above:
*/
- vinfo = draw->render->get_vertex_info(draw->render);
+ fse->vinfo = 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;
+ 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;
+ fse->key.pad = 0;
+
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;
+ fse->key.element[i].in.format = src->src_format;
- /* Consider ignoring these at this point, ie make generated
- * programs independent of this state:
+ /* Consider ignoring these, 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;
+ fse->key.element[i].in.buffer = src->vertex_buffer_index;
+ fse->key.element[i].in.offset = src->src_offset;
}
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;
+ case EMIT_4UB:
+ emit_sz = 4 * sizeof(ubyte);
break;
default:
assert(0);
* 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;
+ 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_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
* 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];
- }
+ fse->active = draw_vs_lookup_varient( draw->vs.vertex_shader,
+ &fse->key );
if (!fse->active) {
assert(0);
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;
-
+ fse->active->set_input( fse->active,
+ i,
+
+ ((const ubyte *) draw->pt.user.vbuffer[buf] +
+ draw->pt.vertex_buffer[buf].buffer_offset),
+
+ draw->pt.vertex_buffer[buf].pitch );
}
-
//return TRUE;
}
-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;
- }
-}
-
-
-#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;
+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;
+ unsigned alloc_count = align(count, 4);
+ char *hw_verts;
- 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);
- }
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (j)
- render->draw( render, tmp, j );
- break;
+ hw_verts = draw->render->allocate_vertices( draw->render,
+ (ushort)fse->key.output_stride,
+ (ushort)alloc_count );
- default:
- render->draw_arrays( render,
- start,
- length );
- break;
+ if (!hw_verts) {
+ assert(0);
+ return;
}
- 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.
+ * Clipping is done elsewhere -- either by the API or on hardware,
+ * or for some other reason not required...
*/
- fse->active->run_linear( fse,
+ fse->active->run_linear( fse->active,
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->draw_arrays( draw->render,
+ 0,
+ count );
+ if (0) {
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ debug_printf("\n\n%s vertex %d: (stride %d, offset %d)\n", __FUNCTION__, i,
+ fse->key.output_stride,
+ fse->key.output_stride * i);
+
+ draw_dump_emitted_vertex( fse->vinfo,
+ (const uint8_t *)hw_verts + fse->key.output_stride * i );
+ }
+ }
+
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)
+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 *)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);
+ struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
+ struct draw_context *draw = fse->draw;
+ unsigned alloc_count = align(fetch_count, 4);
+ void *hw_verts;
- split_prim_inplace(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;
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- if (!do_draw( fse, start + i, nr )) {
- assert(0);
- return ;
+ hw_verts = draw->render->allocate_vertices( draw->render,
+ (ushort)fse->key.output_stride,
+ (ushort)alloc_count );
+ if (!hw_verts) {
+ assert(0);
+ return;
+ }
+
+
+ /* Single routine to fetch vertices, run shader and emit HW verts.
+ */
+ fse->active->run_elts( fse->active,
+ fetch_elts,
+ fetch_count,
+ hw_verts );
+
+ draw->render->draw( draw->render,
+ draw_elts,
+ draw_count );
+
+ if (0) {
+ unsigned i;
+ for (i = 0; i < fetch_count; i++) {
+ debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
+ draw_dump_emitted_vertex( fse->vinfo,
+ (const uint8_t *)hw_verts +
+ fse->key.output_stride * i );
}
-
- /* increment allowing for repeated vertices
- */
- i += nr - (first - incr);
}
- //return TRUE;
+
+ draw->render->release_vertices( draw->render,
+ hw_verts,
+ fse->key.output_stride,
+ fetch_count );
+
}
-static void fse_finish( struct draw_pt_front_end *frontend )
+static void fse_finish( struct draw_pt_middle_end *middle )
{
}
static void
-fse_destroy( struct draw_pt_front_end *frontend )
+fse_destroy( struct draw_pt_middle_end *middle )
{
- FREE(frontend);
+ FREE(middle);
}
-struct draw_pt_front_end *draw_pt_fetch_shade_emit( struct draw_context *draw )
+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)
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 = 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;
}