#include <assert.h>
+#include <stddef.h>
-#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.
/** 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 */
emit_vertex( struct vbuf_stage *vbuf,
struct vertex_header *vertex )
{
+#if 0
const struct vertex_info *vinfo = vbuf->vinfo;
uint i;
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++;
}
}
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);
}
vbuf->vinfo = vinfo;
vbuf->vertex_size = vertex_size;
+ vbuf_set_vf_attributes(vbuf);
if (!vbuf->vertices)
vbuf_alloc_vertices(vbuf);
{
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 );
}
{
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;
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;
}
#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,
};
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 {
GLvector4f * const attrib[],
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,
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
* 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) {
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);
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);
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);
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));
update_src_ptr(p, srcECX, vfESI, a);
break;
- case EMIT_1UB_1F:
+ case DRAW_EMIT_1UB_1F:
/* Test for PAD3 + 1UB:
*/
if (j > 0 &&
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);
/* 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);
/* 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));
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);