summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-05-11 16:38:13 +0200
committerMarek Olšák <[email protected]>2012-05-11 16:38:13 +0200
commitbb4c5d72d7c7cb1d9e7016e2c07c36875f30011a (patch)
tree153444ff535900f82ae63b5af8ccd09fb2f063af /src/mesa
parent96956dc5076fc03b9290368ca90e3f3b870ee613 (diff)
parent8dd3e341b337ca2d22bcc0e7548a78a6c36ca77d (diff)
Merge branch 'gallium-userbuf'
Conflicts: src/gallium/docs/source/screen.rst src/gallium/drivers/nv50/nv50_state.c src/gallium/include/pipe/p_defines.h src/mesa/state_tracker/st_draw.c
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c27
-rw-r--r--src/mesa/state_tracker/st_context.c53
-rw-r--r--src/mesa/state_tracker/st_context.h16
-rw-r--r--src/mesa/state_tracker/st_draw.c240
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c32
5 files changed, 111 insertions, 257 deletions
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 05667a74305..fd9228583d2 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -38,6 +38,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
+#include "util/u_upload_mgr.h"
#include "st_debug.h"
#include "st_context.h"
@@ -55,15 +56,13 @@ void st_upload_constants( struct st_context *st,
struct gl_program_parameter_list *params,
unsigned shader_type)
{
- struct pipe_context *pipe = st->pipe;
-
assert(shader_type == PIPE_SHADER_VERTEX ||
shader_type == PIPE_SHADER_FRAGMENT ||
shader_type == PIPE_SHADER_GEOMETRY);
/* update constants */
if (params && params->NumParameters) {
- struct pipe_resource *cbuf;
+ struct pipe_constant_buffer cb;
const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
/* Update the constants which come from fixed-function state, such as
@@ -77,20 +76,28 @@ void st_upload_constants( struct st_context *st,
* avoid gratuitous rendering synchronization.
* Let's use a user buffer to avoid an unnecessary copy.
*/
- cbuf = pipe_user_buffer_create(pipe->screen,
- params->ParameterValues,
- paramBytes,
- PIPE_BIND_CONSTANT_BUFFER);
+ if (st->constbuf_uploader) {
+ cb.buffer = NULL;
+ cb.user_buffer = NULL;
+ u_upload_data(st->constbuf_uploader, 0, paramBytes,
+ params->ParameterValues, &cb.buffer_offset, &cb.buffer);
+ u_upload_unmap(st->constbuf_uploader);
+ } else {
+ cb.buffer = NULL;
+ cb.user_buffer = params->ParameterValues;
+ cb.buffer_offset = 0;
+ }
+ cb.buffer_size = paramBytes;
if (ST_DEBUG & DEBUG_CONSTANTS) {
- debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
+ debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
__FUNCTION__, shader_type, params->NumParameters,
params->StateFlags);
_mesa_print_parameter_list(params);
}
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
- pipe_resource_reference(&cbuf, NULL);
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
st->state.constants[shader_type].ptr = params->ParameterValues;
st->state.constants[shader_type].size = paramBytes;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index ce7dbb3f39a..b4497652539 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -65,7 +65,6 @@
#include "util/u_inlines.h"
#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
-#include "util/u_vbuf.h"
DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE)
@@ -112,32 +111,12 @@ st_get_msaa(void)
}
-static void st_init_vbuf(struct st_context *st)
-{
- struct u_vbuf_caps caps;
-
- u_vbuf_get_caps(st->pipe->screen, &caps);
-
- /* Create u_vbuf if there is anything unsupported. */
- if (!caps.buffer_offset_unaligned ||
- !caps.buffer_stride_unaligned ||
- !caps.velem_src_offset_unaligned ||
- !caps.format_fixed32 ||
- !caps.format_float16 ||
- !caps.format_float64 ||
- !caps.format_norm32 ||
- !caps.format_scaled32 ||
- !caps.user_vertex_buffers) {
- /* XXX user vertex buffers are always uploaded regardless of the CAP. */
- st->vbuf = u_vbuf_create(st->pipe, &caps);
- cso_install_vbuf(st->cso_context, st->vbuf);
- }
-}
static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
{
+ struct pipe_screen *screen = pipe->screen;
uint i;
struct st_context *st = ST_CALLOC_STRUCT( st_context );
@@ -156,9 +135,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->dirty.st = ~0;
st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
+ st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4,
+ PIPE_BIND_INDEX_BUFFER);
+ }
+
+ if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) {
+ unsigned alignment =
+ screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT);
+
+ st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment,
+ PIPE_BIND_CONSTANT_BUFFER);
+ }
+
st->cso_context = cso_create_context(pipe);
- st_init_vbuf(st);
st_init_atoms( st );
st_init_bitmap(st);
st_init_clear(st);
@@ -254,11 +246,6 @@ static void st_destroy_context_priv( struct st_context *st )
st_destroy_drawpix(st);
st_destroy_drawtex(st);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
-
for (i = 0; i < Elements(st->state.sampler_views); i++) {
pipe_sampler_view_reference(&st->state.sampler_views[i], NULL);
}
@@ -269,6 +256,12 @@ static void st_destroy_context_priv( struct st_context *st )
}
u_upload_destroy(st->uploader);
+ if (st->indexbuf_uploader) {
+ u_upload_destroy(st->indexbuf_uploader);
+ }
+ if (st->constbuf_uploader) {
+ u_upload_destroy(st->constbuf_uploader);
+ }
free( st );
}
@@ -276,7 +269,6 @@ static void st_destroy_context_priv( struct st_context *st )
void st_destroy_context( struct st_context *st )
{
struct pipe_context *pipe = st->pipe;
- struct u_vbuf *vbuf = st->vbuf;
struct cso_context *cso = st->cso_context;
struct gl_context *ctx = st->ctx;
GLuint i;
@@ -312,9 +304,6 @@ void st_destroy_context( struct st_context *st )
st_destroy_context_priv(st);
st = NULL;
- if (vbuf)
- u_vbuf_destroy(vbuf);
-
cso_destroy_context(cso);
pipe->destroy( pipe );
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 4786ed22fe9..00a405b69f9 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -41,7 +41,6 @@ struct gen_mipmap_state;
struct st_context;
struct st_fragment_program;
struct u_upload_mgr;
-struct u_vbuf;
#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */
@@ -74,8 +73,7 @@ struct st_context
struct pipe_context *pipe;
- struct u_upload_mgr *uploader;
- struct u_vbuf *vbuf;
+ struct u_upload_mgr *uploader, *indexbuf_uploader, *constbuf_uploader;
struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
@@ -191,18 +189,6 @@ struct st_context
int force_msaa;
void *winsys_drawable_handle;
- /* User vertex buffers. */
- struct {
- struct pipe_resource *buffer;
-
- /** Element size */
- GLuint element_size;
-
- /** Attribute stride */
- GLsizei stride;
- } user_attrib[PIPE_MAX_ATTRIBS];
- unsigned num_user_attribs;
-
/* Active render condition. */
struct pipe_query *render_condition;
unsigned condition_mode;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 42dc3757615..a8c20f45acd 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -61,6 +61,7 @@
#include "util/u_format.h"
#include "util/u_prim.h"
#include "util/u_draw_quad.h"
+#include "util/u_upload_mgr.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_context.h"
@@ -402,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer *vbuffer,
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
const GLubyte *low_addr = NULL;
GLboolean usingVBO; /* all arrays in a VBO? */
struct gl_buffer_object *bufobj;
- GLuint user_buffer_size = 0;
- GLuint vertex_size = 0; /* bytes per vertex, in bytes */
GLsizei stride;
/* Find the lowest address of the arrays we're drawing,
@@ -464,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx,
array->Normalized,
array->Integer);
assert(velements[attr].src_format);
-
- if (!usingVBO) {
- /* how many bytes referenced by this attribute array? */
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
- uint bytes = src_offset + stride * last_index + element_size;
-
- user_buffer_size = MAX2(user_buffer_size, bytes);
-
- /* update vertex size */
- vertex_size = MAX2(vertex_size, src_offset + element_size);
- }
}
/*
@@ -484,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx,
if (vpv->num_inputs == 0) {
/* just defensive coding here */
vbuffer->buffer = NULL;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = 0;
vbuffer->stride = 0;
- st->num_user_attribs = 0;
}
else if (usingVBO) {
/* all interleaved arrays in a VBO */
@@ -497,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer->buffer = NULL;
- pipe_resource_reference(&vbuffer->buffer, stobj->buffer);
+ vbuffer->buffer = stobj->buffer;
+ vbuffer->user_buffer = NULL;
vbuffer->buffer_offset = pointer_to_offset(low_addr);
vbuffer->stride = stride;
- st->num_user_attribs = 0;
}
else {
/* all interleaved arrays in user memory */
- vbuffer->buffer = pipe_user_buffer_create(pipe->screen,
- (void*) low_addr,
- user_buffer_size,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer->buffer = NULL;
+ vbuffer->user_buffer = low_addr;
vbuffer->buffer_offset = 0;
vbuffer->stride = stride;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer);
- st->user_attrib[0].element_size = vertex_size;
- st->user_attrib[0].stride = stride;
- st->num_user_attribs = 1;
}
return GL_TRUE;
@@ -536,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
struct pipe_vertex_buffer vbuffer[],
- struct pipe_vertex_element velements[],
- unsigned max_index,
- unsigned num_instances)
+ struct pipe_vertex_element velements[])
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
GLuint attr;
for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_client_array *array = arrays[mesaAttr];
struct gl_buffer_object *bufobj = array->BufferObj;
- GLuint element_size = array->_ElementSize;
GLsizei stride = array->StrideB;
- assert(element_size == array->Size * _mesa_sizeof_type(array->Type));
+ assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type));
if (_mesa_is_bufferobj(bufobj)) {
/* Attribute data is in a VBO.
@@ -565,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
return GL_FALSE;
}
- vbuffer[attr].buffer = NULL;
- pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer);
+ vbuffer[attr].buffer = stobj->buffer;
+ vbuffer[attr].user_buffer = NULL;
vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr);
}
else {
/* wrap user data */
- uint bytes;
void *ptr;
if (array->Ptr) {
- uint divisor = array->InstanceDivisor;
- uint last_index = divisor ? num_instances / divisor : max_index;
-
- bytes = stride * last_index + element_size;
-
ptr = (void *) array->Ptr;
}
else {
/* no array, use ctx->Current.Attrib[] value */
- bytes = element_size = sizeof(ctx->Current.Attrib[0]);
ptr = (void *) ctx->Current.Attrib[mesaAttr];
stride = 0;
}
assert(ptr);
- assert(bytes);
-
- vbuffer[attr].buffer =
- pipe_user_buffer_create(pipe->screen, ptr, bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffer[attr].buffer = NULL;
+ vbuffer[attr].user_buffer = ptr;
vbuffer[attr].buffer_offset = 0;
-
- /* Track user vertex buffers. */
- pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer);
- st->user_attrib[attr].element_size = element_size;
- st->user_attrib[attr].stride = stride;
- st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1);
-
- if (!vbuffer[attr].buffer) {
- /* probably ran out of memory */
- return GL_FALSE;
- }
}
/* common-case setup */
@@ -629,34 +577,31 @@ setup_non_interleaved_attribs(struct gl_context *ctx,
static void
-setup_index_buffer(struct gl_context *ctx,
+setup_index_buffer(struct st_context *st,
const struct _mesa_index_buffer *ib,
struct pipe_index_buffer *ibuffer)
{
- struct st_context *st = st_context(ctx);
- struct pipe_context *pipe = st->pipe;
+ struct gl_buffer_object *bufobj = ib->obj;
- memset(ibuffer, 0, sizeof(*ibuffer));
- if (ib) {
- struct gl_buffer_object *bufobj = ib->obj;
-
- ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
+ ibuffer->index_size = vbo_sizeof_ib_type(ib->type);
- /* get/create the index buffer object */
- if (_mesa_is_bufferobj(bufobj)) {
- /* elements/indexes are in a real VBO */
- struct st_buffer_object *stobj = st_buffer_object(bufobj);
- pipe_resource_reference(&ibuffer->buffer, stobj->buffer);
- ibuffer->offset = pointer_to_offset(ib->ptr);
- }
- else {
- /* element/indicies are in user space memory */
- ibuffer->buffer =
- pipe_user_buffer_create(pipe->screen, (void *) ib->ptr,
- ib->count * ibuffer->index_size,
- PIPE_BIND_INDEX_BUFFER);
- }
+ /* get/create the index buffer object */
+ if (_mesa_is_bufferobj(bufobj)) {
+ /* indices are in a real VBO */
+ ibuffer->buffer = st_buffer_object(bufobj)->buffer;
+ ibuffer->offset = pointer_to_offset(ib->ptr);
}
+ else if (st->indexbuf_uploader) {
+ u_upload_data(st->indexbuf_uploader, 0, ib->count * ibuffer->index_size,
+ ib->ptr, &ibuffer->offset, &ibuffer->buffer);
+ u_upload_unmap(st->indexbuf_uploader);
+ }
+ else {
+ /* indices are in user space memory */
+ ibuffer->user_buffer = ib->ptr;
+ }
+
+ cso_set_index_buffer(st->cso_context, ibuffer);
}
@@ -811,10 +756,10 @@ handle_fallback_primitive_restart(struct cso_context *cso,
unsigned num_sub_prims;
assert(info.indexed);
- assert(ibuffer->buffer);
+ assert(ibuffer->buffer || ibuffer->user_buffer);
assert(ib);
- if (!ibuffer->buffer || !ib)
+ if (!ibuffer->buffer || !ibuffer->user_buffer || !ib)
return;
info.primitive_restart = FALSE;
@@ -894,9 +839,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim)
*/
static GLboolean
st_validate_varrays(struct gl_context *ctx,
- const struct gl_client_array **arrays,
- unsigned max_index,
- unsigned num_instances)
+ const struct gl_client_array **arrays)
{
struct st_context *st = st_context(ctx);
const struct st_vertex_program *vp;
@@ -904,8 +847,6 @@ st_validate_varrays(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
unsigned num_vbuffers, num_velements;
- GLuint attr;
- unsigned i;
/* must get these after state validation! */
vp = st->vp;
@@ -913,18 +854,12 @@ st_validate_varrays(struct gl_context *ctx,
memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs);
- /* Unreference any user vertex buffers. */
- for (i = 0; i < st->num_user_attribs; i++) {
- pipe_resource_reference(&st->user_attrib[i].buffer, NULL);
- }
- st->num_user_attribs = 0;
-
/*
* Setup the vbuffer[] and velements[] arrays.
*/
if (is_interleaved_arrays(vp, vpv, arrays)) {
- if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements,
- max_index, num_instances)) {
+ if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer,
+ velements)) {
return GL_FALSE;
}
@@ -935,8 +870,7 @@ st_validate_varrays(struct gl_context *ctx,
}
else {
if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays,
- vbuffer, velements, max_index,
- num_instances)) {
+ vbuffer, velements)) {
return GL_FALSE;
}
@@ -947,14 +881,6 @@ st_validate_varrays(struct gl_context *ctx,
cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer);
cso_set_vertex_elements(st->cso_context, num_velements, velements);
- /* unreference buffers (frees wrapped user-space buffer objects)
- * This is OK, because the pipe driver should reference buffers by itself
- * in set_vertex_buffers. */
- for (attr = 0; attr < num_vbuffers; attr++) {
- pipe_resource_reference(&vbuffer[attr].buffer, NULL);
- assert(!vbuffer[attr].buffer);
- }
-
return GL_TRUE;
}
@@ -976,11 +902,10 @@ st_draw_vbo(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_index_buffer ibuffer;
+ struct pipe_index_buffer ibuffer = {0};
struct pipe_draw_info info;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
- unsigned i, num_instances = 1;
- unsigned max_index_plus_base;
+ unsigned i;
GLboolean new_array;
/* Mesa core state should have been validated already */
@@ -994,43 +919,6 @@ st_draw_vbo(struct gl_context *ctx,
(st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) ||
(st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
- if (ib) {
- int max_base_vertex = 0;
-
- /* Gallium probably doesn't want this in some cases. */
- if (!index_bounds_valid)
- if (!all_varyings_in_vbos(arrays))
- vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
- nr_prims);
-
- for (i = 0; i < nr_prims; i++) {
- num_instances = MAX2(num_instances, prims[i].num_instances);
- max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex);
- }
-
- /* Compute the sum of max_index and max_base_vertex. That's the value
- * we need to use when creating buffers.
- */
- if (max_index == ~0)
- max_index_plus_base = max_index;
- else
- max_index_plus_base = max_index + max_base_vertex;
- }
- else {
- /* Get min/max index for non-indexed drawing. */
- min_index = ~0;
- max_index = 0;
-
- for (i = 0; i < nr_prims; i++) {
- min_index = MIN2(min_index, prims[i].start);
- max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
- num_instances = MAX2(num_instances, prims[i].num_instances);
- }
-
- /* The base vertex offset only applies to indexed drawing */
- max_index_plus_base = max_index;
- }
-
/* Validate state. */
if (st->dirty.st) {
GLboolean vertDataEdgeFlags;
@@ -1045,8 +933,7 @@ st_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (new_array) {
- if (!st_validate_varrays(ctx, arrays, max_index_plus_base,
- num_instances)) {
+ if (!st_validate_varrays(ctx, arrays)) {
/* probably out of memory, no-op the draw call */
return;
}
@@ -1061,31 +948,16 @@ st_draw_vbo(struct gl_context *ctx,
#endif
}
- /* Notify the driver that the content of user buffers may have been
- * changed. */
- assert(max_index >= min_index);
- if (!new_array && st->num_user_attribs) {
- for (i = 0; i < st->num_user_attribs; i++) {
- if (st->user_attrib[i].buffer) {
- unsigned element_size = st->user_attrib[i].element_size;
- unsigned stride = st->user_attrib[i].stride;
- unsigned min_offset = min_index * stride;
- unsigned max_offset = max_index_plus_base * stride + element_size;
-
- assert(max_offset > min_offset);
-
- pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer,
- min_offset,
- max_offset - min_offset);
- }
- }
- }
-
- setup_index_buffer(ctx, ib, &ibuffer);
- cso_set_index_buffer(st->cso_context, &ibuffer);
-
util_draw_init_info(&info);
if (ib) {
+ /* Get index bounds for user buffers. */
+ if (!index_bounds_valid)
+ if (!all_varyings_in_vbos(arrays))
+ vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
+ nr_prims);
+
+ setup_index_buffer(st, ib, &ibuffer);
+
info.indexed = TRUE;
if (min_index != ~0 && max_index != ~0) {
info.min_index = min_index;
@@ -1098,10 +970,12 @@ st_draw_vbo(struct gl_context *ctx,
info.primitive_restart = ctx->Array.PrimitiveRestart;
info.restart_index = ctx->Array.RestartIndex;
}
-
- /* Set info.count_from_stream_output. */
- if (tfb_vertcount) {
- st_transform_feedback_draw_init(tfb_vertcount, &info);
+ else {
+ /* Transform feedback drawing is always non-indexed. */
+ /* Set info.count_from_stream_output. */
+ if (tfb_vertcount) {
+ st_transform_feedback_draw_init(tfb_vertcount, &info);
+ }
}
/* do actual drawing */
@@ -1134,7 +1008,9 @@ st_draw_vbo(struct gl_context *ctx,
cso_draw_vbo(st->cso_context, &info);
}
- pipe_resource_reference(&ibuffer.buffer, NULL);
+ if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) {
+ pipe_resource_reference(&ibuffer.buffer, NULL);
+ }
}
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 257618aa992..4209fb214f8 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -107,7 +107,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS];
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer ibuffer;
- struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *ib_transfer = NULL;
const struct gl_client_array **arrays = ctx->Array._DrawArrays;
GLuint attr, i;
@@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx,
assert(stobj->buffer);
vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = NULL;
pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer);
vbuffers[attr].buffer_offset = pointer_to_offset(low_addr);
velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr;
+
+ /* map the attrib buffer */
+ map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
+ PIPE_TRANSFER_READ,
+ &vb_transfer[attr]);
+ draw_set_mapped_vertex_buffer(draw, attr, map);
}
else {
- /* attribute data is in user-space memory, not a VBO */
- uint bytes = (arrays[mesaAttr]->Size
- * _mesa_sizeof_type(arrays[mesaAttr]->Type)
- * (max_index + 1));
-
- /* wrap user data */
- vbuffers[attr].buffer
- = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr,
- bytes,
- PIPE_BIND_VERTEX_BUFFER);
+ vbuffers[attr].buffer = NULL;
+ vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr;
vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0;
+
+ draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer);
}
/* common-case setup */
@@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx,
#if 0
draw_set_vertex_buffer(draw, attr, &vbuffer[attr]);
#endif
-
- /* map the attrib buffer */
- map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
- PIPE_TRANSFER_READ,
- &vb_transfer[attr]);
- draw_set_mapped_vertex_buffer(draw, attr, map);
}
draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers);
@@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
out_unref_vertex:
for (attr = 0; attr < vp->num_inputs; attr++) {
- pipe_buffer_unmap(pipe, vb_transfer[attr]);
+ if (vb_transfer[attr])
+ pipe_buffer_unmap(pipe, vb_transfer[attr]);
draw_set_mapped_vertex_buffer(draw, attr, NULL);
pipe_resource_reference(&vbuffers[attr].buffer, NULL);
}