summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-07-16 04:35:58 +0800
committerChia-I Wu <olv@lunarg.com>2010-07-29 13:45:30 +0800
commit6d28bf917fb1d741d90fd3f05c22769376021fca (patch)
tree9b8724b30658d61426297113136c2d23c0c62f14 /src/gallium/drivers/nv50
parentc5e9d3114a80d6d35a2f4e65783cdc75fcc2deac (diff)
gallium: Implement draw_vbo and set_index_buffer for all drivers.
Some drivers define a generic function that is called by all drawing functions. To implement draw_vbo for such drivers, either draw_vbo calls the generic function or the prototype of the generic function is changed to match draw_vbo. Other drivers have no such generic function. draw_vbo is implemented by calling either draw_arrays and draw_elements. For most drivers, set_index_buffer does not mark the state dirty for tracking. Instead, the index buffer state is emitted whenever draw_vbo is called, just like the case with draw_elements. It surely can be improved.
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h3
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c15
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c31
4 files changed, 50 insertions, 0 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 915a925402..3fc39c1137 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -86,6 +86,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced;
nv50->pipe.draw_elements = nv50_draw_elements;
nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced;
+ nv50->pipe.draw_vbo = nv50_draw_vbo;
nv50->pipe.clear = nv50_clear;
nv50->pipe.flush = nv50_flush;
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 12c4a93a9b..a7c2b5d487 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -148,6 +148,7 @@ struct nv50_context {
struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
+ struct pipe_index_buffer idxbuf;
struct nv50_vtxelt_stateobj *vtxelt;
struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
unsigned sampler_nr[3];
@@ -197,6 +198,8 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned count,
unsigned startInstance,
unsigned instanceCount);
+extern void nv50_draw_vbo(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 42c5a58318..ec0c0ff283 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -742,6 +742,20 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv50->dirty |= NV50_NEW_ARRAYS;
}
+static void
+nv50_set_index_buffer(struct pipe_context *pipe,
+ const struct pipe_index_buffer *ib)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+
+ if (ib)
+ memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+ else
+ memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf));
+
+ /* TODO make this more like a state */
+}
+
static void *
nv50_vtxelts_state_create(struct pipe_context *pipe,
unsigned num_elements,
@@ -827,5 +841,6 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
+ nv50->pipe.set_index_buffer = nv50_set_index_buffer;
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 864cb09352..11ffc182c2 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -473,6 +473,37 @@ nv50_draw_elements(struct pipe_context *pipe,
mode, start, count, 0, 1);
}
+void
+nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+
+ if (info->indexed && nv50->idxbuf.buffer) {
+ unsigned offset;
+
+ assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0);
+ offset = nv50->idxbuf.offset / nv50->idxbuf.index_size;
+
+ nv50_draw_elements_instanced(pipe,
+ nv50->idxbuf.buffer,
+ nv50->idxbuf.index_size,
+ info->index_bias,
+ info->mode,
+ info->start + offset,
+ info->count,
+ info->start_instance,
+ info->instance_count);
+ }
+ else {
+ nv50_draw_arrays_instanced(pipe,
+ info->mode,
+ info->start,
+ info->count,
+ info->start_instance,
+ info->instance_count);
+ }
+}
+
static INLINE boolean
nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_stateobj **pso,