From 169a74196fdca320cabd5cde33fda17683cc823d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 28 Jan 2008 18:46:21 +0900 Subject: [PATCH] First stab at hooking draw_vbuf & vf. Emit disabled for now. Tested with softpipe. Only one vertex at a time for now (slow). --- src/mesa/pipe/draw/draw_vbuf.c | 183 ++++++++++++++++++++++++++++++++++- src/mesa/pipe/draw/draw_vf.c | 18 +++- src/mesa/pipe/draw/draw_vf.h | 46 +++++---- src/mesa/pipe/draw/draw_vf_generic.c | 2 +- src/mesa/pipe/draw/draw_vf_sse.c | 38 ++++---- 5 files changed, 241 insertions(+), 46 deletions(-) diff --git a/src/mesa/pipe/draw/draw_vbuf.c b/src/mesa/pipe/draw/draw_vbuf.c index 1e260c6..a3d0b5b 100644 --- a/src/mesa/pipe/draw/draw_vbuf.c +++ b/src/mesa/pipe/draw/draw_vbuf.c @@ -35,12 +35,15 @@ #include +#include -#include "pipe/draw/draw_vbuf.h" -#include "pipe/draw/draw_private.h" -#include "pipe/draw/draw_vertex.h" #include "pipe/p_util.h" +#include "draw_vbuf.h" +#include "draw_private.h" +#include "draw_vertex.h" +#include "draw_vf.h" + /** * Vertex buffer emit stage. @@ -55,6 +58,8 @@ struct vbuf_stage { /** Vertex size in bytes */ unsigned vertex_size; + struct draw_vertex_fetch *vf; + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ /** Vertices in hardware format */ @@ -121,6 +126,7 @@ static INLINE void emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { +#if 0 const struct vertex_info *vinfo = vbuf->vinfo; uint i; @@ -151,9 +157,11 @@ emit_vertex( struct vbuf_stage *vbuf, case EMIT_ALL: /* just copy the whole vertex as-is to the vbuf */ assert(i == 0); + assert(j == 0); memcpy(vbuf->vertex_ptr, vertex, vinfo->size * 4); vbuf->vertex_ptr += vinfo->size; - return; + count += vinfo->size; + break; case EMIT_1F: *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); count++; @@ -192,6 +200,156 @@ emit_vertex( struct vbuf_stage *vbuf, } } assert(count == vinfo->size); +#else + if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { + if(vertex->vertex_id < vbuf->nr_vertices) + return; + else + fprintf(stderr, "Bad vertex id 0x%04x (>= 0x%04x)\n", + vertex->vertex_id, vbuf->nr_vertices); + return; + } + + vertex->vertex_id = vbuf->nr_vertices++; + + draw_vf_set_data(vbuf->vf, vertex->data); + draw_vf_emit_vertices(vbuf->vf, 1, vbuf->vertex_ptr); + + vbuf->vertex_ptr += vbuf->vertex_size/4; +#endif +} + + +static void +vbuf_set_vf_attributes(struct vbuf_stage *vbuf ) +{ + const struct vertex_info *vinfo = vbuf->vinfo; + struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; + uint i; + uint count = 0; /* for debug/sanity */ + unsigned nr_attrs = 0; + +// fprintf(stderr, "emit vertex %d to %p\n", +// vbuf->nr_vertices, vbuf->vertex_ptr); + +#if 0 + if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { + if(vertex->vertex_id < vbuf->nr_vertices) + return; + else + fprintf(stderr, "Bad vertex id 0x%04x (>= 0x%04x)\n", + vertex->vertex_id, vbuf->nr_vertices); + return; + } +#endif + + for (i = 0; i < vinfo->num_attribs; i++) { + uint j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + /* no-op */ + break; + case EMIT_ALL: { + /* just copy the whole vertex as-is to the vbuf */ + unsigned k, s = vinfo->size; + assert(i == 0); + assert(j == 0); + /* copy the vertex header */ + /* XXX: we actually don't copy the header, just pad it */ + attrs[nr_attrs].attrib = 0; + attrs[nr_attrs].format = DRAW_EMIT_PAD; + attrs[nr_attrs].offset = offsetof(struct vertex_header, data); + s -= offsetof(struct vertex_header, data)/4; + count += offsetof(struct vertex_header, data)/4; + nr_attrs++; + /* copy the vertex data */ + for(k = 0; k < (s & ~0x3); k += 4) { + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + } + /* tail */ + /* XXX: actually, this shouldn't be needed */ + attrs[nr_attrs].attrib = k/4; + attrs[nr_attrs].offset = 0; + switch(s & 0x3) { + case 0: + break; + case 1: + attrs[nr_attrs].format = DRAW_EMIT_1F; + nr_attrs++; + count += 1; + break; + case 2: + attrs[nr_attrs].format = DRAW_EMIT_2F; + nr_attrs++; + count += 2; + break; + case 3: + attrs[nr_attrs].format = DRAW_EMIT_3F; + nr_attrs++; + count += 3; + break; + } + break; + } + case EMIT_1F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_1F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count++; + break; + case EMIT_1F_PSIZE: + /* FIXME */ + assert(0); + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_PAD; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count++; + break; + case EMIT_2F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_2F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 2; + break; + case EMIT_3F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_3F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 3; + break; + case EMIT_4F: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4F; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 4; + break; + case EMIT_4UB: + attrs[nr_attrs].attrib = j; + attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; + attrs[nr_attrs].offset = 0; + nr_attrs++; + count += 1; + break; + default: + assert(0); + } + } + + assert(count == vinfo->size); + + draw_vf_set_vertex_attributes(vbuf->vf, + attrs, + nr_attrs, + vbuf->vertex_size); } @@ -269,6 +427,7 @@ vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) vbuf->vinfo = vinfo; vbuf->vertex_size = vertex_size; + vbuf_set_vf_attributes(vbuf); if (!vbuf->vertices) vbuf_alloc_vertices(vbuf); @@ -423,7 +582,12 @@ static void vbuf_destroy( struct draw_stage *stage ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); - align_free( vbuf->indices ); + if(vbuf->indices) + align_free( vbuf->indices ); + + if(vbuf->vf) + draw_vf_destroy( vbuf->vf ); + FREE( stage ); } @@ -436,6 +600,9 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, { struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); + if(!vbuf) + return NULL; + vbuf->stage.draw = draw; vbuf->stage.point = vbuf_first_point; vbuf->stage.line = vbuf_first_line; @@ -450,11 +617,17 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->max_indices = render->max_indices; vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + if(!vbuf->indices) + vbuf_destroy(&vbuf->stage); vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; vbuf->prim = ~0; + vbuf->vf = draw_vf_create(FALSE); + if(!vbuf->vf) + vbuf_destroy(&vbuf->stage); + return &vbuf->stage; } diff --git a/src/mesa/pipe/draw/draw_vf.c b/src/mesa/pipe/draw/draw_vf.c index f758460..675974c 100644 --- a/src/mesa/pipe/draw/draw_vf.c +++ b/src/mesa/pipe/draw/draw_vf.c @@ -162,7 +162,7 @@ unsigned draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, for (j = 0, i = 0; i < nr; i++) { const unsigned format = map[i].format; - if (format == EMIT_PAD) { + if (format == DRAW_EMIT_PAD) { if (DBG) _mesa_printf("%d: pad %d, offset %d\n", i, map[i].offset, offset); @@ -261,6 +261,22 @@ void draw_vf_set_sources( struct draw_vertex_fetch *vf, } +/* Set attribute pointers, adjusted for start position: + */ +void draw_vf_set_data( struct draw_vertex_fetch *vf, + float data[][4]) +{ + struct draw_vf_attr *a = vf->attr; + unsigned j; + + for (j = 0; j < vf->attr_count; j++) { + a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ + a[j].inputsize = 4; + a[j].do_insert = a[j].insert[4 - 1]; + a[j].inputptr = (uint8_t *)&data[a[j].attrib][0]; + } +} + /* Emit count VB vertices to dest. */ diff --git a/src/mesa/pipe/draw/draw_vf.h b/src/mesa/pipe/draw/draw_vf.h index 279570a..7619c0e 100644 --- a/src/mesa/pipe/draw/draw_vf.h +++ b/src/mesa/pipe/draw/draw_vf.h @@ -29,9 +29,11 @@ #define DRAW_VF_H -#include "pipe/p_compiler.h" #include "math/m_vector.h" +#include "pipe/p_compiler.h" +#include "draw_vertex.h" + enum { DRAW_VF_ATTRIB_POS = 0, @@ -67,24 +69,24 @@ enum { }; enum draw_vf_attr_format { - EMIT_1F, - EMIT_2F, - EMIT_3F, - EMIT_4F, - EMIT_2F_VIEWPORT, /**< do viewport transform and emit */ - EMIT_3F_VIEWPORT, /**< do viewport transform and emit */ - EMIT_4F_VIEWPORT, /**< do viewport transform and emit */ - EMIT_3F_XYW, /**< for projective texture */ - EMIT_1UB_1F, /**< for fog coordinate */ - EMIT_3UB_3F_RGB, /**< for specular color */ - EMIT_3UB_3F_BGR, /**< for specular color */ - EMIT_4UB_4F_RGBA, /**< for color */ - EMIT_4UB_4F_BGRA, /**< for color */ - EMIT_4UB_4F_ARGB, /**< for color */ - EMIT_4UB_4F_ABGR, /**< for color */ - EMIT_4CHAN_4F_RGBA, /**< for swrast color */ - EMIT_PAD, /**< leave a hole of 'offset' bytes */ - EMIT_MAX + DRAW_EMIT_1F, + DRAW_EMIT_2F, + DRAW_EMIT_3F, + DRAW_EMIT_4F, + DRAW_EMIT_2F_VIEWPORT, /**< do viewport transform and emit */ + DRAW_EMIT_3F_VIEWPORT, /**< do viewport transform and emit */ + DRAW_EMIT_4F_VIEWPORT, /**< do viewport transform and emit */ + DRAW_EMIT_3F_XYW, /**< for projective texture */ + DRAW_EMIT_1UB_1F, /**< for fog coordinate */ + DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ + DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ + DRAW_EMIT_4UB_4F_RGBA, /**< for color */ + DRAW_EMIT_4UB_4F_BGRA, /**< for color */ + DRAW_EMIT_4UB_4F_ARGB, /**< for color */ + DRAW_EMIT_4UB_4F_ABGR, /**< for color */ + DRAW_EMIT_4CHAN_4F_RGBA, /**< for swrast color */ + DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ + DRAW_EMIT_MAX }; struct draw_vf_attr_map { @@ -117,6 +119,10 @@ draw_vf_set_sources( struct draw_vertex_fetch *vf, unsigned start ); void +draw_vf_set_data( struct draw_vertex_fetch *vf, + float data[][4]); + +void draw_vf_emit_vertices( struct draw_vertex_fetch *vf, unsigned count, void *dest ); @@ -243,7 +249,7 @@ struct draw_vf_format_info { const unsigned attrsize; }; -const struct draw_vf_format_info draw_vf_format_info[EMIT_MAX]; +const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX]; #endif diff --git a/src/mesa/pipe/draw/draw_vf_generic.c b/src/mesa/pipe/draw/draw_vf_generic.c index 19e6c58..42effc0 100644 --- a/src/mesa/pipe/draw/draw_vf_generic.c +++ b/src/mesa/pipe/draw/draw_vf_generic.c @@ -735,7 +735,7 @@ static void extract_1ub_1f( const struct draw_vf_attr *a, float *out, const uint } -const struct draw_vf_format_info draw_vf_format_info[EMIT_MAX] = +const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = { { "1f", extract_1f, diff --git a/src/mesa/pipe/draw/draw_vf_sse.c b/src/mesa/pipe/draw/draw_vf_sse.c index 2cf3a45..a7019a4 100644 --- a/src/mesa/pipe/draw/draw_vf_sse.c +++ b/src/mesa/pipe/draw/draw_vf_sse.c @@ -398,19 +398,19 @@ static boolean build_vertex_emit( struct x86_program *p ) * Could be shortcircuited in specific cases: */ switch (a->format) { - case EMIT_1F: + case DRAW_EMIT_1F: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); emit_store(p, dest, 1, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_2F: + case DRAW_EMIT_2F: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); emit_store(p, dest, 2, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_3F: + case DRAW_EMIT_3F: /* Potentially the worst case - hardcode 2+1 copying: */ if (0) { @@ -433,13 +433,13 @@ static boolean build_vertex_emit( struct x86_program *p ) update_src_ptr(p, srcECX, vfESI, a); } break; - case EMIT_4F: + case DRAW_EMIT_4F: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); emit_store(p, dest, 4, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_2F_VIEWPORT: + case DRAW_EMIT_2F_VIEWPORT: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); sse_mulps(&p->func, temp, vp0); @@ -447,7 +447,7 @@ static boolean build_vertex_emit( struct x86_program *p ) emit_store(p, dest, 2, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_3F_VIEWPORT: + case DRAW_EMIT_3F_VIEWPORT: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); sse_mulps(&p->func, temp, vp0); @@ -455,7 +455,7 @@ static boolean build_vertex_emit( struct x86_program *p ) emit_store(p, dest, 3, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_4F_VIEWPORT: + case DRAW_EMIT_4F_VIEWPORT: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); sse_mulps(&p->func, temp, vp0); @@ -463,7 +463,7 @@ static boolean build_vertex_emit( struct x86_program *p ) emit_store(p, dest, 4, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_3F_XYW: + case DRAW_EMIT_3F_XYW: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); @@ -471,7 +471,7 @@ static boolean build_vertex_emit( struct x86_program *p ) update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_1UB_1F: + case DRAW_EMIT_1UB_1F: /* Test for PAD3 + 1UB: */ if (j > 0 && @@ -488,15 +488,15 @@ static boolean build_vertex_emit( struct x86_program *p ) return FALSE; } break; - case EMIT_3UB_3F_RGB: - case EMIT_3UB_3F_BGR: + case DRAW_EMIT_3UB_3F_RGB: + case DRAW_EMIT_3UB_3F_BGR: /* Test for 3UB + PAD1: */ if (j == vf->attr_count - 1 || a[1].vertoffset >= a->vertoffset + 4) { get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - if (a->format == EMIT_3UB_3F_BGR) + if (a->format == DRAW_EMIT_3UB_3F_BGR) sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); emit_pack_store_4ub(p, dest, temp); update_src_ptr(p, srcECX, vfESI, a); @@ -504,7 +504,7 @@ static boolean build_vertex_emit( struct x86_program *p ) /* Test for 3UB + 1UB: */ else if (j < vf->attr_count - 1 && - a[1].format == EMIT_1UB_1F && + a[1].format == DRAW_EMIT_1UB_1F && a[1].vertoffset == a->vertoffset + 3) { get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); @@ -520,7 +520,7 @@ static boolean build_vertex_emit( struct x86_program *p ) /* Rearrange and possibly do BGR conversion: */ - if (a->format == EMIT_3UB_3F_BGR) + if (a->format == DRAW_EMIT_3UB_3F_BGR) sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); else sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); @@ -534,34 +534,34 @@ static boolean build_vertex_emit( struct x86_program *p ) return FALSE; /* add this later */ break; - case EMIT_4UB_4F_RGBA: + case DRAW_EMIT_4UB_4F_RGBA: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); emit_pack_store_4ub(p, dest, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_4UB_4F_BGRA: + case DRAW_EMIT_4UB_4F_BGRA: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); emit_pack_store_4ub(p, dest, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_4UB_4F_ARGB: + case DRAW_EMIT_4UB_4F_ARGB: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); emit_pack_store_4ub(p, dest, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_4UB_4F_ABGR: + case DRAW_EMIT_4UB_4F_ABGR: get_src_ptr(p, srcECX, vfESI, a); emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); emit_pack_store_4ub(p, dest, temp); update_src_ptr(p, srcECX, vfESI, a); break; - case EMIT_4CHAN_4F_RGBA: + case DRAW_EMIT_4CHAN_4F_RGBA: switch (CHAN_TYPE) { case GL_UNSIGNED_BYTE: get_src_ptr(p, srcECX, vfESI, a); -- 2.7.4