summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-03-29 17:51:50 +0200
committerMarek Olšák <[email protected]>2012-10-31 00:55:13 +0100
commite73bf3b805de78299f1a652668ba4e6eab9bac94 (patch)
tree11839d343c6aad3a8fb5c594cadf961288adbea0 /src/gallium/drivers
parenta7c5be098aee3a8228cbd95558bac29cb7ff6a3d (diff)
gallium: add start_slot parameter to set_vertex_buffers
This allows updating only a subrange of buffer bindings. set_vertex_buffers(pipe, start_slot, count, NULL) unbinds buffers in that range. Binding NULL resources unbinds buffers too (both buffer and user_buffer must be NULL). The meta ops are adapted to only save, change, and restore the single slot they use. The cso_context can save and restore only one vertex buffer slot. The clients can query which one it is using cso_get_aux_vertex_buffer_slot. It's currently set to 0. (the Draw module breaks if it's set to non-zero) It should decrease the CPU overhead when using a lot of meta ops, but the drivers must be able to treat each vertex buffer slot as a separate state (only r600g does so at the moment). I can imagine this also being useful for optimizing some OpenGL use cases. Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/galahad/glhd_context.c4
-rw-r--r--src/gallium/drivers/i915/i915_state.c12
-rw-r--r--src/gallium/drivers/i915/i915_surface.c2
-rw-r--r--src/gallium/drivers/identity/id_context.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c3
-rw-r--r--src/gallium/drivers/noop/noop_state.c5
-rw-r--r--src/gallium/drivers/nv30/nv30_draw.c8
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c4
-rw-r--r--src/gallium/drivers/nv30/nv30_push.c11
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c13
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c30
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c68
-rw-r--r--src/gallium/drivers/r300/r300_blit.c3
-rw-r--r--src/gallium/drivers/r300/r300_render.c2
-rw-r--r--src/gallium/drivers/r300/r300_state.c23
-rw-r--r--src/gallium/drivers/r600/r600_blit.c4
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c53
-rw-r--r--src/gallium/drivers/radeonsi/r600_blit.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c5
-rw-r--r--src/gallium/drivers/rbug/rbug_context.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_surface.c3
-rw-r--r--src/gallium/drivers/svga/svga_context.h2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_blit.c4
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c27
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c2
-rw-r--r--src/gallium/drivers/trace/tr_context.c7
30 files changed, 158 insertions, 183 deletions
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index 3400a4d213a..ecdfe068f79 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -621,7 +621,7 @@ galahad_context_set_fragment_sampler_views(struct pipe_context *_pipe,
static void
galahad_context_set_vertex_buffers(struct pipe_context *_pipe,
- unsigned num_buffers,
+ unsigned start_slot, unsigned num_buffers,
const struct pipe_vertex_buffer *_buffers)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
@@ -638,7 +638,7 @@ galahad_context_set_vertex_buffers(struct pipe_context *_pipe,
}
pipe->set_vertex_buffers(pipe,
- num_buffers,
+ start_slot, num_buffers,
buffers);
}
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index d96ac7ab938..7fa648fc4d9 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -30,6 +30,7 @@
#include "draw/draw_context.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -926,19 +927,18 @@ static void i915_delete_rasterizer_state(struct pipe_context *pipe,
}
static void i915_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
- util_copy_vertex_buffers(i915->vertex_buffers,
- &i915->nr_vertex_buffers,
- buffers, count);
+ util_set_vertex_buffers_count(i915->vertex_buffers,
+ &i915->nr_vertex_buffers,
+ buffers, start_slot, count);
/* pass-through to draw module */
- draw_set_vertex_buffers(draw, count, buffers);
-
+ draw_set_vertex_buffers(draw, start_slot, count, buffers);
}
static void *
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index 331d6e230d0..08a6f343922 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -55,7 +55,7 @@ i915_util_blitter_save_states(struct i915_context *i915)
util_blitter_save_viewport(i915->blitter, &i915->viewport);
util_blitter_save_scissor(i915->blitter, &i915->scissor);
util_blitter_save_vertex_elements(i915->blitter, i915->velems);
- util_blitter_save_vertex_buffers(i915->blitter, i915->nr_vertex_buffers,
+ util_blitter_save_vertex_buffer_slot(i915->blitter,
i915->vertex_buffers);
util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index fb2f78764a4..0325b151f83 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -565,7 +565,7 @@ identity_set_vertex_sampler_views(struct pipe_context *_pipe,
static void
identity_set_vertex_buffers(struct pipe_context *_pipe,
- unsigned num_buffers,
+ unsigned start_slot, unsigned num_buffers,
const struct pipe_vertex_buffer *_buffers)
{
struct identity_context *id_pipe = identity_context(_pipe);
@@ -582,7 +582,7 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
}
pipe->set_vertex_buffers(pipe,
- num_buffers,
+ start_slot, num_buffers,
buffers);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index f37b3ca1cea..3497edf9d1c 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -68,8 +68,12 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
*/
for (i = 0; i < lp->num_vertex_buffers; i++) {
const void *buf = lp->vertex_buffer[i].user_buffer;
- if (!buf)
+ if (!buf) {
+ if (!lp->vertex_buffer[i].buffer) {
+ continue;
+ }
buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
+ }
draw_set_mapped_vertex_buffer(draw, i, buf);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index 4a74cd7c9d4..7594d028b71 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -33,6 +33,7 @@
#include "lp_state.h"
#include "draw/draw_context.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
@@ -75,20 +76,20 @@ llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
static void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
assert(count <= PIPE_MAX_ATTRIBS);
- util_copy_vertex_buffers(llvmpipe->vertex_buffer,
- &llvmpipe->num_vertex_buffers,
- buffers, count);
+ util_set_vertex_buffers_count(llvmpipe->vertex_buffer,
+ &llvmpipe->num_vertex_buffers,
+ buffers, start_slot, count);
llvmpipe->dirty |= LP_NEW_VERTEX;
- draw_set_vertex_buffers(llvmpipe->draw, count, buffers);
+ draw_set_vertex_buffers(llvmpipe->draw, start_slot, count, buffers);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index a4789b4f5c3..e42f4c838e9 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -204,8 +204,7 @@ static void lp_blit(struct pipe_context *pipe,
/* XXX turn off occlusion and streamout queries */
- util_blitter_save_vertex_buffers(lp->blitter, lp->num_vertex_buffers,
- lp->vertex_buffer);
+ util_blitter_save_vertex_buffer_slot(lp->blitter, lp->vertex_buffer);
util_blitter_save_vertex_elements(lp->blitter, (void*)lp->velems);
util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs);
util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs);
diff --git a/src/gallium/drivers/noop/noop_state.c b/src/gallium/drivers/noop/noop_state.c
index dbfe35b668c..16ce9b457d9 100644
--- a/src/gallium/drivers/noop/noop_state.c
+++ b/src/gallium/drivers/noop/noop_state.c
@@ -215,8 +215,9 @@ static void noop_set_index_buffer(struct pipe_context *ctx,
{
}
-static void noop_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
- const struct pipe_vertex_buffer *buffers)
+static void noop_set_vertex_buffers(struct pipe_context *ctx,
+ unsigned start_slot, unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
}
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
index 46e85362815..51fe4f86ed1 100644
--- a/src/gallium/drivers/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nv30/nv30_draw.c
@@ -379,7 +379,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (nv30->draw_dirty & NV30_NEW_CLIP)
draw_set_clip_state(draw, &nv30->clip);
if (nv30->draw_dirty & NV30_NEW_ARRAYS) {
- draw_set_vertex_buffers(draw, nv30->num_vtxbufs, nv30->vtxbuf);
+ draw_set_vertex_buffers(draw, 0, nv30->num_vtxbufs, nv30->vtxbuf);
draw_set_vertex_elements(draw, nv30->vertex->num_elements, nv30->vertex->pipe);
}
if (nv30->draw_dirty & NV30_NEW_FRAGPROG) {
@@ -404,10 +404,14 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
for (i = 0; i < nv30->num_vtxbufs; i++) {
const void *map = nv30->vtxbuf[i].user_buffer;
- if (!map)
+ if (!map) {
+ if (!nv30->vtxbuf[i].buffer) {
+ continue;
+ }
map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_READ, &transfer[i]);
+ }
draw_set_mapped_vertex_buffer(draw, i, map);
}
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index e89725feb2f..5d941ab771e 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -193,9 +193,7 @@ nv30_blit(struct pipe_context *pipe,
/* XXX turn off occlusion queries */
- util_blitter_save_vertex_buffers(nv30->blitter,
- nv30->num_vtxbufs,
- nv30->vtxbuf);
+ util_blitter_save_vertex_buffer_slot(nv30->blitter, nv30->vtxbuf);
util_blitter_save_vertex_elements(nv30->blitter, nv30->vertex);
util_blitter_save_vertex_shader(nv30->blitter, nv30->vertprog.program);
util_blitter_save_rasterizer(nv30->blitter, nv30->rast);
diff --git a/src/gallium/drivers/nv30/nv30_push.c b/src/gallium/drivers/nv30/nv30_push.c
index c5867bfa11a..5ec2d462a68 100644
--- a/src/gallium/drivers/nv30/nv30_push.c
+++ b/src/gallium/drivers/nv30/nv30_push.c
@@ -211,6 +211,10 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
struct pipe_vertex_buffer *vb = &nv30->vtxbuf[i];
struct nv04_resource *res = nv04_resource(vb->buffer);
+ if (!vb->buffer && !vb->user_buffer) {
+ continue;
+ }
+
data = nouveau_resource_map_offset(&nv30->base, res,
vb->buffer_offset, NOUVEAU_BO_RD);
@@ -276,8 +280,11 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info)
if (info->indexed)
nouveau_resource_unmap(nv04_resource(nv30->idxbuf.buffer));
- for (i = 0; i < nv30->num_vtxbufs; ++i)
- nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer));
+ for (i = 0; i < nv30->num_vtxbufs; ++i) {
+ if (nv30->vtxbuf[i].buffer) {
+ nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer));
+ }
+ }
nv30_state_release(nv30);
}
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index 046ba723dae..af8bb449fce 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -23,6 +23,7 @@
*
*/
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "nouveau/nouveau_gldefs.h"
@@ -393,21 +394,15 @@ nv30_set_viewport_state(struct pipe_context *pipe,
static void
nv30_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *vb)
{
struct nv30_context *nv30 = nv30_context(pipe);
- unsigned i;
nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXBUF);
- for (i = 0; i < count; ++i)
- pipe_resource_reference(&nv30->vtxbuf[i].buffer, vb[i].buffer);
- for (; i < nv30->num_vtxbufs; ++i)
- pipe_resource_reference(&nv30->vtxbuf[i].buffer, NULL);
-
- memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count);
- nv30->num_vtxbufs = count;
+ util_set_vertex_buffers_count(nv30->vtxbuf, &nv30->num_vtxbufs,
+ vb, start_slot, count);
nv30->dirty |= NV30_NEW_ARRAYS;
}
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 2052f914258..819b0a2e2bf 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -21,6 +21,7 @@
*/
#include "pipe/p_defines.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
@@ -883,30 +884,35 @@ nv50_set_viewport_state(struct pipe_context *pipe,
static void
nv50_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *vb)
{
struct nv50_context *nv50 = nv50_context(pipe);
unsigned i;
- nv50->vbo_user = nv50->vbo_constant = 0;
+ util_set_vertex_buffers_count(nv50->vtxbuf, &nv50->num_vtxbufs, vb,
+ start_slot, count);
+
+ if (!vb) {
+ nv50->vbo_user &= ~(((1ull << count) - 1) << start_slot);
+ nv50->vbo_constant &= ~(((1ull << count) - 1) << start_slot);
+ return;
+ }
for (i = 0; i < count; ++i) {
- nv50->vtxbuf[i].stride = vb[i].stride;
- pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer);
+ unsigned dst_index = start_slot + i;
+
if (!vb[i].buffer && vb[i].user_buffer) {
- nv50->vtxbuf[i].user_buffer = vb[i].user_buffer;
- nv50->vbo_user |= 1 << i;
+ nv50->vbo_user |= 1 << dst_index;
if (!vb[i].stride)
- nv50->vbo_constant |= 1 << i;
+ nv50->vbo_constant |= 1 << dst_index;
+ else
+ nv50->vbo_constant &= ~(1 << dst_index);
} else {
- nv50->vtxbuf[i].buffer_offset = vb[i].buffer_offset;
+ nv50->vbo_user &= ~(1 << dst_index);
+ nv50->vbo_constant &= ~(1 << dst_index);
}
}
- for (; i < nv50->num_vtxbufs; ++i)
- pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
-
- nv50->num_vtxbufs = count;
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 1bd54342e81..30011df4dc1 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -21,6 +21,7 @@
*/
#include "pipe/p_defines.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
@@ -778,59 +779,38 @@ nvc0_set_viewport_state(struct pipe_context *pipe,
static void
nvc0_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *vb)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- uint32_t constant_vbos = 0;
unsigned i;
- nvc0->vbo_user = 0;
-
- if (count != nvc0->num_vtxbufs) {
- for (i = 0; i < count; ++i) {
- pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer);
- if (vb[i].user_buffer) {
- nvc0->vbo_user |= 1 << i;
- nvc0->vtxbuf[i].user_buffer = vb[i].user_buffer;
- if (!vb[i].stride)
- constant_vbos |= 1 << i;
- } else {
- nvc0->vtxbuf[i].buffer_offset = vb[i].buffer_offset;
- }
- nvc0->vtxbuf[i].stride = vb[i].stride;
- }
- for (; i < nvc0->num_vtxbufs; ++i)
- pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
+ util_set_vertex_buffers_count(nvc0->vtxbuf, &nvc0->num_vtxbufs, vb,
+ start_slot, count);
- nvc0->num_vtxbufs = count;
- nvc0->dirty |= NVC0_NEW_ARRAYS;
- } else {
- for (i = 0; i < count; ++i) {
- if (vb[i].user_buffer) {
- nvc0->vtxbuf[i].user_buffer = vb[i].user_buffer;
- nvc0->vbo_user |= 1 << i;
- if (!vb[i].stride)
- constant_vbos |= 1 << i;
- assert(!vb[i].buffer);
- }
- if (nvc0->vtxbuf[i].buffer == vb[i].buffer &&
- nvc0->vtxbuf[i].buffer_offset == vb[i].buffer_offset &&
- nvc0->vtxbuf[i].stride == vb[i].stride)
- continue;
- pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer);
- nvc0->vtxbuf[i].buffer_offset = vb[i].buffer_offset;
- nvc0->vtxbuf[i].stride = vb[i].stride;
- nvc0->dirty |= NVC0_NEW_ARRAYS;
- }
+ if (!vb) {
+ nvc0->vbo_user &= ~(((1ull << count) - 1) << start_slot);
+ nvc0->constant_vbos &= ~(((1ull << count) - 1) << start_slot);
+ return;
}
- if (constant_vbos != nvc0->constant_vbos) {
- nvc0->constant_vbos = constant_vbos;
- nvc0->dirty |= NVC0_NEW_ARRAYS;
+
+ for (i = 0; i < count; ++i) {
+ unsigned dst_index = start_slot + i;
+
+ if (vb[i].user_buffer) {
+ nvc0->vbo_user |= 1 << dst_index;
+ if (!vb[i].stride)
+ nvc0->constant_vbos |= 1 << dst_index;
+ else
+ nvc0->constant_vbos &= ~(1 << dst_index);
+ } else {
+ nvc0->vbo_user &= ~(1 << dst_index);
+ nvc0->constant_vbos &= ~(1 << dst_index);
+ }
}
- if (nvc0->dirty & NVC0_NEW_ARRAYS)
- nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
+ nvc0->dirty |= NVC0_NEW_ARRAYS;
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
}
static void
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 96c96c367a2..651ea8529e8 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -66,8 +66,7 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_scissor(r300->blitter, r300->scissor_state.state);
- util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers,
- r300->vertex_buffer);
+ util_blitter_save_vertex_buffer_slot(r300->blitter, r300->vertex_buffer);
util_blitter_save_vertex_elements(r300->blitter, r300->velems);
if (op & R300_SAVE_FRAMEBUFFER) {
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 198ab73d257..46d7ea1748b 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -1191,8 +1191,6 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
if (r300->skip_rendering)
return;
- r300->context.set_vertex_buffers(&r300->context, 0, NULL);
-
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
r300->sprite_coord_enable = 1;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index b43f330af98..85d05bd2ce3 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -25,6 +25,7 @@
#include "util/u_framebuffer.h"
#include "util/u_half.h"
+#include "util/u_helpers.h"
#include "util/u_math.h"
#include "util/u_mm.h"
#include "util/u_memory.h"
@@ -1626,7 +1627,7 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
}
static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
@@ -1637,31 +1638,31 @@ static void r300_set_vertex_buffers_hwtcl(struct pipe_context* pipe,
count = 1;
}
- util_copy_vertex_buffers(r300->vertex_buffer,
- &r300->nr_vertex_buffers,
- buffers, count);
+ util_set_vertex_buffers_count(r300->vertex_buffer,
+ &r300->nr_vertex_buffers,
+ buffers, start_slot, count);
r300->vertex_arrays_dirty = TRUE;
}
static void r300_set_vertex_buffers_swtcl(struct pipe_context* pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
unsigned i;
- util_copy_vertex_buffers(r300->vertex_buffer,
- &r300->nr_vertex_buffers,
- buffers, count);
- draw_set_vertex_buffers(r300->draw, count, buffers);
+ util_set_vertex_buffers_count(r300->vertex_buffer,
+ &r300->nr_vertex_buffers,
+ buffers, start_slot, count);
+ draw_set_vertex_buffers(r300->draw, start_slot, count, buffers);
for (i = 0; i < count; i++) {
if (buffers[i].user_buffer) {
- draw_set_mapped_vertex_buffer(r300->draw, i,
+ draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,
buffers[i].user_buffer);
} else if (buffers[i].buffer) {
- draw_set_mapped_vertex_buffer(r300->draw, i,
+ draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,
r300_resource(buffers[i].buffer)->malloced_buffer);
}
}
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index a19248da3a2..085108d3709 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -55,9 +55,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
r600_suspend_nontimer_queries(rctx);
- util_blitter_save_vertex_buffers(rctx->blitter,
- util_last_bit(rctx->vertex_buffer_state.enabled_mask),
- rctx->vertex_buffer_state.vb);
+ util_blitter_save_vertex_buffer_slot(rctx->blitter, rctx->vertex_buffer_state.vb);
util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso);
util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader);
util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index a4d3e461ef1..3503c3964a6 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -495,41 +495,42 @@ void r600_vertex_buffers_dirty(struct r600_context *rctx)
}
}
-static void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
- const struct pipe_vertex_buffer *input)
+static void r600_set_vertex_buffers(struct pipe_context *ctx,
+ unsigned start_slot, unsigned count,
+ const struct pipe_vertex_buffer *input)
{
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_vertexbuf_state *state = &rctx->vertex_buffer_state;
- struct pipe_vertex_buffer *vb = state->vb;
+ struct pipe_vertex_buffer *vb = state->vb + start_slot;
unsigned i;
- /* This sets 1-bit for buffers with index >= count. */
- uint32_t disable_mask = ~((1ull << count) - 1);
+ uint32_t disable_mask = 0;
/* These are the new buffers set by this function. */
uint32_t new_buffer_mask = 0;
- /* Set buffers with index >= count to NULL. */
- uint32_t remaining_buffers_mask =
- rctx->vertex_buffer_state.enabled_mask & disable_mask;
-
- while (remaining_buffers_mask) {
- i = u_bit_scan(&remaining_buffers_mask);
- pipe_resource_reference(&vb[i].buffer, NULL);
- }
-
/* Set vertex buffers. */
- for (i = 0; i < count; i++) {
- if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) {
- if (input[i].buffer) {
- vb[i].stride = input[i].stride;
- vb[i].buffer_offset = input[i].buffer_offset;
- pipe_resource_reference(&vb[i].buffer, input[i].buffer);
- new_buffer_mask |= 1 << i;
- } else {
- pipe_resource_reference(&vb[i].buffer, NULL);
- disable_mask |= 1 << i;
+ if (input) {
+ for (i = 0; i < count; i++) {
+ if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) {
+ if (input[i].buffer) {
+ vb[i].stride = input[i].stride;
+ vb[i].buffer_offset = input[i].buffer_offset;
+ pipe_resource_reference(&vb[i].buffer, input[i].buffer);
+ new_buffer_mask |= 1 << i;
+ } else {
+ pipe_resource_reference(&vb[i].buffer, NULL);
+ disable_mask |= 1 << i;
+ }
}
}
- }
+ } else {
+ for (i = 0; i < count; i++) {
+ pipe_resource_reference(&vb[i].buffer, NULL);
+ }
+ disable_mask = ((1ull << count) - 1);
+ }
+
+ disable_mask <<= start_slot;
+ new_buffer_mask <<= start_slot;
rctx->vertex_buffer_state.enabled_mask &= ~disable_mask;
rctx->vertex_buffer_state.dirty_mask &= rctx->vertex_buffer_state.enabled_mask;
@@ -1371,7 +1372,7 @@ void r600_draw_rectangle(struct blitter_context *blitter,
}
/* draw */
- util_draw_vertex_buffer(&rctx->context, NULL, buf, offset,
+ util_draw_vertex_buffer(&rctx->context, NULL, buf, rctx->blitter->vb_slot, offset,
R600_PRIM_RECTANGLE_LIST, 3, 2);
pipe_resource_reference(&buf, NULL);
}
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c
index cea7e128018..30736fcf8a7 100644
--- a/src/gallium/drivers/radeonsi/r600_blit.c
+++ b/src/gallium/drivers/radeonsi/r600_blit.c
@@ -61,9 +61,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
if (rctx->queued.named.viewport) {
util_blitter_save_viewport(rctx->blitter, &rctx->queued.named.viewport->viewport);
}
- util_blitter_save_vertex_buffers(rctx->blitter,
- rctx->nr_vertex_buffers,
- rctx->vertex_buffer);
+ util_blitter_save_vertex_buffer_slot(rctx->blitter, rctx->vertex_buffer);
util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets,
(struct pipe_stream_output_target**)rctx->so_targets);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 66f0bd886fe..bd44d732935 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -27,6 +27,7 @@
#include "util/u_memory.h"
#include "util/u_framebuffer.h"
#include "util/u_blitter.h"
+#include "util/u_helpers.h"
#include "util/u_math.h"
#include "util/u_pack_color.h"
#include "tgsi/tgsi_parse.h"
@@ -2488,12 +2489,12 @@ static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
FREE(state);
}
-static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
+static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- util_copy_vertex_buffers(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, count);
+ util_set_vertex_buffers_count(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, start_slot, count);
}
static void si_set_index_buffer(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
index 0b59a0121c2..28f300877cf 100644
--- a/src/gallium/drivers/rbug/rbug_context.c
+++ b/src/gallium/drivers/rbug/rbug_context.c
@@ -783,7 +783,7 @@ rbug_set_fragment_sampler_views(struct pipe_context *_pipe,
static void
rbug_set_vertex_buffers(struct pipe_context *_pipe,
- unsigned num_buffers,
+ unsigned start_slot, unsigned num_buffers,
const struct pipe_vertex_buffer *_buffers)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
@@ -801,7 +801,7 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe,
buffers = unwrapped_buffers;
}
- pipe->set_vertex_buffers(pipe,
+ pipe->set_vertex_buffers(pipe, start_slot,
num_buffers,
buffers);
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 59226fb9c15..ba9e7817ceb 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -76,8 +76,12 @@ softpipe_draw_vbo(struct pipe_context *pipe,
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
const void *buf = sp->vertex_buffer[i].user_buffer;
- if (!buf)
+ if (!buf) {
+ if (!sp->vertex_buffer[i].buffer) {
+ continue;
+ }
buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
+ }
draw_set_mapped_vertex_buffer(draw, i, buf);
}
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index 95acecd3be4..2aee700fec2 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -33,6 +33,7 @@
#include "sp_state.h"
#include "util/u_memory.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
#include "draw/draw_context.h"
@@ -79,20 +80,20 @@ softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
static void
softpipe_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
assert(count <= PIPE_MAX_ATTRIBS);
- util_copy_vertex_buffers(softpipe->vertex_buffer,
- &softpipe->num_vertex_buffers,
- buffers, count);
+ util_set_vertex_buffers_count(softpipe->vertex_buffer,
+ &softpipe->num_vertex_buffers,
+ buffers, start_slot, count);
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_buffers(softpipe->draw, count, buffers);
+ draw_set_vertex_buffers(softpipe->draw, start_slot, count, buffers);
}
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index bb143f4cb3a..911c34df1b8 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -56,8 +56,7 @@ static void sp_blit(struct pipe_context *pipe,
/* XXX turn off occlusion and streamout queries */
- util_blitter_save_vertex_buffers(sp->blitter, sp->num_vertex_buffers,
- sp->vertex_buffer);
+ util_blitter_save_vertex_buffer_slot(sp->blitter, sp->vertex_buffer);
util_blitter_save_vertex_elements(sp->blitter, sp->velems);
util_blitter_save_vertex_shader(sp->blitter, sp->vs);
util_blitter_save_geometry_shader(sp->blitter, sp->gs);
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index f2f26da1cd5..32671ecafa7 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -234,8 +234,6 @@ struct svga_state
unsigned flag_1d;
unsigned flag_srgb;
} tex_flags;
-
- boolean any_user_vertex_buffers;
};
struct svga_prescale {
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
index 34ac995ef60..a44ed12adf7 100644
--- a/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -183,9 +183,7 @@ static void svga_blit(struct pipe_context *pipe,
/* XXX turn off occlusion and streamout queries */
- util_blitter_save_vertex_buffers(svga->blitter,
- svga->curr.num_vertex_buffers,
- svga->curr.vb);
+ util_blitter_save_vertex_buffer_slot(svga->blitter, svga->curr.vb);
util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems);
util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs);
/*util_blitter_save_geometry_shader(svga->blitter, svga->curr.gs);*/
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 58469910732..82bd1b33efe 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -23,6 +23,7 @@
*
**********************************************************/
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
@@ -36,32 +37,14 @@
static void svga_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct svga_context *svga = svga_context(pipe);
- unsigned i;
- boolean any_user_buffer = FALSE;
-
- /* Check for no change */
- if (count == svga->curr.num_vertex_buffers &&
- memcmp(svga->curr.vb, buffers, count * sizeof buffers[0]) == 0)
- return;
-
- /* Adjust refcounts */
- for (i = 0; i < count; i++) {
- pipe_resource_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
- if (svga_buffer_is_user_buffer(buffers[i].buffer))
- any_user_buffer = TRUE;
- }
-
- for ( ; i < svga->curr.num_vertex_buffers; i++)
- pipe_resource_reference(&svga->curr.vb[i].buffer, NULL);
- /* Copy remaining data */
- memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]);
- svga->curr.num_vertex_buffers = count;
- svga->curr.any_user_vertex_buffers = any_user_buffer;
+ util_set_vertex_buffers_count(svga->curr.vb,
+ &svga->curr.num_vertex_buffers,
+ buffers, start_slot, count);
svga->dirty |= SVGA_NEW_VBUFFER;
}
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index e9239bafef9..dea3a26b6f2 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -98,7 +98,7 @@ update_swtnl_draw( struct svga_context *svga,
svga->curr.fs->draw_shader);
if (dirty & SVGA_NEW_VBUFFER)
- draw_set_vertex_buffers(svga->swtnl.draw,
+ draw_set_vertex_buffers(svga->swtnl.draw, 0,
svga->curr.num_vertex_buffers,
svga->curr.vb);
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index a5110bec487..ba1882ea652 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1060,7 +1060,7 @@ trace_context_set_vertex_sampler_views(struct pipe_context *_pipe,
static INLINE void
trace_context_set_vertex_buffers(struct pipe_context *_pipe,
- unsigned num_buffers,
+ unsigned start_slot, unsigned num_buffers,
const struct pipe_vertex_buffer *buffers)
{
struct trace_context *tr_ctx = trace_context(_pipe);
@@ -1070,6 +1070,7 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
trace_dump_call_begin("pipe_context", "set_vertex_buffers");
trace_dump_arg(ptr, pipe);
+ trace_dump_arg(uint, start_slot);
trace_dump_arg(uint, num_buffers);
trace_dump_arg_begin("buffers");
@@ -1081,10 +1082,10 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
memcpy(_buffers, buffers, num_buffers * sizeof(*_buffers));
for (i = 0; i < num_buffers; i++)
_buffers[i].buffer = trace_resource_unwrap(tr_ctx, buffers[i].buffer);
- pipe->set_vertex_buffers(pipe, num_buffers, _buffers);
+ pipe->set_vertex_buffers(pipe, start_slot, num_buffers, _buffers);
FREE(_buffers);
} else {
- pipe->set_vertex_buffers(pipe, num_buffers, NULL);
+ pipe->set_vertex_buffers(pipe, start_slot, num_buffers, NULL);
}
trace_dump_call_end();