summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-02-18 12:54:26 +0000
committerKeith Whitwell <[email protected]>2009-02-18 12:54:26 +0000
commit89e2b9c6c24e1a0b7690b9a7502b0ea198069d10 (patch)
tree520ef9752161f6f79851f8d44290baafd72c0a4d /src/gallium/drivers
parentea4bf267e4b023b08043f91ac44592fed1736e7f (diff)
parentb57031624ef94dd3128f989acabdffa2f2a32f57 (diff)
Merge commit 'origin/draw-vbuf-interface'
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c57
-rw-r--r--src/gallium/drivers/nv04/nv04_prim_vbuf.c22
-rw-r--r--src/gallium/drivers/nv10/nv10_prim_vbuf.c36
-rw-r--r--src/gallium/drivers/nv20/nv20_prim_vbuf.c58
-rw-r--r--src/gallium/drivers/r300/r300_reg.h88
-rw-r--r--src/gallium/drivers/r300/r300_swtcl_emit.c333
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c45
7 files changed, 450 insertions, 189 deletions
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index 2dc2e073291..58c41840e1f 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -62,7 +62,7 @@ struct i915_vbuf_render {
struct i915_context *i915;
/** Vertex size in bytes */
- unsigned vertex_size;
+ size_t vertex_size;
/** Software primitive */
unsigned prim;
@@ -79,6 +79,7 @@ struct i915_vbuf_render {
size_t vbo_offset;
void *vbo_ptr;
size_t vbo_alloc_size;
+ size_t vbo_max_used;
};
@@ -108,7 +109,7 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
}
-static void *
+static boolean
i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
@@ -124,7 +125,8 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
} else {
i915->vbo_flushed = 0;
- pipe_buffer_reference(screen, &i915_render->vbo, NULL);
+ if (i915_render->vbo)
+ pipe_buffer_reference(screen, &i915_render->vbo, NULL);
}
if (!i915_render->vbo) {
@@ -134,19 +136,49 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
64,
I915_BUFFER_USAGE_LIT_VERTEX,
i915_render->vbo_size);
- i915_render->vbo_ptr = pipe_buffer_map(screen,
- i915_render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- pipe_buffer_unmap(screen, i915_render->vbo);
+
}
+ i915_render->vertex_size = vertex_size;
i915->vbo = i915_render->vbo;
i915->vbo_offset = i915_render->vbo_offset;
i915->dirty |= I915_NEW_VBO;
+ if (!i915_render->vbo)
+ return FALSE;
+ return TRUE;
+}
+
+
+static void *
+i915_vbuf_render_map_vertices( struct vbuf_render *render )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ struct pipe_screen *screen = i915->pipe.screen;
+
+ if (i915->vbo_flushed)
+ debug_printf("%s bad vbo flush occured stalling on hw\n");
+
+ i915_render->vbo_ptr = pipe_buffer_map(screen,
+ i915_render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
}
+static void
+i915_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ struct pipe_screen *screen = i915->pipe.screen;
+
+ i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
+ pipe_buffer_unmap(screen, i915_render->vbo);
+}
static boolean
i915_vbuf_render_set_primitive( struct vbuf_render *render,
@@ -454,18 +486,15 @@ out:
static void
-i915_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+i915_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- size_t size = (size_t)vertex_size * (size_t)vertices_used;
assert(i915->vbo);
- i915_render->vbo_offset += size;
+ i915_render->vbo_offset += i915_render->vbo_max_used;
+ i915_render->vbo_max_used = 0;
i915->vbo = NULL;
i915->dirty |= I915_NEW_VBO;
}
@@ -499,6 +528,8 @@ i915_vbuf_render_create( struct i915_context *i915 )
i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;
i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
+ i915_render->base.map_vertices = i915_vbuf_render_map_vertices;
+ i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices;
i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
i915_render->base.draw = i915_vbuf_render_draw;
i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c
index 221bee4777a..f6458232ae5 100644
--- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c
+++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c
@@ -51,7 +51,7 @@ nv04_vbuf_render_get_vertex_info( struct vbuf_render *render )
}
-static void *
+static boolean
nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
@@ -61,9 +61,22 @@ nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,
nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE);
assert(!nv04_render->buffer);
+ return nv04_render->buffer ? TRUE : FALSE;
+}
+
+static void *
+nv04_vbuf_render_map_vertices( struct vbuf_render *render )
+{
+ struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
return nv04_render->buffer;
}
+static void
+nv04_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+{
+}
static boolean
nv04_vbuf_render_set_primitive( struct vbuf_render *render,
@@ -244,10 +257,7 @@ nv04_vbuf_render_draw( struct vbuf_render *render,
static void
-nv04_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+nv04_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
@@ -278,6 +288,8 @@ nv04_vbuf_render_create( struct nv04_context *nv04 )
nv04_render->base.max_indices = 65536;
nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info;
nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices;
+ nv04_render->base.map_vertices = nv04_vbuf_render_map_vertices;
+ nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_vertices;
nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive;
nv04_render->base.draw = nv04_vbuf_render_draw;
nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices;
diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
index 5e5436be537..491a8818068 100644
--- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c
+++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
@@ -99,8 +99,7 @@ nv10_vbuf_render_get_vertex_info( struct vbuf_render *render )
return &nv10->vertex_info;
}
-
-static void *
+static boolean
nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
@@ -115,11 +114,35 @@ nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,
nv10->dirty |= NV10_NEW_VTXARRAYS;
+ if (nv10_render->buffer)
+ return FALSE;
+ return TRUE;
+}
+
+static void *
+nv10_vbuf_render_map_vertices( struct vbuf_render *render )
+{
+ struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
+ struct nv10_context *nv10 = nv10_render->nv10;
+ struct pipe_winsys *winsys = nv10->pipe.winsys;
+
return winsys->buffer_map(winsys,
nv10_render->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
}
+static void
+nv10_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+{
+ struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
+ struct nv10_context *nv10 = nv10_render->nv10;
+ struct pipe_winsys *winsys = nv10->pipe.winsys;
+
+ assert(!nv10_render->buffer);
+ winsys->buffer_unmap(winsys, nv10_render->buffer);
+}
static boolean
nv10_vbuf_render_set_primitive( struct vbuf_render *render,
@@ -176,18 +199,13 @@ nv10_vbuf_render_draw( struct vbuf_render *render,
static void
-nv10_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+nv10_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
struct nv10_context *nv10 = nv10_render->nv10;
- struct pipe_winsys *winsys = nv10->pipe.winsys;
struct pipe_screen *pscreen = &nv10->screen->pipe;
assert(nv10_render->buffer);
- winsys->buffer_unmap(winsys, nv10_render->buffer);
pipe_buffer_reference(pscreen, &nv10_render->buffer, NULL);
}
@@ -214,6 +232,8 @@ nv10_vbuf_render_create( struct nv10_context *nv10 )
nv10_render->base.max_indices = 1024;
nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info;
nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices;
+ nv10_render->base.map_vertices = nv10_vbuf_render_map_vertices;
+ nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_vertices;
nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive;
nv10_render->base.draw = nv10_vbuf_render_draw;
nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices;
diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
index 187136ce7b7..319e1f65572 100644
--- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c
+++ b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
@@ -109,18 +109,15 @@ nv20__allocate_mbuffer(struct nv20_vbuf_render *nv20_render, size_t size)
return nv20_render->mbuffer;
}
-static void *
+static void
nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size)
{
struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
nv20_render->pbuffer = winsys->buffer_create(winsys, 64,
PIPE_BUFFER_USAGE_VERTEX, size);
- return winsys->buffer_map(winsys,
- nv20_render->pbuffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
}
-static void *
+static boolean
nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
@@ -137,15 +134,49 @@ nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,
* buffer, the data will be passed directly via the fifo.
*/
/* XXX: Pipe vertex buffers don't work. */
- if (0 && size > 16 * 1024)
- buf = nv20__allocate_pbuffer(nv20_render, size);
- else
+ if (0 && size > 16 * 1024) {
+ nv20__allocate_pbuffer(nv20_render, size);
+ /* umm yeah so this is ugly */
+ buf = nv20_render->pbuffer;
+ } else {
buf = nv20__allocate_mbuffer(nv20_render, size);
+ }
if (buf)
nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS;
- return buf;
+ return buf ? TRUE : FALSE;
+}
+
+static void *
+nv20_vbuf_render_map_vertices( struct vbuf_render *render )
+{
+ struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
+ struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+
+ if (nv20_render->pbuffer) {
+ return winsys->buffer_map(winsys,
+ nv20_render->pbuffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ } else if (nv20_render->mbuffer) {
+ return nv20_render->mbuffer;
+ } else
+ assert(0);
+
+ /* warnings be gone */
+ return NULL;
+}
+
+static void
+nv20_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+{
+ struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
+ struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+
+ if (nv20_render->pbuffer)
+ winsys->buffer_unmap(winsys, nv20_render->pbuffer);
}
static boolean
@@ -323,18 +354,13 @@ nv20_vbuf_render_draw( struct vbuf_render *render,
static void
-nv20_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+nv20_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
struct nv20_context *nv20 = nv20_render->nv20;
- struct pipe_winsys *winsys = nv20->pipe.winsys;
struct pipe_screen *pscreen = &nv20->screen->pipe;
if (nv20_render->pbuffer) {
- winsys->buffer_unmap(winsys, nv20_render->pbuffer);
pipe_buffer_reference(pscreen, &nv20_render->pbuffer, NULL);
} else if (nv20_render->mbuffer) {
FREE(nv20_render->mbuffer);
@@ -371,6 +397,8 @@ nv20_vbuf_render_create( struct nv20_context *nv20 )
nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info;
nv20_render->base.allocate_vertices =
nv20_vbuf_render_allocate_vertices;
+ nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices;
+ nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices;
nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive;
nv20_render->base.draw = nv20_vbuf_render_draw;
nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices;
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 468e0a2e44b..be26b13b0b0 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -64,7 +64,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R300_SE_VPORT_ZSCALE 0x1DA8
#define R300_SE_VPORT_ZOFFSET 0x1DAC
-
+#define R300_VAP_PORT_IDX0 0x2040
/*
* Vertex Array Processing (VAP) Control
*/
@@ -732,8 +732,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R500_RS_IP_TEX_PTR_Q_SHIFT 18
#define R500_RS_IP_COL_PTR_SHIFT 24
#define R500_RS_IP_COL_FMT_SHIFT 27
-# define R500_RS_COL_PTR(x) (x << 24)
-# define R500_RS_COL_FMT(x) (x << 27)
+# define R500_RS_COL_PTR(x) ((x) << 24)
+# define R500_RS_COL_FMT(x) ((x) << 27)
/* gap */
#define R500_RS_IP_OFFSET_DIS (0 << 31)
#define R500_RS_IP_OFFSET_EN (1 << 31)
@@ -1175,8 +1175,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_RS_INTERP_SRC_SHIFT 2 /* TODO: check for removal */
# define R300_RS_INTERP_SRC_MASK (7 << 2) /* TODO: check for removal */
# define R300_RS_TEX_PTR(x) (x << 0)
-# define R300_RS_COL_PTR(x) (x << 6)
-# define R300_RS_COL_FMT(x) (x << 9)
+# define R300_RS_COL_PTR(x) ((x) << 6)
+# define R300_RS_COL_FMT(x) ((x) << 9)
# define R300_RS_COL_FMT_RGBA 0
# define R300_RS_COL_FMT_RGB0 1
# define R300_RS_COL_FMT_RGB1 2
@@ -1186,10 +1186,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_RS_COL_FMT_111A 8
# define R300_RS_COL_FMT_1110 9
# define R300_RS_COL_FMT_1111 10
-# define R300_RS_SEL_S(x) (x << 13)
-# define R300_RS_SEL_T(x) (x << 16)
-# define R300_RS_SEL_R(x) (x << 19)
-# define R300_RS_SEL_Q(x) (x << 22)
+# define R300_RS_SEL_S(x) ((x) << 13)
+# define R300_RS_SEL_T(x) ((x) << 16)
+# define R300_RS_SEL_R(x) ((x) << 19)
+# define R300_RS_SEL_Q(x) ((x) << 22)
# define R300_RS_SEL_C0 0
# define R300_RS_SEL_C1 1
# define R300_RS_SEL_C2 2
@@ -1708,7 +1708,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_C3_SEL_R (1 << 14)
# define R300_C3_SEL_G (2 << 14)
# define R300_C3_SEL_B (3 << 14)
-# define R300_OUT_SIGN(x) (x << 16)
+# define R300_OUT_SIGN(x) ((x) << 16)
# define R500_ROUND_ADJ (1 << 20)
/* ALU
@@ -2732,7 +2732,7 @@ enum {
# define R500_ALPHA_OP_COS 13
# define R500_ALPHA_OP_MDH 14
# define R500_ALPHA_OP_MDV 15
-# define R500_ALPHA_ADDRD(x) (x << 4)
+# define R500_ALPHA_ADDRD(x) ((x) << 4)
# define R500_ALPHA_ADDRD_REL (1 << 11)
# define R500_ALPHA_SEL_A_SHIFT 12
# define R500_ALPHA_SEL_A_SRC0 (0 << 12)
@@ -2776,16 +2776,16 @@ enum {
# define R500_ALPHA_OMOD_DIV_4 (5 << 26)
# define R500_ALPHA_OMOD_DIV_8 (6 << 26)
# define R500_ALPHA_OMOD_DISABLE (7 << 26)
-# define R500_ALPHA_TARGET(x) (x << 29)
+# define R500_ALPHA_TARGET(x) ((x) << 29)
# define R500_ALPHA_W_OMASK (1 << 31)
#define R500_US_ALU_ALPHA_ADDR_0 0x9800
-# define R500_ALPHA_ADDR0(x) (x << 0)
+# define R500_ALPHA_ADDR0(x) ((x) << 0)
# define R500_ALPHA_ADDR0_CONST (1 << 8)
# define R500_ALPHA_ADDR0_REL (1 << 9)
-# define R500_ALPHA_ADDR1(x) (x << 10)
+# define R500_ALPHA_ADDR1(x) ((x) << 10)
# define R500_ALPHA_ADDR1_CONST (1 << 18)
# define R500_ALPHA_ADDR1_REL (1 << 19)
-# define R500_ALPHA_ADDR2(x) (x << 20)
+# define R500_ALPHA_ADDR2(x) ((x) << 20)
# define R500_ALPHA_ADDR2_CONST (1 << 28)
# define R500_ALPHA_ADDR2_REL (1 << 29)
# define R500_ALPHA_SRCP_OP_1_MINUS_2A0 (0 << 30)
@@ -2806,7 +2806,7 @@ enum {
# define R500_ALU_RGBA_OP_SOP (10 << 0)
# define R500_ALU_RGBA_OP_MDH (11 << 0)
# define R500_ALU_RGBA_OP_MDV (12 << 0)
-# define R500_ALU_RGBA_ADDRD(x) (x << 4)
+# define R500_ALU_RGBA_ADDRD(x) ((x) << 4)
# define R500_ALU_RGBA_ADDRD_REL (1 << 11)
# define R500_ALU_RGBA_SEL_C_SHIFT 12
# define R500_ALU_RGBA_SEL_C_SRC0 (0 << 12)
@@ -2933,16 +2933,16 @@ enum {
# define R500_ALU_RGB_OMOD_DIV_4 (5 << 26)
# define R500_ALU_RGB_OMOD_DIV_8 (6 << 26)
# define R500_ALU_RGB_OMOD_DISABLE (7 << 26)
-# define R500_ALU_RGB_TARGET(x) (x << 29)
+# define R500_ALU_RGB_TARGET(x) ((x) << 29)
# define R500_ALU_RGB_WMASK (1 << 31)
#define R500_US_ALU_RGB_ADDR_0 0x9000
-# define R500_RGB_ADDR0(x) (x << 0)
+# define R500_RGB_ADDR0(x) ((x) << 0)
# define R500_RGB_ADDR0_CONST (1 << 8)
# define R500_RGB_ADDR0_REL (1 << 9)
-# define R500_RGB_ADDR1(x) (x << 10)
+# define R500_RGB_ADDR1(x) ((x) << 10)
# define R500_RGB_ADDR1_CONST (1 << 18)
# define R500_RGB_ADDR1_REL (1 << 19)
-# define R500_RGB_ADDR2(x) (x << 20)
+# define R500_RGB_ADDR2(x) ((x) << 20)
# define R500_RGB_ADDR2_CONST (1 << 28)
# define R500_RGB_ADDR2_REL (1 << 29)
# define R500_RGB_SRCP_OP_1_MINUS_2RGB0 (0 << 30)
@@ -2998,19 +2998,19 @@ enum {
/* note that these are 8 bit lengths, despite the offsets, at least for R500 */
#define R500_US_CODE_ADDR 0x4630
-# define R500_US_CODE_START_ADDR(x) (x << 0)
-# define R500_US_CODE_END_ADDR(x) (x << 16)
+# define R500_US_CODE_START_ADDR(x) ((x) << 0)
+# define R500_US_CODE_END_ADDR(x) ((x) << 16)
#define R500_US_CODE_OFFSET 0x4638
-# define R500_US_CODE_OFFSET_ADDR(x) (x << 0)
+# define R500_US_CODE_OFFSET_ADDR(x) ((x) << 0)
#define R500_US_CODE_RANGE 0x4634
-# define R500_US_CODE_RANGE_ADDR(x) (x << 0)
-# define R500_US_CODE_RANGE_SIZE(x) (x << 16)
+# define R500_US_CODE_RANGE_ADDR(x) ((x) << 0)
+# define R500_US_CODE_RANGE_SIZE(x) ((x) << 16)
#define R500_US_CONFIG 0x4600
# define R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO (1 << 1)
#define R500_US_FC_ADDR_0 0xa000
-# define R500_FC_BOOL_ADDR(x) (x << 0)
-# define R500_FC_INT_ADDR(x) (x << 8)
-# define R500_FC_JUMP_ADDR(x) (x << 16)
+# define R500_FC_BOOL_ADDR(x) ((x) << 0)
+# define R500_FC_INT_ADDR(x) ((x) << 8)
+# define R500_FC_JUMP_ADDR(x) ((x) << 16)
# define R500_FC_JUMP_GLOBAL (1 << 31)
#define R500_US_FC_BOOL_CONST 0x4620
# define R500_FC_KBOOL(x) (x)
@@ -3031,8 +3031,8 @@ enum {
# define R500_FC_A_OP_NONE (0 << 6)
# define R500_FC_A_OP_POP (1 << 6)
# define R500_FC_A_OP_PUSH (2 << 6)
-# define R500_FC_JUMP_FUNC(x) (x << 8)
-# define R500_FC_B_POP_CNT(x) (x << 16)
+# define R500_FC_JUMP_FUNC(x) ((x) << 8)
+# define R500_FC_B_POP_CNT(x) ((x) << 16)
# define R500_FC_B_OP0_NONE (0 << 24)
# define R500_FC_B_OP0_DECR (1 << 24)
# define R500_FC_B_OP0_INCR (2 << 24)
@@ -3041,18 +3041,18 @@ enum {
# define R500_FC_B_OP1_INCR (2 << 26)
# define R500_FC_IGNORE_UNCOVERED (1 << 28)
#define R500_US_FC_INT_CONST_0 0x4c00
-# define R500_FC_INT_CONST_KR(x) (x << 0)
-# define R500_FC_INT_CONST_KG(x) (x << 8)
-# define R500_FC_INT_CONST_KB(x) (x << 16)
+# define R500_FC_INT_CONST_KR(x) ((x) << 0)
+# define R500_FC_INT_CONST_KG(x) ((x) << 8)
+# define R500_FC_INT_CONST_KB(x) ((x) << 16)
/* _0 through _15 */
#define R500_US_FORMAT0_0 0x4640
-# define R500_FORMAT_TXWIDTH(x) (x << 0)
-# define R500_FORMAT_TXHEIGHT(x) (x << 11)
-# define R500_FORMAT_TXDEPTH(x) (x << 22)
+# define R500_FORMAT_TXWIDTH(x) ((x) << 0)
+# define R500_FORMAT_TXHEIGHT(x) ((x) << 11)
+# define R500_FORMAT_TXDEPTH(x) ((x) << 22)
#define R500_US_PIXSIZE 0x4604
# define R500_PIX_SIZE(x) (x)
#define R500_US_TEX_ADDR_0 0x9800
-# define R500_TEX_SRC_ADDR(x) (x << 0)
+# define R500_TEX_SRC_ADDR(x) ((x) << 0)
# define R500_TEX_SRC_ADDR_REL (1 << 7)
# define R500_TEX_SRC_S_SWIZ_R (0 << 8)
# define R500_TEX_SRC_S_SWIZ_G (1 << 8)
@@ -3070,7 +3070,7 @@ enum {
# define R500_TEX_SRC_Q_SWIZ_G (1 << 14)
# define R500_TEX_SRC_Q_SWIZ_B (2 << 14)
# define R500_TEX_SRC_Q_SWIZ_A (3 << 14)
-# define R500_TEX_DST_ADDR(x) (x << 16)
+# define R500_TEX_DST_ADDR(x) ((x) << 16)
# define R500_TEX_DST_ADDR_REL (1 << 23)
# define R500_TEX_DST_R_SWIZ_R (0 << 24)
# define R500_TEX_DST_R_SWIZ_G (1 << 24)
@@ -3089,7 +3089,7 @@ enum {
# define R500_TEX_DST_A_SWIZ_B (2 << 30)
# define R500_TEX_DST_A_SWIZ_A (3 << 30)
#define R500_US_TEX_ADDR_DXDY_0 0xa000
-# define R500_DX_ADDR(x) (x << 0)
+# define R500_DX_ADDR(x) ((x) << 0)
# define R500_DX_ADDR_REL (1 << 7)
# define R500_DX_S_SWIZ_R (0 << 8)
# define R500_DX_S_SWIZ_G (1 << 8)
@@ -3107,7 +3107,7 @@ enum {
# define R500_DX_Q_SWIZ_G (1 << 14)
# define R500_DX_Q_SWIZ_B (2 << 14)
# define R500_DX_Q_SWIZ_A (3 << 14)
-# define R500_DY_ADDR(x) (x << 16)
+# define R500_DY_ADDR(x) ((x) << 16)
# define R500_DY_ADDR_REL (1 << 17)
# define R500_DY_S_SWIZ_R (0 << 24)
# define R500_DY_S_SWIZ_G (1 << 24)
@@ -3126,7 +3126,7 @@ enum {
# define R500_DY_Q_SWIZ_B (2 << 30)
# define R500_DY_Q_SWIZ_A (3 << 30)
#define R500_US_TEX_INST_0 0x9000
-# define R500_TEX_ID(x) (x << 16)
+# define R500_TEX_ID(x) ((x) << 16)
# define R500_TEX_INST_NOP (0 << 22)
# define R500_TEX_INST_LD (1 << 22)
# define R500_TEX_INST_TEXKILL (2 << 22)
@@ -3187,9 +3187,9 @@ enum {
#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00
#define R300_PACKET3_INDX_BUFFER 0x00003300
-# define R300_EB_UNK1_SHIFT 24
-# define R300_EB_UNK1 (0x80<<24)
-# define R300_EB_UNK2 0x0810
+# define R300_INDX_BUFFER_DST_SHIFT 0
+# define R300_INDX_BUFFER_SKIP_SHIFT 16
+# define R300_INDX_BUFFER_ONE_REG_WR (1<<31)
/* Same as R300_PACKET3_3D_DRAW_VBUF but without VAP_VTX_FMT */
#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400
diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_swtcl_emit.c
index 76ef48962b9..fb009247a50 100644
--- a/src/gallium/drivers/r300/r300_swtcl_emit.c
+++ b/src/gallium/drivers/r300/r300_swtcl_emit.c
@@ -21,144 +21,295 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "draw/draw_pipe.h"
+#include "draw/draw_vbuf.h"
#include "util/u_memory.h"
#include "r300_cs.h"
#include "r300_context.h"
#include "r300_reg.h"
-/* r300_swtcl_emit: Primitive vertex emission using an immediate
- * vertex buffer and no HW TCL. */
+/* r300_swtcl_emit: Vertex and index buffer primitive emission. No HW TCL. */
-struct swtcl_stage {
+struct r300_swtcl_render {
/* Parent class */
- struct draw_stage draw;
-
+ struct vbuf_render base;
+
+ /* Pipe context */
struct r300_context* r300;
+
+ /* Vertex information */
+ size_t vertex_size;
+ unsigned prim;
+ unsigned hwprim;
+
+ /* VBO */
+ struct pipe_buffer* vbo;
+ size_t vbo_size;
+ size_t vbo_offset;
+ void* vbo_map;
+ size_t vbo_alloc_size;
+ size_t vbo_max_used;
};
-static INLINE struct swtcl_stage* swtcl_stage(struct draw_stage* draw) {
- return (struct swtcl_stage*)draw;
+static INLINE struct r300_swtcl_render*
+r300_swtcl_render(struct vbuf_render* render)
+{
+ return (struct r300_swtcl_render*)render;
}
-static INLINE void r300_emit_vertex(struct r300_context* r300,
- const struct vertex_header* vertex)
+static const struct vertex_info*
+r300_swtcl_render_get_vertex_info(struct vbuf_render* render)
{
- struct vertex_info* vinfo = &r300->vertex_info;
- CS_LOCALS(r300);
- uint i, j;
-
- for (i = 0; i < vinfo->num_attribs; i++) {
- j = vinfo->attrib[i].src_index;
- switch (vinfo->attrib[i].emit) {
- case EMIT_1F:
- OUT_CS_32F(vertex->data[j][0]);
- break;
- case EMIT_2F:
- OUT_CS_32F(vertex->data[j][0]);
- OUT_CS_32F(vertex->data[j][1]);
- break;
- case EMIT_3F:
- OUT_CS_32F(vertex->data[j][0]);
- OUT_CS_32F(vertex->data[j][1]);
- OUT_CS_32F(vertex->data[j][2]);
- break;
- case EMIT_4F:
- OUT_CS_32F(vertex->data[j][0]);
- OUT_CS_32F(vertex->data[j][1]);
- OUT_CS_32F(vertex->data[j][2]);
- OUT_CS_32F(vertex->data[j][3]);
- break;
- default:
- debug_printf("r300: Unknown emit value %d\n",
- vinfo->attrib[i].emit);
- break;
- }
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct r300_context* r300 = r300render->r300;
+
+ r300_update_derived_state(r300);
+
+ return &r300->vertex_info;
+}
+
+static boolean r300_swtcl_render_allocate_vertices(struct vbuf_render* render,
+ ushort vertex_size,
+ ushort count)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct r300_context* r300 = r300render->r300;
+ struct pipe_screen* screen = r300->context.screen;
+ size_t size = (size_t)vertex_size * (size_t)count;
+
+ if (r300render->vbo) {
+ pipe_buffer_reference(screen, r300render->vbo, NULL);
+ }
+
+ r300render->vbo_size = MAX2(size, r300render->vbo_alloc_size);
+ r300render->vbo_offset = 0;
+ r300render->vbo = pipe_buffer_create(screen,
+ 64,
+ PIPE_BUFFER_USAGE_VERTEX,
+ r300render->vbo_size);
+
+ r300render->vertex_size = vertex_size;
+
+ if (r300render->vbo) {
+ return true;
+ } else {
+ return false;
}
}
-static INLINE void r300_emit_prim(struct draw_stage* draw,
- struct prim_header* prim,
- unsigned hwprim,
- unsigned count)
+static void* r300_swtcl_render_map_vertices(struct vbuf_render* render)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct pipe_screen* screen = r300render->r300->context.screen;
+
+ r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ return (unsigned char*)r300render->vbo_map + r300render->vbo_offset;
+}
+
+static void* r300_swtcl_render_unmap_vertices(struct vbuf_render* render,
+ ushort min,
+ ushort max)
{
- struct r300_context* r300 = swtcl_stage(draw)->r300;
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct pipe_screen* screen = r300render->r300->context.screen;
+
+ r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
+ r300render->vertex_size * (max + 1));
+
+ pipe_buffer_unmap(screen, r300render->vbo);
+}
+
+static void r300_swtcl_render_release_vertices(struct vbuf_render* render)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct pipe_screen* screen = r300render->r300->context.screen;
+
+ pipe_buffer_reference(screen, r300render->vbo, NULL);
+}
+
+static boolean r300_swtcl_render_set_primitive(struct vbuf_render* render,
+ unsigned prim)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ r300render->prim = prim;
+
+ switch (prim) {
+ case PIPE_PRIM_POINTS:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_POINTS;
+ break;
+ case PIPE_PRIM_LINES:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINES;
+ break;
+ case PIPE_PRIM_LINE_LOOP:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
+ break;
+ case PIPE_PRIM_LINE_STRIP:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLES;
+ break;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
+ break;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
+ break;
+ case PIPE_PRIM_QUADS:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_QUADS;
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
+ break;
+ case PIPE_PRIM_POLYGON:
+ r300render->hwprim = R300_VAP_VF_CNTL__PRIM_POLYGON;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+static void r300_swtcl_render_draw_arrays(struct vbuf_render* render,
+ unsigned start,
+ unsigned count)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct r300_context* r300 = r300render->r300;
+ struct pipe_screen* screen = r300->context.screen;
+
CS_LOCALS(r300);
- int i;
+ /* Make sure that all possible state is emitted. */
+ r300_update_derived_state(r300);
r300_emit_dirty_state(r300);
+ /* Take care of vertex formats and routes */
BEGIN_CS(3);
OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
OUT_CS(r300->vertex_info.hwfmt[0]);
OUT_CS(r300->vertex_info.hwfmt[1]);
END_CS;
- BEGIN_CS(2 + (count * r300->vertex_info.size) + 2);
- OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, count));
- OUT_CS(hwprim | R300_PRIM_WALK_RING |
- (count << R300_PRIM_NUM_VERTICES_SHIFT));
+ /* Draw stuff! */
+ BEGIN_CS(2);
+ OUT_CS(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0));
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
+}
+
+static void r300_swtcl_render_draw(struct vbuf_render* render,
+ const ushort* indices,
+ uint count)
+{
+ struct r300_swtcl_render* r300render = r300_swtcl_render(render);
+ struct r300_context* r300 = r300render->r300;
+ struct pipe_screen* screen = r300->context.screen;
+ struct pipe_buffer* index_buffer;
+ void* index_map;
+
+ CS_LOCALS(r300);
+
+ /* Make sure that all possible state is emitted. */
+ r300_update_derived_state(r300);
+ r300_emit_dirty_state(r300);
- for (i = 0; i < count; i++) {
- r300_emit_vertex(r300, prim->v[i]);
+ /* Send our indices into an index buffer. */
+ index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX,
+ count * 4);
+ if (!index_buffer) {
+ return;
}
+ index_map = pipe_buffer_map(screen, index_buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memcpy(index_map, indices, count * 4);
+ pipe_buffer_unmap(screen, index_buffer);
+
+ /* Take care of vertex formats and routes */
+ BEGIN_CS(3);
+ OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
+ OUT_CS(r300->vertex_info.hwfmt[0]);
+ OUT_CS(r300->vertex_info.hwfmt[1]);
END_CS;
-}
-/* Just as an aside...
- *
- * Radeons can do many more primitives:
- * - Line strip
- * - Triangle fan
- * - Triangle strip
- * - Line loop
- * - Quads
- * - Quad strip
- * - Polygons
- *
- * The following were just the only ones in Draw. */
+ /* Draw stuff! */
+ BEGIN_CS(10);
+ OUT_CS(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0));
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300render->hwprim | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
-static void r300_emit_point(struct draw_stage* draw, struct prim_header* prim)
-{
- r300_emit_prim(draw, prim, R300_PRIM_TYPE_POINT, 1);
+ OUT_CS(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2));
+ OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2));
+ OUT_CS_RELOC(index_buffer, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
}
-static void r300_emit_line(struct draw_stage* draw, struct prim_header* prim)
+static void r300_swtcl_render_destroy(struct vbuf_render* render)
{
- r300_emit_prim(draw, prim, R300_PRIM_TYPE_LINE, 2);
+ FREE(render);
}
-static void r300_emit_tri(struct draw_stage* draw, struct prim_header* prim)
+static struct vbuf_render* r300_swtcl_render_create(struct r300_context* r300)
{
- r300_emit_prim(draw, prim, R300_PRIM_TYPE_TRI_LIST, 3);
-}
+ struct r300_swtcl_render* r300render = CALLOC_STRUCT(r300_swtcl_render);
+ struct pipe_screen* screen = r300->context.screen;
-static void r300_swtcl_flush(struct draw_stage* draw, unsigned flags)
-{
-}
+ r300render->r300 = r300;
-static void r300_reset_stipple(struct draw_stage* draw)
-{
- /* XXX */
-}
+ /* XXX find real numbers plz */
+ r300render->base.max_vertex_buffer_bytes = 128 * 1024;
+ r300render->base.max_indices = 16 * 1024;
-static void r300_swtcl_destroy(struct draw_stage* draw)
-{
- FREE(draw);
+ r300render->base.get_vertex_info = r300_swtcl_render_get_vertex_info;
+ r300render->base.allocate_vertices = r300_swtcl_render_allocate_vertices;
+ r300render->base.map_vertices = r300_swtcl_render_map_vertices;
+ r300render->base.unmap_vertices = r300_swtcl_render_unmap_vertices;
+ r300render->base.set_primitive = r300_swtcl_render_set_primitive;
+ r300render->base.draw = r300_swtcl_render_draw;
+ r300render->base.draw_arrays = r300_swtcl_render_draw_arrays;
+ r300render->base.release_vertices = r300_swtcl_render_release_vertices;
+ r300render->base.destroy = r300_swtcl_render_destroy;
+
+ /* XXX bonghits ahead
+ r300render->vbo_alloc_size = 128 * 4096;
+ r300render->vbo_size = r300render->vbo_alloc_size;
+ r300render->vbo_offset = 0;
+ r300render->vbo = pipe_buffer_create(screen,
+ 64,
+ PIPE_BUFFER_USAGE_VERTEX,
+ r300render->vbo_size);
+ r300render->vbo_map = pipe_buffer_map(screen,
+ r300render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ pipe_buffer_unmap(screen, r300render->vbo); */
+
+ return &r300render->base;
}
struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300)
{
- struct swtcl_stage* swtcl = CALLOC_STRUCT(swtcl_stage);
+ struct vbuf_render* render;
+ struct draw_stage* stage;
+
+ render = r300_swtcl_render_create(r300);
+
+ if (!render) {
+ return NULL;
+ }
+
+ stage = draw_vbuf_stage(r300->draw, render);
+
+ if (!stage) {
+ render->destroy(render);
+ return NULL;
+ }
- swtcl->r300 = r300;
- swtcl->draw.point = r300_emit_point;
- swtcl->draw.line = r300_emit_line;
- swtcl->draw.tri = r300_emit_tri;
- swtcl->draw.flush = r300_swtcl_flush;
- swtcl->draw.reset_stipple_counter = r300_reset_stipple;
- swtcl->draw.destroy = r300_swtcl_destroy;
+ draw_set_render(r300->draw, render);
- return &swtcl->draw;
+ return stage;
}
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 9cd5784e5bc..d56eed80a4f 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -60,6 +60,7 @@ struct softpipe_vbuf_render
struct softpipe_context *softpipe;
uint prim;
uint vertex_size;
+ uint vertex_buffer_size;
void *vertex_buffer;
};
@@ -80,26 +81,44 @@ sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
}
-static void *
+static boolean
sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
- ushort vertex_size, ushort nr_vertices)
+ ushort vertex_size, ushort nr_vertices)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- assert(!cvbr->vertex_buffer);
- cvbr->vertex_buffer = align_malloc(vertex_size * nr_vertices, 16);
+ unsigned size = vertex_size * nr_vertices;
+
+ if (cvbr->vertex_buffer_size < size) {
+ align_free(cvbr->vertex_buffer);
+ cvbr->vertex_buffer = align_malloc(size, 16);
+ cvbr->vertex_buffer_size = size;
+ }
+
cvbr->vertex_size = vertex_size;
- return cvbr->vertex_buffer;
+ return cvbr->vertex_buffer != NULL;
}
-
static void
-sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
- unsigned vertex_size, unsigned vertices_used)
+sp_vbuf_release_vertices(struct vbuf_render *vbr)
+{
+ /* keep the old allocation for next time */
+}
+
+static void *
+sp_vbuf_map_vertices(struct vbuf_render *vbr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- align_free(vertices);
- assert(vertices == cvbr->vertex_buffer);
- cvbr->vertex_buffer = NULL;
+ return cvbr->vertex_buffer;
+}
+
+static void
+sp_vbuf_unmap_vertices(struct vbuf_render *vbr,
+ ushort min_index,
+ ushort max_index )
+{
+ struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
+ /* do nothing */
}
@@ -115,8 +134,6 @@ sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
setup_prepare( setup_ctx );
-
-
cvbr->prim = prim;
return TRUE;
@@ -394,6 +411,8 @@ sp_init_vbuf(struct softpipe_context *sp)
sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;
sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
+ sp->vbuf_render->base.map_vertices = sp_vbuf_map_vertices;
+ sp->vbuf_render->base.unmap_vertices = sp_vbuf_unmap_vertices;
sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
sp->vbuf_render->base.draw = sp_vbuf_draw;
sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays;