From 0a262998ef2813d19e9fee01d3e5808416e9cb04 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 20 Aug 2007 15:11:11 -0600 Subject: [PATCH] Move guts of vertex array drawing into the 'draw' module. --- src/mesa/pipe/draw/draw_arrays.c | 386 ++++++++++++++++++++++++++++++ src/mesa/pipe/draw/draw_context.c | 28 +++ src/mesa/pipe/draw/draw_context.h | 36 ++- src/mesa/pipe/draw/draw_prim.c | 7 +- src/mesa/pipe/draw/draw_prim.h | 7 - src/mesa/pipe/draw/draw_private.h | 6 +- src/mesa/pipe/draw/draw_vb.c | 9 +- src/mesa/pipe/softpipe/sp_draw_arrays.c | 349 +-------------------------- src/mesa/pipe/softpipe/sp_state_derived.c | 15 +- src/mesa/pipe/softpipe/sp_state_fs.c | 2 + src/mesa/pipe/softpipe/sp_state_vertex.c | 4 + src/mesa/sources | 1 + 12 files changed, 478 insertions(+), 372 deletions(-) create mode 100644 src/mesa/pipe/draw/draw_arrays.c diff --git a/src/mesa/pipe/draw/draw_arrays.c b/src/mesa/pipe/draw/draw_arrays.c new file mode 100644 index 0000000..59098fe --- /dev/null +++ b/src/mesa/pipe/draw/draw_arrays.c @@ -0,0 +1,386 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "pipe/draw/draw_private.h" +#include "pipe/draw/draw_context.h" +#include "pipe/draw/draw_prim.h" + +#include "pipe/tgsi/core/tgsi_exec.h" +#include "pipe/tgsi/core/tgsi_build.h" +#include "pipe/tgsi/core/tgsi_util.h" + + +#if defined __GNUC__ +#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME[SIZE] __attribute__(( aligned( 16 ) )) +#define ALIGN16_ASSIGN(P) P +#else +#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME[SIZE + 1] +#define ALIGN16_ASSIGN(P) align16(P) +#endif + + + +static INLINE unsigned +compute_clipmask(float cx, float cy, float cz, float cw) +{ + unsigned mask; +#if defined(macintosh) || defined(__powerpc__) + /* on powerpc cliptest is 17% faster in this way. */ + mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); + mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); + mask |= (((cw < cy) << CLIP_TOP_SHIFT)); + mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); + mask |= (((cw < cz) << CLIP_FAR_SHIFT)); + mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); +#else /* !defined(macintosh)) */ + mask = 0x0; + if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; + if (-cy + cw < 0) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; + if (-cz + cw < 0) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; +#endif /* defined(macintosh) */ + return mask; +} + + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * XXX this might be a temporary thing. + */ +static void +fetch_attrib4(const void *ptr, unsigned format, float attrib[4]) +{ + /* defaults */ + attrib[1] = 0.0; + attrib[2] = 0.0; + attrib[3] = 1.0; + switch (format) { + case PIPE_FORMAT_R32G32B32A32_FLOAT: + attrib[3] = ((float *) ptr)[3]; + /* fall-through */ + case PIPE_FORMAT_R32G32B32_FLOAT: + attrib[2] = ((float *) ptr)[2]; + /* fall-through */ + case PIPE_FORMAT_R32G32_FLOAT: + attrib[1] = ((float *) ptr)[1]; + /* fall-through */ + case PIPE_FORMAT_R32_FLOAT: + attrib[0] = ((float *) ptr)[0]; + break; + default: + assert(0); + } +} + + +/** + * Transform vertices with the current vertex program/shader + * Up to four vertices can be shaded at a time. + * \param vbuffer the input vertex data + * \param elts indexes of four input vertices + * \param count number of vertices to shade [1..4] + * \param vOut array of pointers to four output vertices + */ +static void +run_vertex_program(struct draw_context *draw, + unsigned elts[4], unsigned count, + struct vertex_header *vOut[]) +{ + struct tgsi_exec_machine machine; + unsigned int j; + + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); + const float *scale = draw->viewport.scale; + const float *trans = draw->viewport.translate; + + assert(count <= 4); + +#ifdef DEBUG + memset( &machine, 0, sizeof( machine ) ); +#endif + + /* init machine state */ + tgsi_exec_machine_init(&machine, + draw->vertex_shader.tokens, + PIPE_MAX_SAMPLERS, + NULL /*samplers*/ ); + + /* Consts does not require 16 byte alignment. */ + machine.Consts = draw->vertex_shader.constants->constant; + + machine.Inputs = ALIGN16_ASSIGN(inputs); + machine.Outputs = ALIGN16_ASSIGN(outputs); + + + if (0) + { + unsigned attr; + for (attr = 0; attr < 16; attr++) { + if (draw->vertex_shader.inputs_read & (1 << attr)) { + printf("attr %d: buf_off %d src_off %d pitch %d\n", + attr, + draw->vertex_buffer[attr].buffer_offset, + draw->vertex_element[attr].src_offset, + draw->vertex_buffer[attr].pitch); + } + } + } + + /* load machine inputs */ + for (j = 0; j < count; j++) { + unsigned attr; + for (attr = 0; attr < 16; attr++) { + if (draw->vertex_shader.inputs_read & (1 << attr)) { + const void *src + = (const void *) ((const ubyte *) draw->mapped_vbuffer[attr] + + draw->vertex_buffer[attr].buffer_offset + + draw->vertex_element[attr].src_offset + + elts[j] * draw->vertex_buffer[attr].pitch); + float p[4]; + + fetch_attrib4(src, draw->vertex_element[attr].src_format, p); + + machine.Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/ + machine.Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/ + machine.Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/ + machine.Inputs[attr].xyzw[3].f[j] = p[3]; /*W*/ +#if 0 + if (attr == 0) { + printf("Input vertex %d: %f %f %f\n", + j, p[0], p[1], p[2]); + } +#endif + } + } + } + +#if 0 + printf("Consts:\n"); + for (i = 0; i < 4; i++) { + printf(" %d: %f %f %f %f\n", i, + machine.Consts[i][0], + machine.Consts[i][1], + machine.Consts[i][2], + machine.Consts[i][3]); + } +#endif + + /* run shader */ + tgsi_exec_machine_run( &machine ); + +#if 0 + printf("VS result: %f %f %f %f\n", + outputs[0].xyzw[0].f[0], + outputs[0].xyzw[1].f[0], + outputs[0].xyzw[2].f[0], + outputs[0].xyzw[3].f[0]); +#endif + + /* store machine results */ + assert(draw->vertex_shader.outputs_written & (1 << VERT_RESULT_HPOS)); + for (j = 0; j < count; j++) { + unsigned attr, slot; + float x, y, z, w; + + /* Handle attr[0] (position) specially: */ + x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; + + vOut[j]->clipmask = compute_clipmask(x, y, z, w); + vOut[j]->edgeflag = 1; + + /* divide by w */ + w = 1.0 / w; + x *= w; + y *= w; + z *= w; + + /* Viewport mapping */ + vOut[j]->data[0][0] = x * scale[0] + trans[0]; + vOut[j]->data[0][1] = y * scale[1] + trans[1]; + vOut[j]->data[0][2] = z * scale[2] + trans[2]; + vOut[j]->data[0][3] = w; +#if 0 + printf("wincoord: %f %f %f\n", + vOut[j]->data[0][0], + vOut[j]->data[0][1], + vOut[j]->data[0][2]); +#endif + + /* remaining attributes: */ + /* pack into sequential post-transform attrib slots */ + slot = 1; + for (attr = 1; attr < VERT_RESULT_MAX; attr++) { + if (draw->vertex_shader.outputs_written & (1 << attr)) { + assert(slot < draw->nr_attrs); + vOut[j]->data[slot][0] = outputs[attr].xyzw[0].f[j]; + vOut[j]->data[slot][1] = outputs[attr].xyzw[1].f[j]; + vOut[j]->data[slot][2] = outputs[attr].xyzw[2].f[j]; + vOut[j]->data[slot][3] = outputs[attr].xyzw[3].f[j]; + slot++; + } + } + } + +#if 0 + memcpy( + quad->outputs.color, + &machine.Outputs[1].xyzw[0].f[0], + sizeof( quad->outputs.color ) ); +#endif +} + + +/** + * Called by the draw module when the vertx cache needs to be flushed. + * This involves running the vertex shader. + */ +static void vs_flush( struct draw_context *draw ) +{ + unsigned i, j; + + /* run vertex shader on vertex cache entries, four per invokation */ + for (i = 0; i < draw->vs.queue_nr; i += 4) { + struct vertex_header *dests[4]; + unsigned elts[4]; + int n; + + for (j = 0; j < 4; j++) { + elts[j] = draw->vs.queue[i + j].elt; + dests[j] = draw->vs.queue[i + j].dest; + } + + n = MIN2(4, draw->vs.queue_nr - i); + assert(n > 0); + assert(n <= 4); + + run_vertex_program(draw, elts, n, dests); + } + + draw->vs.queue_nr = 0; +} + + +void draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer) +{ + draw->mapped_vbuffer[attr] = buffer; +} + + +/** + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw + */ +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) +{ + /* tell drawing pipeline we're beginning drawing */ + draw->pipeline.first->begin( draw->pipeline.first ); + + draw->vs_flush = vs_flush; + + draw_invalidate_vcache( draw ); + + draw_set_prim( draw, prim ); + + /* drawing done here: */ + draw_prim(draw, start, count); + + /* draw any left-over buffered prims */ + draw_flush(draw); + + /* tell drawing pipeline we're done drawing */ + draw->pipeline.first->end( draw->pipeline.first ); +} + + +/* XXX move this into draw_context.c? */ + +#define EMIT_ATTR( VF_ATTR, STYLE, SIZE ) \ +do { \ + if (draw->nr_attrs >= 2) \ + draw->vf_attr_to_slot[VF_ATTR] = draw->nr_attrs - 2; \ + draw->attrs[draw->nr_attrs].attrib = VF_ATTR; \ + draw->attrs[draw->nr_attrs].format = STYLE; \ + draw->nr_attrs++; \ + draw->vertex_size += SIZE; \ +} while (0) + + +/** + * XXX very similar to same func in draw_vb.c (which will go away) + */ +void +draw_set_vertex_attributes( struct draw_context *draw, + const unsigned *slot_to_vf_attr, + unsigned nr_attrs ) +{ + unsigned i; + + memset(draw->vf_attr_to_slot, 0, sizeof(draw->vf_attr_to_slot)); + draw->nr_attrs = 0; + draw->vertex_size = 0; + + /* + * First three attribs are always the same: header, clip pos, winpos + */ + EMIT_ATTR(VF_ATTRIB_VERTEX_HEADER, EMIT_1F, 1); + EMIT_ATTR(VF_ATTRIB_CLIP_POS, EMIT_4F, 4); + + assert(slot_to_vf_attr[0] == VF_ATTRIB_POS); + EMIT_ATTR(slot_to_vf_attr[0], EMIT_4F_VIEWPORT, 4); + + /* + * Remaining attribs (color, texcoords, etc) + */ + for (i = 1; i < nr_attrs; i++) + EMIT_ATTR(slot_to_vf_attr[i], EMIT_4F, 4); + + draw->vertex_size *= 4; /* floats to bytes */ +} diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index a808fb7..cc00576 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -201,3 +201,31 @@ void draw_set_viewport_state( struct draw_context *draw, * Full pipe will have vertex shader, vertex fetch of its own. */ } + + +void +draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer) +{ + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_buffer[attr] = *buffer; +} + + +void +draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element) +{ + assert(attr < PIPE_ATTRIB_MAX); + draw->vertex_element[attr] = *element; +} + + +void +draw_set_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + draw->vertex_shader = *shader; +} diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 74fdd46..2fce132 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -93,14 +93,36 @@ void draw_set_vertex_attributes( struct draw_context *draw, const unsigned *attrs, unsigned nr_attrs ); -/* XXX temporary */ -void draw_set_vertex_attributes2( struct draw_context *draw, - const unsigned *attrs, - unsigned nr_attrs ); +unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr ); + +unsigned draw_trim( unsigned count, unsigned first, unsigned incr ); + +void draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ); + +void draw_set_mapped_vertex_buffer(struct draw_context *draw, + unsigned attr, const void *buffer); + + +void +draw_set_vertex_buffer(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_buffer *buffer); + +void +draw_set_vertex_element(struct draw_context *draw, + unsigned attr, + const struct pipe_vertex_element *element); + +void +draw_set_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader); + + +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count); -/* XXX temporary */ -void draw_vb(struct draw_context *draw, - struct vertex_buffer *VB ); void draw_vertices(struct draw_context *draw, unsigned mode, diff --git a/src/mesa/pipe/draw/draw_prim.c b/src/mesa/pipe/draw/draw_prim.c index fb8bc0f..fbd0672 100644 --- a/src/mesa/pipe/draw/draw_prim.c +++ b/src/mesa/pipe/draw/draw_prim.c @@ -434,8 +434,8 @@ draw_set_prim( struct draw_context *draw, unsigned prim ) * \param elements the element buffer ptr */ void -draw_set_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ) +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ) { /* choose the get_vertex() function to use */ switch (eltSize) { @@ -456,10 +456,9 @@ draw_set_element_buffer( struct draw_context *draw, } draw->elts = elements; draw->eltSize = eltSize; - - } + unsigned draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) { diff --git a/src/mesa/pipe/draw/draw_prim.h b/src/mesa/pipe/draw/draw_prim.h index 3224989..4c55b02 100644 --- a/src/mesa/pipe/draw/draw_prim.h +++ b/src/mesa/pipe/draw/draw_prim.h @@ -8,16 +8,9 @@ void draw_invalidate_vcache( struct draw_context *draw ); void draw_set_prim( struct draw_context *draw, unsigned prim ); -void draw_set_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ); - void draw_prim( struct draw_context *draw, unsigned start, unsigned count ); void draw_flush( struct draw_context *draw ); -unsigned draw_prim_info( unsigned prim, unsigned *first, unsigned *incr ); - -unsigned draw_trim( unsigned count, unsigned first, unsigned incr ); - #endif /* DRAW_PRIM_H */ diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 798fa5c..5c3efb8 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -158,9 +158,11 @@ struct draw_context /* pipe state that we need: */ struct pipe_setup_state setup; struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; + struct pipe_shader_state vertex_shader; - /** need to know the pipe for vertex flushing/transformation: */ - struct pipe_context *pipe; + const void *mapped_vbuffer[PIPE_ATTRIB_MAX]; /* Clip derived state: */ diff --git a/src/mesa/pipe/draw/draw_vb.c b/src/mesa/pipe/draw/draw_vb.c index 18e48c0..0eefb0b 100644 --- a/src/mesa/pipe/draw/draw_vb.c +++ b/src/mesa/pipe/draw/draw_vb.c @@ -221,9 +221,9 @@ void draw_vb(struct draw_context *draw, vf_emit_vertices( draw->vf, VB->Count, draw->verts ); if (VB->Elts) - draw_set_element_buffer(draw, sizeof(unsigned), VB->Elts); + draw_set_mapped_element_buffer(draw, sizeof(unsigned), VB->Elts); else - draw_set_element_buffer(draw, 0, NULL); + draw_set_mapped_element_buffer(draw, 0, NULL); for (i = 0; i < VB->PrimitiveCount; i++) { const GLenum mode = VB->Primitive[i].mode; @@ -281,7 +281,7 @@ draw_vertices(struct draw_context *draw, /* no element/index buffer */ - draw_set_element_buffer(draw, 0, NULL); + draw_set_mapped_element_buffer(draw, 0, NULL); /*draw_prim_info(mode, &first, &incr);*/ draw_allocate_vertices( draw, numVerts ); @@ -325,7 +325,7 @@ draw_vertices(struct draw_context *draw, draw->in_vb = 0; } - +#if 000 /** * Accumulate another attribute's info. @@ -383,3 +383,4 @@ void draw_set_vertex_attributes( struct draw_context *draw, draw->nr_attrs, 0 ); #endif } +#endif diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index 6213286..2df07eb 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -31,284 +31,15 @@ */ -/** TEMP */ -#include "main/context.h" -#include "main/macros.h" - #include "pipe/p_defines.h" #include "pipe/p_context.h" #include "pipe/p_winsys.h" - +#include "pipe/p_util.h" #include "sp_context.h" #include "sp_state.h" -#include "pipe/draw/draw_private.h" #include "pipe/draw/draw_context.h" -#include "pipe/draw/draw_prim.h" - -#include "pipe/tgsi/core/tgsi_exec.h" -#include "pipe/tgsi/core/tgsi_build.h" -#include "pipe/tgsi/core/tgsi_util.h" - - -#if defined __GNUC__ -#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME[SIZE] __attribute__(( aligned( 16 ) )) -#define ALIGN16_ASSIGN(P) P -#else -#define ALIGN16_DECL(TYPE, NAME, SIZE) TYPE NAME[SIZE + 1] -#define ALIGN16_ASSIGN(P) align16(P) -#endif - - - -static INLINE unsigned -compute_clipmask(float cx, float cy, float cz, float cw) -{ - unsigned mask; -#if defined(macintosh) || defined(__powerpc__) - /* on powerpc cliptest is 17% faster in this way. */ - mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); - mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); - mask |= (((cw < cy) << CLIP_TOP_SHIFT)); - mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); - mask |= (((cw < cz) << CLIP_FAR_SHIFT)); - mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); -#else /* !defined(macintosh)) */ - mask = 0x0; - if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; - if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; - if (-cy + cw < 0) mask |= CLIP_TOP_BIT; - if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; - if (-cz + cw < 0) mask |= CLIP_FAR_BIT; - if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; -#endif /* defined(macintosh) */ - return mask; -} - - -/** - * Fetch a float[4] vertex attribute from memory, doing format/type - * conversion as needed. - * XXX this might be a temporary thing. - */ -static void -fetch_attrib4(const void *ptr, unsigned format, float attrib[4]) -{ - /* defaults */ - attrib[1] = 0.0; - attrib[2] = 0.0; - attrib[3] = 1.0; - switch (format) { - case PIPE_FORMAT_R32G32B32A32_FLOAT: - attrib[3] = ((float *) ptr)[3]; - /* fall-through */ - case PIPE_FORMAT_R32G32B32_FLOAT: - attrib[2] = ((float *) ptr)[2]; - /* fall-through */ - case PIPE_FORMAT_R32G32_FLOAT: - attrib[1] = ((float *) ptr)[1]; - /* fall-through */ - case PIPE_FORMAT_R32_FLOAT: - attrib[0] = ((float *) ptr)[0]; - break; - default: - assert(0); - } -} - - -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static void -run_vertex_program(struct softpipe_context *sp, - unsigned elts[4], unsigned count, - struct vertex_header *vOut[]) -{ - struct tgsi_exec_machine machine; - unsigned int j; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_ATTRIB_MAX); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_ATTRIB_MAX); - const float *scale = sp->viewport.scale; - const float *trans = sp->viewport.translate; - - assert(count <= 4); - -#ifdef DEBUG - memset( &machine, 0, sizeof( machine ) ); -#endif - - /* init machine state */ - tgsi_exec_machine_init( - &machine, - sp->vs.tokens, - PIPE_MAX_SAMPLERS, - NULL /*samplers*/ ); - - /* Consts does not require 16 byte alignment. */ - machine.Consts = sp->vs.constants->constant; - - machine.Inputs = ALIGN16_ASSIGN(inputs); - machine.Outputs = ALIGN16_ASSIGN(outputs); - - - if (0) - { - unsigned attr; - for (attr = 0; attr < 16; attr++) { - if (sp->vs.inputs_read & (1 << attr)) { - printf("attr %d: buf_off %d src_off %d pitch %d\n", - attr, - sp->vertex_buffer[attr].buffer_offset, - sp->vertex_element[attr].src_offset, - sp->vertex_buffer[attr].pitch); - } - } - } - - /* load machine inputs */ - for (j = 0; j < count; j++) { - unsigned attr; - for (attr = 0; attr < 16; attr++) { - if (sp->vs.inputs_read & (1 << attr)) { - const void *src - = (const void *) ((const ubyte *) sp->mapped_vbuffer[attr] - + sp->vertex_buffer[attr].buffer_offset - + sp->vertex_element[attr].src_offset - + elts[j] * sp->vertex_buffer[attr].pitch); - float p[4]; - - fetch_attrib4(src, sp->vertex_element[attr].src_format, p); - - machine.Inputs[attr].xyzw[0].f[j] = p[0]; /*X*/ - machine.Inputs[attr].xyzw[1].f[j] = p[1]; /*Y*/ - machine.Inputs[attr].xyzw[2].f[j] = p[2]; /*Z*/ - machine.Inputs[attr].xyzw[3].f[j] = p[3]; /*W*/ -#if 0 - if (attr == 0) { - printf("Input vertex %d: %f %f %f\n", - j, p[0], p[1], p[2]); - } -#endif - } - } - } - -#if 0 - printf("Consts:\n"); - for (i = 0; i < 4; i++) { - printf(" %d: %f %f %f %f\n", i, - machine.Consts[i][0], - machine.Consts[i][1], - machine.Consts[i][2], - machine.Consts[i][3]); - } -#endif - - /* run shader */ - tgsi_exec_machine_run( &machine ); - -#if 0 - printf("VS result: %f %f %f %f\n", - outputs[0].xyzw[0].f[0], - outputs[0].xyzw[1].f[0], - outputs[0].xyzw[2].f[0], - outputs[0].xyzw[3].f[0]); -#endif - - /* store machine results */ - assert(sp->vs.outputs_written & (1 << VERT_RESULT_HPOS)); - for (j = 0; j < count; j++) { - unsigned attr, slot; - float x, y, z, w; - - /* Handle attr[0] (position) specially: */ - x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; - - vOut[j]->clipmask = compute_clipmask(x, y, z, w); - vOut[j]->edgeflag = 1; - - /* divide by w */ - w = 1.0 / w; - x *= w; - y *= w; - z *= w; - - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; -#if 0 - printf("wincoord: %f %f %f\n", - vOut[j]->data[0][0], - vOut[j]->data[0][1], - vOut[j]->data[0][2]); -#endif - - /* remaining attributes: */ - /* pack into sequential post-transform attrib slots */ - slot = 1; - for (attr = 1; attr < VERT_RESULT_MAX; attr++) { - if (sp->vs.outputs_written & (1 << attr)) { - assert(slot < sp->nr_attrs); - vOut[j]->data[slot][0] = outputs[attr].xyzw[0].f[j]; - vOut[j]->data[slot][1] = outputs[attr].xyzw[1].f[j]; - vOut[j]->data[slot][2] = outputs[attr].xyzw[2].f[j]; - vOut[j]->data[slot][3] = outputs[attr].xyzw[3].f[j]; - slot++; - } - } - } - -#if 0 - memcpy( - quad->outputs.color, - &machine.Outputs[1].xyzw[0].f[0], - sizeof( quad->outputs.color ) ); -#endif -} - - -/** - * Called by the draw module when the vertx cache needs to be flushed. - * This involves running the vertex shader. - */ -static void vs_flush( struct draw_context *draw ) -{ - struct softpipe_context *sp = (struct softpipe_context *) draw->pipe; - unsigned i, j; - - /* run vertex shader on vertex cache entries, four per invokation */ - for (i = 0; i < draw->vs.queue_nr; i += 4) { - struct vertex_header *dests[4]; - unsigned elts[4]; - int n; - - for (j = 0; j < 4; j++) { - elts[j] = draw->vs.queue[i + j].elt; - dests[j] = draw->vs.queue[i + j].dest; - } - - n = MIN2(4, draw->vs.queue_nr - i); - assert(n > 0); - assert(n <= 4); - - run_vertex_program(sp, elts, n, dests); - } - - draw->vs.queue_nr = 0; -} @@ -322,6 +53,10 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, /** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + * * XXX should the element buffer be specified/bound with a separate function? */ void @@ -330,7 +65,6 @@ softpipe_draw_elements(struct pipe_context *pipe, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { - struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; unsigned length, first, incr, i; @@ -353,10 +87,11 @@ softpipe_draw_elements(struct pipe_context *pipe, */ for (i = 0; i < PIPE_ATTRIB_MAX; i++) { if (sp->vertex_buffer[i].buffer) { - sp->mapped_vbuffer[i] + void *buf = pipe->winsys->buffer_map(pipe->winsys, sp->vertex_buffer[i].buffer, PIPE_BUFFER_FLAG_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); } } /* Map index buffer, if present */ @@ -364,30 +99,15 @@ softpipe_draw_elements(struct pipe_context *pipe, mapped_indexes = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, PIPE_BUFFER_FLAG_READ); - draw_set_element_buffer(draw, indexSize, mapped_indexes); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { - draw_set_element_buffer(draw, 0, NULL); /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); /* no index/element buffer */ } - /* tell drawing pipeline we're beginning drawing */ - draw->pipeline.first->begin( draw->pipeline.first ); - - draw->vs_flush = vs_flush; - draw->pipe = pipe; /* XXX pass pipe to draw_create() */ - - draw_invalidate_vcache( draw ); - draw_set_prim( draw, mode ); + draw_arrays(draw, mode, start, count); - /* drawing done here: */ - draw_prim(draw, start, count); - - /* draw any left-over buffered prims */ - draw_flush(draw); - - /* tell drawing pipeline we're done drawing */ - draw->pipeline.first->end( draw->pipeline.first ); /* * unmap vertex/index buffers @@ -395,58 +115,13 @@ softpipe_draw_elements(struct pipe_context *pipe, for (i = 0; i < PIPE_ATTRIB_MAX; i++) { if (sp->vertex_buffer[i].buffer) { pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); } } if (indexBuffer) { pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + draw_set_mapped_element_buffer(draw, 0, NULL); } softpipe_unmap_surfaces(sp); } - - - -#define EMIT_ATTR( VF_ATTR, STYLE, SIZE ) \ -do { \ - if (draw->nr_attrs >= 2) \ - draw->vf_attr_to_slot[VF_ATTR] = draw->nr_attrs - 2; \ - draw->attrs[draw->nr_attrs].attrib = VF_ATTR; \ - draw->attrs[draw->nr_attrs].format = STYLE; \ - draw->nr_attrs++; \ - draw->vertex_size += SIZE; \ -} while (0) - - -/** - * XXX very similar to same func in draw_vb.c (which will go away) - */ -void -draw_set_vertex_attributes2( struct draw_context *draw, - const unsigned *slot_to_vf_attr, - unsigned nr_attrs ) -{ - unsigned i; - - memset(draw->vf_attr_to_slot, 0, sizeof(draw->vf_attr_to_slot)); - draw->nr_attrs = 0; - draw->vertex_size = 0; - - /* - * First three attribs are always the same: header, clip pos, winpos - */ - EMIT_ATTR(VF_ATTRIB_VERTEX_HEADER, EMIT_1F, 1); - EMIT_ATTR(VF_ATTRIB_CLIP_POS, EMIT_4F, 4); - - assert(slot_to_vf_attr[0] == VF_ATTRIB_POS); - EMIT_ATTR(slot_to_vf_attr[0], EMIT_4F_VIEWPORT, 4); - - /* - * Remaining attribs (color, texcoords, etc) - */ - for (i = 1; i < nr_attrs; i++) - EMIT_ATTR(slot_to_vf_attr[i], EMIT_4F, 4); - - draw->vertex_size *= 4; /* floats to bytes */ -} - - diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 95b0cfe..eba789e 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -210,22 +210,15 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) } } - /* If the attributes have changed, tell the draw module (which in turn - * tells the vf module) about the new vertex layout. + /* If the attributes have changed, tell the draw module about + * the new vertex layout. */ if (attr_mask != softpipe->attr_mask) { softpipe->attr_mask = attr_mask; -#define USE_NEW_DRAW 01 -#if USE_NEW_DRAW - draw_set_vertex_attributes2( softpipe->draw, - slot_to_vf_attr, - softpipe->nr_attrs ); -#else draw_set_vertex_attributes( softpipe->draw, - slot_to_vf_attr, - softpipe->nr_attrs ); -#endif + slot_to_vf_attr, + softpipe->nr_attrs ); } } diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 3505c2f..98d596d 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -49,4 +49,6 @@ void softpipe_set_vs_state( struct pipe_context *pipe, memcpy(&softpipe->vs, vs, sizeof(*vs)); softpipe->dirty |= SP_NEW_VS; + + draw_set_vertex_shader(softpipe->draw, vs); } diff --git a/src/mesa/pipe/softpipe/sp_state_vertex.c b/src/mesa/pipe/softpipe/sp_state_vertex.c index d985b20..1885255 100644 --- a/src/mesa/pipe/softpipe/sp_state_vertex.c +++ b/src/mesa/pipe/softpipe/sp_state_vertex.c @@ -41,6 +41,8 @@ softpipe_set_vertex_element(struct pipe_context *pipe, assert(index < PIPE_ATTRIB_MAX); softpipe->vertex_element[index] = *attrib; /* struct copy */ softpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_element(softpipe->draw, index, attrib); } @@ -53,4 +55,6 @@ softpipe_set_vertex_buffer(struct pipe_context *pipe, assert(index < PIPE_ATTRIB_MAX); softpipe->vertex_buffer[index] = *buffer; /* struct copy */ softpipe->dirty |= SP_NEW_VERTEX; + + draw_set_vertex_buffer(softpipe->draw, index, buffer); } diff --git a/src/mesa/sources b/src/mesa/sources index d97a34f..0731e64 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -156,6 +156,7 @@ VF_SOURCES = \ DRAW_SOURCES = \ + pipe/draw/draw_arrays.c \ pipe/draw/draw_clip.c \ pipe/draw/draw_context.c\ pipe/draw/draw_cull.c \ -- 2.7.4