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 <brianp@vmware.com>
util/u_handle_table.c \
util/u_hash.c \
util/u_hash_table.c \
+ util/u_helpers.c \
util/u_index_modify.c \
util/u_keymap.c \
util/u_linear.c \
struct sampler_info samplers[PIPE_SHADER_TYPES];
- uint nr_vertex_buffers;
- struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
-
- uint nr_vertex_buffers_saved;
- struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_buffer aux_vertex_buffer_current;
+ struct pipe_vertex_buffer aux_vertex_buffer_saved;
+ unsigned aux_vertex_buffer_index;
unsigned nr_so_targets;
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
!caps.format_norm32 ||
!caps.format_scaled32 ||
!caps.user_vertex_buffers) {
- cso->vbuf = u_vbuf_create(cso->pipe, &caps);
+ cso->vbuf = u_vbuf_create(cso->pipe, &caps,
+ cso->aux_vertex_buffer_index);
}
}
ctx->pipe = pipe;
ctx->sample_mask_saved = ~0;
+ ctx->aux_vertex_buffer_index = 0; /* 0 for now */
+
cso_init_vbuf(ctx);
/* Enable for testing: */
util_unreference_framebuffer_state(&ctx->fb);
util_unreference_framebuffer_state(&ctx->fb_saved);
- util_copy_vertex_buffers(ctx->vertex_buffers,
- &ctx->nr_vertex_buffers,
- NULL, 0);
- util_copy_vertex_buffers(ctx->vertex_buffers_saved,
- &ctx->nr_vertex_buffers_saved,
- NULL, 0);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer, NULL);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL);
for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
pipe_so_target_reference(&ctx->so_targets[i], NULL);
/* vertex buffers */
void cso_set_vertex_buffers(struct cso_context *ctx,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_set_vertex_buffers(vbuf, count, buffers);
+ u_vbuf_set_vertex_buffers(vbuf, start_slot, count, buffers);
return;
}
- if (count != ctx->nr_vertex_buffers ||
- memcmp(buffers, ctx->vertex_buffers,
- sizeof(struct pipe_vertex_buffer) * count) != 0) {
- util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers,
- buffers, count);
- ctx->pipe->set_vertex_buffers(ctx->pipe, count, buffers);
+ /* Save what's in the auxiliary slot, so that we can save and restore it
+ * for meta ops. */
+ if (start_slot <= ctx->aux_vertex_buffer_index &&
+ start_slot+count > ctx->aux_vertex_buffer_index) {
+ if (buffers) {
+ const struct pipe_vertex_buffer *vb =
+ buffers + (ctx->aux_vertex_buffer_index - start_slot);
+
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer,
+ vb->buffer);
+ memcpy(&ctx->aux_vertex_buffer_current, vb,
+ sizeof(struct pipe_vertex_buffer));
+ }
+ else {
+ pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer,
+ NULL);
+ ctx->aux_vertex_buffer_current.user_buffer = NULL;
+ }
}
+
+ ctx->pipe->set_vertex_buffers(ctx->pipe, start_slot, count, buffers);
}
-void cso_save_vertex_buffers(struct cso_context *ctx)
+void cso_save_aux_vertex_buffer_slot(struct cso_context *ctx)
{
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_save_vertex_buffers(vbuf);
+ u_vbuf_save_aux_vertex_buffer_slot(vbuf);
return;
}
- util_copy_vertex_buffers(ctx->vertex_buffers_saved,
- &ctx->nr_vertex_buffers_saved,
- ctx->vertex_buffers,
- ctx->nr_vertex_buffers);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer,
+ ctx->aux_vertex_buffer_current.buffer);
+ memcpy(&ctx->aux_vertex_buffer_saved, &ctx->aux_vertex_buffer_current,
+ sizeof(struct pipe_vertex_buffer));
}
-void cso_restore_vertex_buffers(struct cso_context *ctx)
+void cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx)
{
- unsigned i;
struct u_vbuf *vbuf = ctx->vbuf;
if (vbuf) {
- u_vbuf_restore_vertex_buffers(vbuf);
+ u_vbuf_restore_aux_vertex_buffer_slot(vbuf);
return;
}
- util_copy_vertex_buffers(ctx->vertex_buffers,
- &ctx->nr_vertex_buffers,
- ctx->vertex_buffers_saved,
- ctx->nr_vertex_buffers_saved);
-
- for (i = 0; i < ctx->nr_vertex_buffers_saved; i++) {
- pipe_resource_reference(&ctx->vertex_buffers_saved[i].buffer, NULL);
- }
- ctx->nr_vertex_buffers_saved = 0;
+ cso_set_vertex_buffers(ctx, ctx->aux_vertex_buffer_index, 1,
+ &ctx->aux_vertex_buffer_saved);
+ pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL);
+}
- ctx->pipe->set_vertex_buffers(ctx->pipe, ctx->nr_vertex_buffers,
- ctx->vertex_buffers);
+unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx)
+{
+ return ctx->aux_vertex_buffer_index;
}
void cso_set_vertex_buffers(struct cso_context *ctx,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers);
-void cso_save_vertex_buffers(struct cso_context *ctx);
-void cso_restore_vertex_buffers(struct cso_context *ctx);
+
+/* One vertex buffer slot is provided with the save/restore functionality.
+ * cso_context chooses the slot, it can be non-zero. */
+void cso_save_aux_vertex_buffer_slot(struct cso_context *ctx);
+void cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx);
+unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx);
void cso_set_stream_outputs(struct cso_context *ctx,
#include "util/u_math.h"
#include "util/u_cpu_detect.h"
#include "util/u_inlines.h"
+#include "util/u_helpers.h"
#include "draw_context.h"
#include "draw_vs.h"
#include "draw_gs.h"
void
draw_set_vertex_buffers(struct draw_context *draw,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers)
{
- assert(count <= PIPE_MAX_ATTRIBS);
+ assert(start_slot + count <= PIPE_MAX_ATTRIBS);
- util_copy_vertex_buffers(draw->pt.vertex_buffer,
- &draw->pt.nr_vertex_buffers,
- buffers, count);
+ util_set_vertex_buffers_count(draw->pt.vertex_buffer,
+ &draw->pt.nr_vertex_buffers,
+ buffers, start_slot, count);
}
*/
void draw_set_vertex_buffers(struct draw_context *draw,
- unsigned count,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *buffers);
void draw_set_vertex_elements(struct draw_context *draw,
void
pp_filter_draw(struct program *p)
{
- util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0,
+ util_draw_vertex_buffer(p->pipe, p->cso, p->vbuf, 0, 0,
PIPE_PRIM_QUADS, 4, 2);
p->pipe->flush(p->pipe, NULL);
}
for (i = 0; i < 2; i++) {
ctx->velem[i].src_offset = i * 4 * sizeof(float);
ctx->velem[i].instance_divisor = 0;
- ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
cso_save_vertex_shader(ctx->cso);
cso_save_geometry_shader(ctx->cso);
cso_save_vertex_elements(ctx->cso);
- cso_save_vertex_buffers(ctx->cso);
+ cso_save_aux_vertex_buffer_slot(ctx->cso);
/* set misc state we care about */
if (writemask)
z);
if (ctx->vbuf) {
- util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
+ cso_get_aux_vertex_buffer_slot(ctx->cso),
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
cso_restore_vertex_shader(ctx->cso);
cso_restore_geometry_shader(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
- cso_restore_vertex_buffers(ctx->cso);
+ cso_restore_aux_vertex_buffer_slot(ctx->cso);
cso_restore_stream_outputs(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
cso_save_vertex_shader(ctx->cso);
cso_save_geometry_shader(ctx->cso);
cso_save_vertex_elements(ctx->cso);
- cso_save_vertex_buffers(ctx->cso);
+ cso_save_aux_vertex_buffer_slot(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend_write_color);
s0, t0, s1, t1,
z);
- util_draw_vertex_buffer(ctx->pipe, ctx->cso,
- ctx->vbuf, offset,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
+ cso_get_aux_vertex_buffer_slot(ctx->cso),
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
cso_restore_vertex_shader(ctx->cso);
cso_restore_geometry_shader(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
- cso_restore_vertex_buffers(ctx->cso);
+ cso_restore_aux_vertex_buffer_slot(ctx->cso);
cso_restore_stream_outputs(ctx->cso);
}
ctx->base.saved_fb_state.nr_cbufs = ~0;
ctx->base.saved_num_sampler_views = ~0;
ctx->base.saved_num_sampler_states = ~0;
- ctx->base.saved_num_vertex_buffers = ~0;
ctx->base.saved_num_so_targets = ~0;
ctx->has_geometry_shader =
ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
}
+ ctx->base.vb_slot = 0; /* 0 for now */
+
/* vertex elements states */
memset(&velem[0], 0, sizeof(velem[0]) * 2);
for (i = 0; i < 2; i++) {
velem[i].src_offset = i * 4 * sizeof(float);
velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velem[i].vertex_buffer_index = ctx->base.vb_slot;
}
ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
memset(&velem[0], 0, sizeof(velem[0]) * 2);
velem[0].src_offset = 0;
velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velem[0].vertex_buffer_index = ctx->base.vb_slot;
velem[1].src_offset = 4 * sizeof(float);
velem[1].src_format = PIPE_FORMAT_R32G32B32A32_SINT;
+ velem[1].vertex_buffer_index = ctx->base.vb_slot;
ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
memset(&velem[0], 0, sizeof(velem[0]) * 2);
velem[0].src_offset = 0;
velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velem[0].vertex_buffer_index = ctx->base.vb_slot;
velem[1].src_offset = 4 * sizeof(float);
velem[1].src_format = PIPE_FORMAT_R32G32B32A32_UINT;
+ velem[1].vertex_buffer_index = ctx->base.vb_slot;
ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
}
if (ctx->has_stream_out) {
velem[0].src_format = PIPE_FORMAT_R32_UINT;
+ velem[0].vertex_buffer_index = ctx->base.vb_slot;
ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
}
static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
{
- assert(ctx->base.saved_num_vertex_buffers != ~0);
assert(ctx->base.saved_velem_state != INVALID_PTR);
assert(ctx->base.saved_vs != INVALID_PTR);
assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
struct pipe_context *pipe = ctx->base.pipe;
unsigned i;
- /* Vertex buffers. */
- pipe->set_vertex_buffers(pipe,
- ctx->base.saved_num_vertex_buffers,
- ctx->base.saved_vertex_buffers);
-
- for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) {
- if (ctx->base.saved_vertex_buffers[i].buffer) {
- pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer,
- NULL);
- }
- }
- ctx->base.saved_num_vertex_buffers = ~0;
+ /* Vertex buffer. */
+ pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1,
+ &ctx->base.saved_vertex_buffer);
+ pipe_resource_reference(&ctx->base.saved_vertex_buffer.buffer, NULL);
/* Vertex elements. */
pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices,
&offset, &buf);
u_upload_unmap(ctx->upload);
- util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, offset,
- PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, ctx->base.vb_slot,
+ offset, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
pipe_resource_reference(&buf, NULL);
}
vb.buffer_offset = srcx;
vb.stride = 4;
- pipe->set_vertex_buffers(pipe, 1, &vb);
+ pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf);
pipe->bind_vs_state(pipe, ctx->vs_pos_only);
if (ctx->has_geometry_shader)
unsigned saved_num_sampler_views;
struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
- unsigned saved_num_vertex_buffers;
- struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS];
+ unsigned vb_slot;
+ struct pipe_vertex_buffer saved_vertex_buffer;
unsigned saved_num_so_targets;
struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];
}
static INLINE void
-util_blitter_save_vertex_buffers(struct blitter_context *blitter,
- unsigned num_vertex_buffers,
- struct pipe_vertex_buffer *vertex_buffers)
+util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter,
+ struct pipe_vertex_buffer *vertex_buffers)
{
- assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers));
-
- blitter->saved_num_vertex_buffers = 0;
- util_copy_vertex_buffers(blitter->saved_vertex_buffers,
- (unsigned*)&blitter->saved_num_vertex_buffers,
- vertex_buffers,
- num_vertex_buffers);
+ pipe_resource_reference(&blitter->saved_vertex_buffer.buffer,
+ vertex_buffers[blitter->vb_slot].buffer);
+ memcpy(&blitter->saved_vertex_buffer, &vertex_buffers[blitter->vb_slot],
+ sizeof(struct pipe_vertex_buffer));
}
static INLINE void
util_draw_vertex_buffer(struct pipe_context *pipe,
struct cso_context *cso,
struct pipe_resource *vbuf,
+ uint vbuf_slot,
uint offset,
uint prim_type,
uint num_verts,
/* note: vertex elements already set by caller */
if (cso) {
- cso_set_vertex_buffers(cso, 1, &vbuffer);
+ cso_set_vertex_buffers(cso, vbuf_slot, 1, &vbuffer);
cso_draw_arrays(cso, prim_type, 0, num_verts);
} else {
- pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+ pipe->set_vertex_buffers(pipe, vbuf_slot, 1, &vbuffer);
util_draw_arrays(pipe, prim_type, 0, num_verts);
}
}
/* note: vertex elements already set by caller */
- cso_set_vertex_buffers(cso, 1, &vbuffer);
+ cso_set_vertex_buffers(cso, 0, 1, &vbuffer);
cso_draw_arrays(cso, prim_type, 0, num_verts);
}
*/
void
util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
+ uint vbuf_slot,
float x0, float y0, float x1, float y1, float z)
{
uint numAttribs = 2, i, j;
goto out;
pipe_buffer_write(pipe, vbuf, 0, vertexBytes, v);
- util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ util_draw_vertex_buffer(pipe, cso, vbuf, vbuf_slot, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
out:
if (vbuf)
extern void
util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
- struct pipe_resource *vbuf, uint offset,
- uint num_attribs, uint num_verts, uint prim_type);
+ struct pipe_resource *vbuf, uint vbuf_slot,
+ uint offset, uint prim_type, uint num_attribs,
+ uint num_verts);
void
util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer,
extern void
util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
+ uint vbuf_slot,
float x0, float y0, float x1, float y1, float z);
for (i = 0; i < 2; i++) {
ctx->velem[i].src_offset = i * 4 * sizeof(float);
ctx->velem[i].instance_divisor = 0;
- ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
cso_save_geometry_shader(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_vertex_elements(ctx->cso);
- cso_save_vertex_buffers(ctx->cso);
+ cso_save_aux_vertex_buffer_slot(ctx->cso);
/* bind our state */
cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color :
util_draw_vertex_buffer(ctx->pipe,
ctx->cso,
ctx->vbuf,
+ cso_get_aux_vertex_buffer_slot(ctx->cso),
offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
cso_restore_viewport(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
cso_restore_stream_outputs(ctx->cso);
- cso_restore_vertex_buffers(ctx->cso);
+ cso_restore_aux_vertex_buffer_slot(ctx->cso);
}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 Marek Olšák <maraeo@gmail.com>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_helpers.h"
+#include "util/u_inlines.h"
+
+/**
+ * This function is used to copy an array of pipe_vertex_buffer structures,
+ * while properly referencing the pipe_vertex_buffer::buffer member.
+ *
+ * enabled_buffers is updated such that the bits corresponding to the indices
+ * of disabled buffers are set to 0 and the enabled ones are set to 1.
+ *
+ * \sa util_copy_framebuffer_state
+ */
+void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst,
+ uint32_t *enabled_buffers,
+ const struct pipe_vertex_buffer *src,
+ unsigned start_slot, unsigned count)
+{
+ unsigned i;
+ uint32_t bitmask = 0;
+
+ dst += start_slot;
+
+ if (src) {
+ for (i = 0; i < count; i++) {
+ if (src[i].buffer || src[i].user_buffer) {
+ bitmask |= 1 << i;
+ }
+ pipe_resource_reference(&dst[i].buffer, src[i].buffer);
+ }
+
+ /* Copy over the other members of pipe_vertex_buffer. */
+ memcpy(dst, src, count * sizeof(struct pipe_vertex_buffer));
+
+ *enabled_buffers &= ~(((1ull << count) - 1) << start_slot);
+ *enabled_buffers |= bitmask << start_slot;
+ }
+ else {
+ /* Unreference the buffers. */
+ for (i = 0; i < count; i++) {
+ pipe_resource_reference(&dst[i].buffer, NULL);
+ dst[i].user_buffer = NULL;
+ }
+
+ *enabled_buffers &= ~(((1ull << count) - 1) << start_slot);
+ }
+}
+
+/**
+ * Same as util_set_vertex_buffers_mask, but it only returns the number
+ * of bound buffers.
+ */
+void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
+ unsigned *dst_count,
+ const struct pipe_vertex_buffer *src,
+ unsigned start_slot, unsigned count)
+{
+ uint32_t enabled_buffers = (1ull << *dst_count) - 1;
+
+ util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot,
+ count);
+
+ *dst_count = util_last_bit(enabled_buffers);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 Marek Olšák <maraeo@gmail.com>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_HELPERS_H
+#define U_HELPERS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pipe/p_state.h"
+
+void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst,
+ uint32_t *enabled_buffers,
+ const struct pipe_vertex_buffer *src,
+ unsigned start_slot, unsigned count);
+
+void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
+ unsigned *dst_count,
+ const struct pipe_vertex_buffer *src,
+ unsigned start_slot, unsigned count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
}
}
-/**
- * This function is used to copy an array of pipe_vertex_buffer structures,
- * while properly referencing the pipe_vertex_buffer::buffer member.
- *
- * \sa util_copy_framebuffer_state
- */
-static INLINE void util_copy_vertex_buffers(struct pipe_vertex_buffer *dst,
- unsigned *dst_count,
- const struct pipe_vertex_buffer *src,
- unsigned src_count)
-{
- unsigned i;
-
- /* Reference the buffers of 'src' in 'dst'. */
- for (i = 0; i < src_count; i++) {
- pipe_resource_reference(&dst[i].buffer, src[i].buffer);
- }
- /* Unreference the rest of the buffers in 'dst'. */
- for (; i < *dst_count; i++) {
- pipe_resource_reference(&dst[i].buffer, NULL);
- }
-
- /* Update the size of 'dst' and copy over the other members
- * of pipe_vertex_buffer. */
- *dst_count = src_count;
- memcpy(dst, src, src_count * sizeof(struct pipe_vertex_buffer));
-}
-
static INLINE float
util_get_min_point_size(const struct pipe_rasterizer_state *state)
{
*/
static INLINE unsigned util_last_bit(unsigned u)
{
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304)
+ return u == 0 ? 0 : 32 - __builtin_clz(u);
+#else
unsigned r = 0;
while (u) {
r++;
u >>= 1;
}
return r;
+#endif
}
/* This is what was set in set_vertex_buffers.
* May contain user buffers. */
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- unsigned nr_vertex_buffers;
+ uint32_t enabled_vb_mask;
- /* Saved vertex buffers. */
- struct pipe_vertex_buffer vertex_buffer_saved[PIPE_MAX_ATTRIBS];
- unsigned nr_vertex_buffers_saved;
+ /* Saved vertex buffer. */
+ unsigned aux_vertex_buffer_slot;
+ struct pipe_vertex_buffer aux_vertex_buffer_saved;
/* Vertex buffers for the driver.
- * There are no user buffers. */
+ * There are usually no user buffers. */
struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS];
- unsigned nr_real_vertex_buffers;
- boolean vertex_buffers_dirty;
+ uint32_t dirty_real_vb_mask; /* which buffers are dirty since the last
+ call of set_vertex_buffers */
/* The index buffer. */
struct pipe_index_buffer index_buffer;
struct u_vbuf *
u_vbuf_create(struct pipe_context *pipe,
- struct u_vbuf_caps *caps)
+ struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index)
{
struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf);
mgr->caps = *caps;
+ mgr->aux_vertex_buffer_slot = aux_vertex_buffer_index;
mgr->pipe = pipe;
mgr->cso_cache = cso_cache_create();
mgr->translate_cache = translate_cache_create();
void u_vbuf_destroy(struct u_vbuf *mgr)
{
+ struct pipe_screen *screen = mgr->pipe->screen;
unsigned i;
+ unsigned num_vb = screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
+ PIPE_SHADER_CAP_MAX_INPUTS);
- mgr->pipe->set_vertex_buffers(mgr->pipe, 0, NULL);
+ mgr->pipe->set_vertex_buffers(mgr->pipe, 0, num_vb, NULL);
- for (i = 0; i < mgr->nr_vertex_buffers; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
}
- for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
}
+ pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, NULL);
translate_cache_destroy(mgr->translate_cache);
u_upload_destroy(mgr->uploader);
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
struct pipe_resource *out_buffer = NULL;
uint8_t *out_map;
- unsigned i, out_offset;
+ unsigned out_offset, mask;
/* Get a translate object. */
tr = translate_cache_find(mgr->translate_cache, key);
/* Map buffers we want to translate. */
- for (i = 0; i < mgr->nr_vertex_buffers; i++) {
- if (vb_mask & (1 << i)) {
- struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[i];
- unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
- uint8_t *map;
+ mask = vb_mask;
+ while (mask) {
+ struct pipe_vertex_buffer *vb;
+ unsigned offset;
+ uint8_t *map;
+ unsigned i = u_bit_scan(&mask);
- if (vb->user_buffer) {
- map = (uint8_t*)vb->user_buffer + offset;
- } else {
- unsigned size = vb->stride ? num_vertices * vb->stride
- : sizeof(double)*4;
+ vb = &mgr->vertex_buffer[i];
+ offset = vb->buffer_offset + vb->stride * start_vertex;
- if (offset+size > vb->buffer->width0) {
- size = vb->buffer->width0 - offset;
- }
+ if (vb->user_buffer) {
+ map = (uint8_t*)vb->user_buffer + offset;
+ } else {
+ unsigned size = vb->stride ? num_vertices * vb->stride
+ : sizeof(double)*4;
- map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size,
- PIPE_TRANSFER_READ, &vb_transfer[i]);
+ if (offset+size > vb->buffer->width0) {
+ size = vb->buffer->width0 - offset;
}
- /* Subtract min_index so that indexing with the index buffer works. */
- if (unroll_indices) {
- map -= vb->stride * min_index;
- }
+ map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size,
+ PIPE_TRANSFER_READ, &vb_transfer[i]);
+ }
- tr->set_buffer(tr, i, map, vb->stride, ~0);
+ /* Subtract min_index so that indexing with the index buffer works. */
+ if (unroll_indices) {
+ map -= vb->stride * min_index;
}
+
+ tr->set_buffer(tr, i, map, vb->stride, ~0);
}
/* Translate. */
}
/* Unmap all buffers. */
- for (i = 0; i < mgr->nr_vertex_buffers; i++) {
+ mask = vb_mask;
+ while (mask) {
+ unsigned i = u_bit_scan(&mask);
+
if (vb_transfer[i]) {
pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
}
/* Set the bit for each buffer which is incompatible, or isn't set. */
uint32_t unused_vb_mask =
mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
- ~((1 << mgr->nr_vertex_buffers) - 1);
+ ~mgr->enabled_vb_mask;
memset(fallback_vbs, ~0, sizeof(fallback_vbs));
uint32_t index;
if (!unused_vb_mask) {
- /* fail, reset the number to its original value */
- mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
return FALSE;
}
index = ffs(unused_vb_mask) - 1;
fallback_vbs[type] = index;
- if (index >= mgr->nr_real_vertex_buffers) {
- mgr->nr_real_vertex_buffers = index + 1;
- }
/*printf("found slot=%i for type=%i\n", index, type);*/
}
}
+ for (type = 0; type < VB_NUM; type++) {
+ if (mask[type]) {
+ mgr->dirty_real_vb_mask |= 1 << fallback_vbs[type];
+ }
+ }
+
memcpy(mgr->fallback_vbs, fallback_vbs, sizeof(fallback_vbs));
return TRUE;
}
if (vb != ~0) {
pipe_resource_reference(&mgr->real_vertex_buffer[vb].buffer, NULL);
mgr->fallback_vbs[i] = ~0;
+
+ /* This will cause the buffer to be unbound in the driver later. */
+ mgr->dirty_real_vb_mask |= 1 << vb;
}
}
- mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers;
}
#define FORMAT_REPLACE(what, withwhat) \
FREE(ve);
}
-void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
+void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *bufs)
{
unsigned i;
+ /* which buffers are enabled */
+ uint32_t enabled_vb_mask = 0;
+ /* which buffers are in user memory */
+ uint32_t user_vb_mask = 0;
+ /* which buffers are incompatible with the driver */
+ uint32_t incompatible_vb_mask = 0;
+ /* which buffers have a non-zero stride */
+ uint32_t nonzero_stride_vb_mask = 0;
+ uint32_t mask = ~(((1ull << count) - 1) << start_slot);
+
+ /* Zero out the bits we are going to rewrite completely. */
+ mgr->user_vb_mask &= mask;
+ mgr->incompatible_vb_mask &= mask;
+ mgr->nonzero_stride_vb_mask &= mask;
+ mgr->enabled_vb_mask &= mask;
+
+ if (!bufs) {
+ struct pipe_context *pipe = mgr->pipe;
+ /* Unbind. */
+ mgr->dirty_real_vb_mask &= mask;
- mgr->user_vb_mask = 0;
- mgr->incompatible_vb_mask = 0;
- mgr->nonzero_stride_vb_mask = 0;
+ for (i = 0; i < count; i++) {
+ unsigned dst_index = start_slot + i;
+
+ pipe_resource_reference(&mgr->vertex_buffer[dst_index].buffer, NULL);
+ pipe_resource_reference(&mgr->real_vertex_buffer[dst_index].buffer,
+ NULL);
+ }
+
+ pipe->set_vertex_buffers(pipe, start_slot, count, NULL);
+ return;
+ }
for (i = 0; i < count; i++) {
+ unsigned dst_index = start_slot + i;
const struct pipe_vertex_buffer *vb = &bufs[i];
- struct pipe_vertex_buffer *orig_vb = &mgr->vertex_buffer[i];
- struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
+ struct pipe_vertex_buffer *orig_vb = &mgr->vertex_buffer[dst_index];
+ struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[dst_index];
+
+ if (!vb->buffer && !vb->user_buffer) {
+ pipe_resource_reference(&orig_vb->buffer, NULL);
+ pipe_resource_reference(&real_vb->buffer, NULL);
+ real_vb->user_buffer = NULL;
+ continue;
+ }
pipe_resource_reference(&orig_vb->buffer, vb->buffer);
orig_vb->user_buffer = vb->user_buffer;
real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
real_vb->stride = orig_vb->stride = vb->stride;
- real_vb->user_buffer = NULL;
if (vb->stride) {
- mgr->nonzero_stride_vb_mask |= 1 << i;
- }
-
- if (!vb->buffer && !vb->user_buffer) {
- pipe_resource_reference(&real_vb->buffer, NULL);
- continue;
+ nonzero_stride_vb_mask |= 1 << dst_index;
}
+ enabled_vb_mask |= 1 << dst_index;
if ((!mgr->caps.buffer_offset_unaligned && vb->buffer_offset % 4 != 0) ||
(!mgr->caps.buffer_stride_unaligned && vb->stride % 4 != 0)) {
- mgr->incompatible_vb_mask |= 1 << i;
+ incompatible_vb_mask |= 1 << dst_index;
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
- mgr->user_vb_mask |= 1 << i;
+ user_vb_mask |= 1 << dst_index;
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
real_vb->user_buffer = vb->user_buffer;
}
- for (i = count; i < mgr->nr_vertex_buffers; i++) {
- pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL);
- }
- for (i = count; i < mgr->nr_real_vertex_buffers; i++) {
- pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL);
- }
+ mgr->user_vb_mask |= user_vb_mask;
+ mgr->incompatible_vb_mask |= incompatible_vb_mask;
+ mgr->nonzero_stride_vb_mask |= nonzero_stride_vb_mask;
+ mgr->enabled_vb_mask |= enabled_vb_mask;
- mgr->nr_vertex_buffers = count;
- mgr->nr_real_vertex_buffers = count;
- mgr->vertex_buffers_dirty = TRUE;
+ /* All changed buffers are marked as dirty, even the NULL ones,
+ * which will cause the NULL buffers to be unbound in the driver later. */
+ mgr->dirty_real_vb_mask |= ~mask;
}
void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
{
unsigned i;
unsigned nr_velems = mgr->ve->count;
- unsigned nr_vbufs = mgr->nr_vertex_buffers;
+ unsigned nr_vbufs = util_last_bit(mgr->enabled_vb_mask);
struct pipe_vertex_element *velems =
mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve;
unsigned start_offset[PIPE_MAX_ATTRIBS];
}
}
+static void u_vbuf_set_driver_vertex_buffers(struct u_vbuf *mgr)
+{
+ struct pipe_context *pipe = mgr->pipe;
+ unsigned start_slot, count;
+
+ start_slot = ffs(mgr->dirty_real_vb_mask) - 1;
+ count = util_last_bit(mgr->dirty_real_vb_mask >> start_slot);
+
+ pipe->set_vertex_buffers(pipe, start_slot, count,
+ mgr->real_vertex_buffer + start_slot);
+ mgr->dirty_real_vb_mask = 0;
+}
+
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
{
struct pipe_context *pipe = mgr->pipe;
if (!mgr->incompatible_vb_mask &&
!mgr->ve->incompatible_elem_mask &&
!user_vb_mask) {
+
/* Set vertex buffers if needed. */
- if (mgr->vertex_buffers_dirty) {
- pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
- mgr->real_vertex_buffer);
- mgr->vertex_buffers_dirty = FALSE;
+ if (mgr->dirty_real_vb_mask) {
+ u_vbuf_set_driver_vertex_buffers(mgr);
}
pipe->draw_vbo(pipe, info);
if (user_vb_mask) {
u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
info->start_instance, info->instance_count);
+ mgr->dirty_real_vb_mask |= user_vb_mask;
}
/*
*/
u_upload_unmap(mgr->uploader);
- pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
- mgr->real_vertex_buffer);
+ u_vbuf_set_driver_vertex_buffers(mgr);
if (unlikely(unroll_indices)) {
struct pipe_draw_info new_info = *info;
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);
}
- mgr->vertex_buffers_dirty = TRUE;
}
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr)
mgr->ve_saved = NULL;
}
-void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr)
+void u_vbuf_save_aux_vertex_buffer_slot(struct u_vbuf *mgr)
{
- util_copy_vertex_buffers(mgr->vertex_buffer_saved,
- &mgr->nr_vertex_buffers_saved,
- mgr->vertex_buffer,
- mgr->nr_vertex_buffers);
+ struct pipe_vertex_buffer *vb =
+ &mgr->vertex_buffer[mgr->aux_vertex_buffer_slot];
+
+ pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, vb->buffer);
+ memcpy(&mgr->aux_vertex_buffer_saved, vb, sizeof(*vb));
}
-void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr)
+void u_vbuf_restore_aux_vertex_buffer_slot(struct u_vbuf *mgr)
{
- unsigned i;
-
- u_vbuf_set_vertex_buffers(mgr, mgr->nr_vertex_buffers_saved,
- mgr->vertex_buffer_saved);
- for (i = 0; i < mgr->nr_vertex_buffers_saved; i++) {
- pipe_resource_reference(&mgr->vertex_buffer_saved[i].buffer, NULL);
- }
- mgr->nr_vertex_buffers_saved = 0;
+ u_vbuf_set_vertex_buffers(mgr, mgr->aux_vertex_buffer_slot, 1,
+ &mgr->aux_vertex_buffer_saved);
+ pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, NULL);
}
struct u_vbuf *
u_vbuf_create(struct pipe_context *pipe,
- struct u_vbuf_caps *caps);
+ struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index);
void u_vbuf_destroy(struct u_vbuf *mgr);
/* State and draw functions. */
void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count,
const struct pipe_vertex_element *states);
-void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
+void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
+ unsigned start_slot, unsigned count,
const struct pipe_vertex_buffer *bufs);
void u_vbuf_set_index_buffer(struct u_vbuf *mgr,
const struct pipe_index_buffer *ib);
/* Save/restore functionality. */
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr);
void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr);
-void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr);
-void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr);
+void u_vbuf_save_aux_vertex_buffer_slot(struct u_vbuf *mgr);
+void u_vbuf_restore_aux_vertex_buffer_slot(struct u_vbuf *mgr);
#endif
c->pipe->set_scissor_state(c->pipe, &s->scissor);
c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
c->pipe->bind_vs_state(c->pipe, c->vs);
- c->pipe->set_vertex_buffers(c->pipe, 1, &c->vertex_buf);
+ c->pipe->set_vertex_buffers(c->pipe, 0, 1, &c->vertex_buf);
c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);
pipe_set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->csc_matrix);
c->pipe->bind_rasterizer_state(c->pipe, c->rast);
filter->pipe->bind_fs_state(filter->pipe, filter->fs);
filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
filter->pipe->set_viewport_state(filter->pipe, &viewport);
- filter->pipe->set_vertex_buffers(filter->pipe, 1, &filter->quad);
+ filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
filter->pipe->bind_fs_state(filter->pipe, filter->fs);
filter->pipe->set_framebuffer_state(filter->pipe, &fb_state);
filter->pipe->set_viewport_state(filter->pipe, &viewport);
- filter->pipe->set_vertex_buffers(filter->pipe, 1, &filter->quad);
+ filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad);
filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves);
util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4);
if (!ref_frames[j] || !ref_frames[j][i]) continue;
vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);;
- dec->base.context->set_vertex_buffers(dec->base.context, 3, vb);
+ dec->base.context->set_vertex_buffers(dec->base.context, 0, 3, vb);
vl_mc_render_ref(i ? &dec->mc_c : &dec->mc_y, &buf->mc[i], ref_frames[j][i]);
}
if (!buf->num_ycbcr_blocks[i]) continue;
vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i);
- dec->base.context->set_vertex_buffers(dec->base.context, 2, vb);
+ dec->base.context->set_vertex_buffers(dec->base.context, 0, 2, vb);
vl_zscan_render(i ? &dec->zscan_c : & dec->zscan_y, &buf->zscan[i] , buf->num_ycbcr_blocks[i]);
if (!buf->num_ycbcr_blocks[plane]) continue;
vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, plane);
- dec->base.context->set_vertex_buffers(dec->base.context, 2, vb);
+ dec->base.context->set_vertex_buffers(dec->base.context, 0, 2, vb);
if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
vl_idct_prepare_stage2(i ? &dec->idct_c : &dec->idct_y, &buf->idct[plane]);
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);
}
pipe->set_vertex_buffers(pipe,
- num_buffers,
+ start_slot, num_buffers,
buffers);
}
#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"
}
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 *
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);
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);
}
pipe->set_vertex_buffers(pipe,
- num_buffers,
+ start_slot, num_buffers,
buffers);
}
*/
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);
}
#include "lp_state.h"
#include "draw/draw_context.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
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);
}
/* 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);
{
}
-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)
{
}
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) {
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);
}
/* 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);
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);
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);
}
*
*/
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "nouveau/nouveau_gldefs.h"
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;
}
*/
#include "pipe/p_defines.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
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);
*/
#include "pipe/p_defines.h"
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
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
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) {
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;
#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"
}
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);
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);
}
}
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,
}
}
-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;
}
/* 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);
}
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);
#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"
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,
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);
buffers = unwrapped_buffers;
}
- pipe->set_vertex_buffers(pipe,
+ pipe->set_vertex_buffers(pipe, start_slot,
num_buffers,
buffers);
/* 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);
}
#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"
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);
}
/* 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);
unsigned flag_1d;
unsigned flag_srgb;
} tex_flags;
-
- boolean any_user_vertex_buffers;
};
struct svga_prescale {
/* 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);*/
*
**********************************************************/
+#include "util/u_helpers.h"
#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
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;
}
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);
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);
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");
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();
struct pipe_surface **resources);
void (*set_vertex_buffers)( struct pipe_context *,
+ unsigned start_slot,
unsigned num_buffers,
const struct pipe_vertex_buffer * );
pipe->bind_depth_stencil_alpha_state(pipe, zsa);
pipe->bind_blend_state(pipe, blend);
pipe->bind_vertex_elements_state(pipe, elements);
- pipe->set_vertex_buffers(pipe, 1, &vbuf);
+ pipe->set_vertex_buffers(pipe, 0, 1, &vbuf);
pipe->bind_fs_state(pipe, fs);
pipe->bind_vs_state(pipe, vs);
if(pipe->bind_gs_state)
{
assert(renderer->state == RENDERER_STATE_POLYGON_STENCIL);
- cso_set_vertex_buffers(renderer->cso, 1, vbuf);
+ cso_set_vertex_buffers(renderer->cso, 0, 1, vbuf);
if (!renderer->u.polygon_stencil.manual_two_sides) {
cso_draw_arrays(renderer->cso, mode, start, count);
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
sizeof(vertices),
vertices);
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
vertices);
}
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
bytes,
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
sizeof(vertices),
vertices);
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
sizeof(vertices),
vertices);
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
num_verts * sizeof(struct vertex),
verts);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
static void set_vertex_shader(void)
sizeof(vertices),
vertices);
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
sizeof(inst_data),
inst_data);
- ctx->set_vertex_buffers(ctx, 2, vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 2, vbuf);
/* index data */
ibuf.buffer = pipe_buffer_create_with_data(ctx,
sizeof(vertices),
vertices);
- info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
+ info.ctx->set_vertex_buffers(info.ctx, 0, 1, &vbuf);
}
sizeof(vertices),
vertices);
- ctx->set_vertex_buffers(ctx, 1, &vbuf);
+ ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
}
static void set_vertex_shader( void )
num_velements = vpv->num_inputs;
}
- cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer);
+ cso_set_vertex_buffers(st->cso_context, 0, num_vbuffers, vbuffer);
+ if (st->last_num_vbuffers > num_vbuffers) {
+ /* Unbind remaining buffers, if any. */
+ cso_set_vertex_buffers(st->cso_context, num_vbuffers,
+ st->last_num_vbuffers - num_vbuffers, NULL);
+ }
+ st->last_num_vbuffers = num_vbuffers;
cso_set_vertex_elements(st->cso_context, num_velements, velements);
}
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
- cso_save_vertex_buffers(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
/* rasterizer state: just scissor */
st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled;
x, y, width, height, z, color, &vbuf, &offset);
if (vbuf) {
- util_draw_vertex_buffer(pipe, st->cso_context, vbuf, offset,
+ util_draw_vertex_buffer(pipe, st->cso_context, vbuf,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
3); /* attribs/vert */
cso_restore_vertex_shader(cso);
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
- cso_restore_vertex_buffers(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
cso_restore_stream_outputs(cso);
pipe_resource_reference(&vbuf, NULL);
/* draw */
util_draw_vertex_buffer(pipe,
st->cso_context,
- vbuf, offset,
+ vbuf,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
cso_save_vertex_shader(st->cso_context);
cso_save_geometry_shader(st->cso_context);
cso_save_vertex_elements(st->cso_context);
- cso_save_vertex_buffers(st->cso_context);
+ cso_save_aux_vertex_buffer_slot(st->cso_context);
/* blend state: RGBA masking */
{
cso_restore_vertex_shader(st->cso_context);
cso_restore_geometry_shader(st->cso_context);
cso_restore_vertex_elements(st->cso_context);
- cso_restore_vertex_buffers(st->cso_context);
+ cso_restore_aux_vertex_buffer_slot(st->cso_context);
cso_restore_stream_outputs(st->cso_context);
}
}
u_upload_unmap(st->uploader);
- util_draw_vertex_buffer(pipe, st->cso_context, buf, offset,
+ util_draw_vertex_buffer(pipe, st->cso_context, buf,
+ cso_get_aux_vertex_buffer_slot(st->cso_context),
+ offset,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
- cso_save_vertex_buffers(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
if (write_stencil) {
cso_save_depth_stencil_alpha(cso);
cso_save_blend(cso);
cso_restore_vertex_shader(cso);
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
- cso_restore_vertex_buffers(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
cso_restore_stream_outputs(cso);
if (write_stencil) {
cso_restore_depth_stencil_alpha(cso);
cso_save_vertex_shader(cso);
cso_save_geometry_shader(cso);
cso_save_vertex_elements(cso);
- cso_save_vertex_buffers(cso);
+ cso_save_aux_vertex_buffer_slot(cso);
{
void *vs = lookup_shader(pipe, numAttribs,
util_draw_vertex_buffer(pipe, cso, vbuffer,
+ cso_get_aux_vertex_buffer_slot(cso),
offset, /* offset */
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
cso_restore_vertex_shader(cso);
cso_restore_geometry_shader(cso);
cso_restore_vertex_elements(cso);
- cso_restore_vertex_buffers(cso);
+ cso_restore_aux_vertex_buffer_slot(cso);
cso_restore_stream_outputs(cso);
}
memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element));
st->velems_util_draw[i].src_offset = i * 4 * sizeof(float);
st->velems_util_draw[i].instance_divisor = 0;
- st->velems_util_draw[i].vertex_buffer_index = 0;
+ st->velems_util_draw[i].vertex_buffer_index =
+ cso_get_aux_vertex_buffer_slot(st->cso_context);
st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
int force_msaa;
void *winsys_drawable_handle;
+ /* The number of vertex buffers from the last call of validate_arrays. */
+ unsigned last_num_vbuffers;
+
/* Active render condition. */
struct pipe_query *render_condition;
unsigned condition_mode;
#endif
}
- draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
+ draw_set_vertex_buffers(draw, 0, vp->num_inputs, vbuffers);
draw_set_vertex_elements(draw, vp->num_inputs, velements);
memset(&ibuffer, 0, sizeof(ibuffer));
draw_set_mapped_vertex_buffer(draw, attr, NULL);
pipe_resource_reference(&vbuffers[attr].buffer, NULL);
}
- draw_set_vertex_buffers(draw, 0, NULL);
+ draw_set_vertex_buffers(draw, 0, vp->num_inputs, NULL);
}