draw: don't crash on vertex buffer overflow

We would crash when stride was bigger than the size of the buffer.
The correct behavior is to just fetch zero's in this case.
Unfortunatly with user_buffer's there's no way to validate the size
because currently we're just not getting it. Adjust the draw interface
to pass the size along the mapped buffer, which works perfectly
for buffer backed vertex_buffers and, in future, it will allow
us to plumb user_buffer sizes through the same interface.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Zack Rusin 2013-05-08 23:48:20 -04:00
parent 386327c48f
commit 29853ab7b8
17 changed files with 142 additions and 45 deletions

View File

@ -364,9 +364,11 @@ draw_set_vertex_elements(struct draw_context *draw,
*/ */
void void
draw_set_mapped_vertex_buffer(struct draw_context *draw, draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer) unsigned attr, const void *buffer,
size_t size)
{ {
draw->pt.user.vbuffer[attr] = buffer; draw->pt.user.vbuffer[attr].map = buffer;
draw->pt.user.vbuffer[attr].size = size;
} }

View File

@ -215,7 +215,8 @@ void draw_set_indexes(struct draw_context *draw,
const void *elements, unsigned elem_size); const void *elements, unsigned elem_size);
void draw_set_mapped_vertex_buffer(struct draw_context *draw, void draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer); unsigned attr, const void *buffer,
size_t size);
void void
draw_set_mapped_constant_buffer(struct draw_context *draw, draw_set_mapped_constant_buffer(struct draw_context *draw,

View File

@ -77,6 +77,44 @@ draw_gs_llvm_iface(const struct lp_build_tgsi_gs_iface *iface)
return (const struct draw_gs_llvm_iface *)iface; return (const struct draw_gs_llvm_iface *)iface;
} }
/**
* Create LLVM type for draw_vertex_buffer.
*/
static LLVMTypeRef
create_jit_dvbuffer_type(struct gallivm_state *gallivm,
const char *struct_name)
{
LLVMTargetDataRef target = gallivm->target;
LLVMTypeRef dvbuffer_type;
LLVMTypeRef elem_types[DRAW_JIT_DVBUFFER_NUM_FIELDS];
LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context);
elem_types[DRAW_JIT_DVBUFFER_MAP] =
LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0);
elem_types[DRAW_JIT_DVBUFFER_SIZE] = int32_type;
dvbuffer_type = LLVMStructTypeInContext(gallivm->context, elem_types,
Elements(elem_types), 0);
#if HAVE_LLVM < 0x0300
LLVMAddTypeName(gallivm->module, struct_name, dvbuffer_type);
/* Make sure the target's struct layout cache doesn't return
* stale/invalid data.
*/
LLVMInvalidateStructLayout(gallivm->target, dvbuffer_type);
#endif
LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, map,
target, dvbuffer_type,
DRAW_JIT_DVBUFFER_MAP);
LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, size,
target, dvbuffer_type,
DRAW_JIT_DVBUFFER_SIZE);
return dvbuffer_type;
}
/** /**
* Create LLVM type for struct draw_jit_texture * Create LLVM type for struct draw_jit_texture
*/ */
@ -328,7 +366,8 @@ create_gs_jit_input_type(struct gallivm_state *gallivm)
* Create LLVM type for struct pipe_vertex_buffer * Create LLVM type for struct pipe_vertex_buffer
*/ */
static LLVMTypeRef static LLVMTypeRef
create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name) create_jit_vertex_buffer_type(struct gallivm_state *gallivm,
const char *struct_name)
{ {
LLVMTargetDataRef target = gallivm->target; LLVMTargetDataRef target = gallivm->target;
LLVMTypeRef elem_types[4]; LLVMTypeRef elem_types[4];
@ -337,7 +376,7 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_
elem_types[0] = elem_types[0] =
elem_types[1] = LLVMInt32TypeInContext(gallivm->context); elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
elem_types[2] = elem_types[2] =
elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */ elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
vb_type = LLVMStructTypeInContext(gallivm->context, elem_types, vb_type = LLVMStructTypeInContext(gallivm->context, elem_types,
Elements(elem_types), 0); Elements(elem_types), 0);
@ -422,7 +461,8 @@ static void
create_jit_types(struct draw_llvm_variant *variant) create_jit_types(struct draw_llvm_variant *variant)
{ {
struct gallivm_state *gallivm = variant->gallivm; struct gallivm_state *gallivm = variant->gallivm;
LLVMTypeRef texture_type, sampler_type, context_type, buffer_type, vb_type; LLVMTypeRef texture_type, sampler_type, context_type, buffer_type,
vb_type;
texture_type = create_jit_texture_type(gallivm, "texture"); texture_type = create_jit_texture_type(gallivm, "texture");
sampler_type = create_jit_sampler_type(gallivm, "sampler"); sampler_type = create_jit_sampler_type(gallivm, "sampler");
@ -431,7 +471,7 @@ create_jit_types(struct draw_llvm_variant *variant)
"draw_jit_context"); "draw_jit_context");
variant->context_ptr_type = LLVMPointerType(context_type, 0); variant->context_ptr_type = LLVMPointerType(context_type, 0);
buffer_type = LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0); buffer_type = create_jit_dvbuffer_type(gallivm, "draw_vertex_buffer");
variant->buffer_ptr_type = LLVMPointerType(buffer_type, 0); variant->buffer_ptr_type = LLVMPointerType(buffer_type, 0);
vb_type = create_jit_vertex_buffer_type(gallivm, "pipe_vertex_buffer"); vb_type = create_jit_vertex_buffer_type(gallivm, "pipe_vertex_buffer");
@ -631,7 +671,6 @@ generate_vs(struct draw_llvm_variant *variant,
} }
} }
static void static void
generate_fetch(struct gallivm_state *gallivm, generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef vbuffers_ptr, LLVMValueRef vbuffers_ptr,
@ -641,7 +680,8 @@ generate_fetch(struct gallivm_state *gallivm,
LLVMValueRef index, LLVMValueRef index,
LLVMValueRef instance_id) LLVMValueRef instance_id)
{ {
const struct util_format_description *format_desc = util_format_description(velem->src_format); const struct util_format_description *format_desc =
util_format_description(velem->src_format);
LLVMValueRef zero = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context)); LLVMValueRef zero = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context));
LLVMBuilderRef builder = gallivm->builder; LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef indices = LLVMValueRef indices =
@ -651,7 +691,14 @@ generate_fetch(struct gallivm_state *gallivm,
&indices, 1, ""); &indices, 1, "");
LLVMValueRef vb_stride = draw_jit_vbuffer_stride(gallivm, vbuf); LLVMValueRef vb_stride = draw_jit_vbuffer_stride(gallivm, vbuf);
LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vbuf); LLVMValueRef vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vbuf);
LLVMValueRef map_ptr = draw_jit_dvbuffer_map(gallivm, vbuffer_ptr);
LLVMValueRef buffer_size = draw_jit_dvbuffer_size(gallivm, vbuffer_ptr);
LLVMValueRef stride; LLVMValueRef stride;
LLVMValueRef buffer_overflowed;
LLVMValueRef temp_ptr =
lp_build_alloca(gallivm,
lp_build_vec_type(gallivm, lp_float32_vec4_type()), "");
struct lp_build_if_state if_ctx;
if (velem->instance_divisor) { if (velem->instance_divisor) {
/* array index = instance_id / instance_divisor */ /* array index = instance_id / instance_divisor */
@ -662,8 +709,6 @@ generate_fetch(struct gallivm_state *gallivm,
stride = LLVMBuildMul(builder, vb_stride, index, ""); stride = LLVMBuildMul(builder, vb_stride, index, "");
vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer");
stride = LLVMBuildAdd(builder, stride, stride = LLVMBuildAdd(builder, stride,
vb_buffer_offset, vb_buffer_offset,
""); "");
@ -671,14 +716,36 @@ generate_fetch(struct gallivm_state *gallivm,
lp_build_const_int32(gallivm, velem->src_offset), lp_build_const_int32(gallivm, velem->src_offset),
""); "");
/* lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);*/ buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGE,
vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, ""); stride, buffer_size,
"buffer_overflowed");
/*
lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);
lp_build_print_value(gallivm, " buffer size = ", buffer_size);
lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed);
*/
*res = lp_build_fetch_rgba_aos(gallivm, lp_build_if(&if_ctx, gallivm, buffer_overflowed);
{
LLVMValueRef val =
lp_build_const_vec(gallivm, lp_float32_vec4_type(), 0);
LLVMBuildStore(builder, val, temp_ptr);
}
lp_build_else(&if_ctx);
{
LLVMValueRef val;
map_ptr = LLVMBuildGEP(builder, map_ptr, &stride, 1, "");
val = lp_build_fetch_rgba_aos(gallivm,
format_desc, format_desc,
lp_float32_vec4_type(), lp_float32_vec4_type(),
vbuffer_ptr, map_ptr,
zero, zero, zero); zero, zero, zero);
LLVMBuildStore(builder, val, temp_ptr);
}
lp_build_endif(&if_ctx);
*res = LLVMBuildLoad(builder, temp_ptr, "aos");
} }
static void static void

View File

@ -173,6 +173,18 @@ enum {
#define draw_jit_vbuffer_offset(_gallivm, _ptr) \ #define draw_jit_vbuffer_offset(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, 1, "buffer_offset") lp_build_struct_get(_gallivm, _ptr, 1, "buffer_offset")
enum {
DRAW_JIT_DVBUFFER_MAP = 0,
DRAW_JIT_DVBUFFER_SIZE,
DRAW_JIT_DVBUFFER_NUM_FIELDS /* number of fields above */
};
#define draw_jit_dvbuffer_map(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, DRAW_JIT_DVBUFFER_MAP, "map")
#define draw_jit_dvbuffer_size(_gallivm, _ptr) \
lp_build_struct_get(_gallivm, _ptr, DRAW_JIT_DVBUFFER_SIZE, "size")
/** /**
* This structure is passed directly to the generated geometry shader. * This structure is passed directly to the generated geometry shader.
@ -246,7 +258,7 @@ enum {
typedef int typedef int
(*draw_jit_vert_func)(struct draw_jit_context *context, (*draw_jit_vert_func)(struct draw_jit_context *context,
struct vertex_header *io, struct vertex_header *io,
const char *vbuffers[PIPE_MAX_ATTRIBS], const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS],
unsigned start, unsigned start,
unsigned count, unsigned count,
unsigned stride, unsigned stride,
@ -257,7 +269,7 @@ typedef int
typedef int typedef int
(*draw_jit_vert_func_elts)(struct draw_jit_context *context, (*draw_jit_vert_func_elts)(struct draw_jit_context *context,
struct vertex_header *io, struct vertex_header *io,
const char *vbuffers[PIPE_MAX_ATTRIBS], const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS],
const unsigned *fetch_elts, const unsigned *fetch_elts,
unsigned fetch_count, unsigned fetch_count,
unsigned stride, unsigned stride,

View File

@ -66,6 +66,14 @@ struct tgsi_sampler;
struct draw_pt_front_end; struct draw_pt_front_end;
/**
* Represents the mapped vertex buffer.
*/
struct draw_vertex_buffer {
const void *map;
size_t size;
};
/** /**
* Basic vertex info. * Basic vertex info.
* Carry some useful information around with the vertices in the prim pipe. * Carry some useful information around with the vertices in the prim pipe.
@ -183,7 +191,7 @@ struct draw_context
unsigned max_index; unsigned max_index;
/** vertex arrays */ /** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS]; struct draw_vertex_buffer vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffers (for vertex/geometry shader) */ /** constant buffers (for vertex/geometry shader) */
const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];

View File

@ -282,7 +282,7 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
for (j = 0; j < draw->pt.nr_vertex_elements; j++) { for (j = 0; j < draw->pt.nr_vertex_elements; j++) {
uint buf = draw->pt.vertex_element[j].vertex_buffer_index; uint buf = draw->pt.vertex_element[j].vertex_buffer_index;
ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf].map;
if (draw->pt.vertex_element[j].instance_divisor) { if (draw->pt.vertex_element[j].instance_divisor) {
ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor; ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor;
@ -524,11 +524,12 @@ draw_vbo(struct draw_context *draw,
} }
debug_printf("Buffers:\n"); debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
debug_printf(" %u: stride=%u offset=%u ptr=%p\n", debug_printf(" %u: stride=%u offset=%u size=%d ptr=%p\n",
i, i,
draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].stride,
draw->pt.vertex_buffer[i].buffer_offset, draw->pt.vertex_buffer[i].buffer_offset,
draw->pt.user.vbuffer[i]); draw->pt.user.vbuffer[i].size,
draw->pt.user.vbuffer[i].map);
} }
} }

View File

@ -159,7 +159,7 @@ draw_pt_fetch_run(struct pt_fetch *fetch,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
translate->set_buffer(translate, translate->set_buffer(translate,
i, i,
((char *)draw->pt.user.vbuffer[i] + ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].stride,
draw->pt.max_index); draw->pt.max_index);
@ -186,7 +186,7 @@ draw_pt_fetch_run_linear(struct pt_fetch *fetch,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
translate->set_buffer(translate, translate->set_buffer(translate,
i, i,
((char *)draw->pt.user.vbuffer[i] + ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].stride,
draw->pt.max_index); draw->pt.max_index);

View File

@ -169,7 +169,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
feme->translate->set_buffer(feme->translate, feme->translate->set_buffer(feme->translate,
i, i,
((char *)draw->pt.user.vbuffer[i] + ((char *)draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].stride,
draw->pt.max_index); draw->pt.max_index);

View File

@ -159,7 +159,7 @@ fse_prepare(struct draw_pt_middle_end *middle,
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
fse->active->set_buffer( fse->active, fse->active->set_buffer( fse->active,
i, i,
((const ubyte *) draw->pt.user.vbuffer[i] + ((const ubyte *) draw->pt.user.vbuffer[i].map +
draw->pt.vertex_buffer[i].buffer_offset), draw->pt.vertex_buffer[i].buffer_offset),
draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].stride,
draw->pt.max_index ); draw->pt.max_index );

View File

@ -348,7 +348,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
if (fetch_info->linear) if (fetch_info->linear)
clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context, clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context,
llvm_vert_info.verts, llvm_vert_info.verts,
(const char **)draw->pt.user.vbuffer, draw->pt.user.vbuffer,
fetch_info->start, fetch_info->start,
fetch_info->count, fetch_info->count,
fpme->vertex_size, fpme->vertex_size,
@ -357,7 +357,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
else else
clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
llvm_vert_info.verts, llvm_vert_info.verts,
(const char **)draw->pt.user.vbuffer, draw->pt.user.vbuffer,
fetch_info->elts, fetch_info->elts,
fetch_info->count, fetch_info->count,
fpme->vertex_size, fpme->vertex_size,

View File

@ -71,7 +71,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
const void *buf = i915->vertex_buffers[i].user_buffer; const void *buf = i915->vertex_buffers[i].user_buffer;
if (!buf) if (!buf)
buf = i915_buffer(i915->vertex_buffers[i].buffer)->data; buf = i915_buffer(i915->vertex_buffers[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf); draw_set_mapped_vertex_buffer(draw, i, buf, ~0);
} }
/* /*
@ -106,7 +106,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
* unmap vertex/index buffers * unmap vertex/index buffers
*/ */
for (i = 0; i < i915->nr_vertex_buffers; i++) { for (i = 0; i < i915->nr_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(i915->draw, i, NULL); draw_set_mapped_vertex_buffer(i915->draw, i, NULL, 0);
} }
if (mapped_indices) if (mapped_indices)
draw_set_indexes(draw, NULL, 0); draw_set_indexes(draw, NULL, 0);

View File

@ -68,13 +68,15 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
*/ */
for (i = 0; i < lp->num_vertex_buffers; i++) { for (i = 0; i < lp->num_vertex_buffers; i++) {
const void *buf = lp->vertex_buffer[i].user_buffer; const void *buf = lp->vertex_buffer[i].user_buffer;
size_t size = ~0;
if (!buf) { if (!buf) {
if (!lp->vertex_buffer[i].buffer) { if (!lp->vertex_buffer[i].buffer) {
continue; continue;
} }
buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer); buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
size = lp->vertex_buffer[i].buffer->width0;
} }
draw_set_mapped_vertex_buffer(draw, i, buf); draw_set_mapped_vertex_buffer(draw, i, buf, size);
} }
/* Map index buffer, if present */ /* Map index buffer, if present */
@ -121,7 +123,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
* unmap vertex/index buffers * unmap vertex/index buffers
*/ */
for (i = 0; i < lp->num_vertex_buffers; i++) { for (i = 0; i < lp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL, 0);
} }
if (mapped_indices) { if (mapped_indices) {
draw_set_indexes(draw, NULL, 0); draw_set_indexes(draw, NULL, 0);

View File

@ -412,7 +412,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_READ, &transfer[i]); PIPE_TRANSFER_READ, &transfer[i]);
} }
draw_set_mapped_vertex_buffer(draw, i, map); draw_set_mapped_vertex_buffer(draw, i, map, ~0);
} }
if (info->indexed) { if (info->indexed) {

View File

@ -1821,10 +1821,10 @@ static void r300_set_vertex_buffers_swtcl(struct pipe_context* pipe,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (buffers[i].user_buffer) { if (buffers[i].user_buffer) {
draw_set_mapped_vertex_buffer(r300->draw, start_slot + i, draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,
buffers[i].user_buffer); buffers[i].user_buffer, ~0);
} else if (buffers[i].buffer) { } else if (buffers[i].buffer) {
draw_set_mapped_vertex_buffer(r300->draw, start_slot + i, draw_set_mapped_vertex_buffer(r300->draw, start_slot + i,
r300_resource(buffers[i].buffer)->malloced_buffer); r300_resource(buffers[i].buffer)->malloced_buffer, ~0);
} }
} }
} }

View File

@ -76,13 +76,15 @@ softpipe_draw_vbo(struct pipe_context *pipe,
/* Map vertex buffers */ /* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) { for (i = 0; i < sp->num_vertex_buffers; i++) {
const void *buf = sp->vertex_buffer[i].user_buffer; const void *buf = sp->vertex_buffer[i].user_buffer;
size_t size = ~0;
if (!buf) { if (!buf) {
if (!sp->vertex_buffer[i].buffer) { if (!sp->vertex_buffer[i].buffer) {
continue; continue;
} }
buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data; buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
size = sp->vertex_buffer[i].buffer->width0;
} }
draw_set_mapped_vertex_buffer(draw, i, buf); draw_set_mapped_vertex_buffer(draw, i, buf, size);
} }
/* Map index buffer, if present */ /* Map index buffer, if present */
@ -120,7 +122,7 @@ softpipe_draw_vbo(struct pipe_context *pipe,
/* unmap vertex/index buffers - will cause draw module to flush */ /* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) { for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL, 0);
} }
if (mapped_indices) { if (mapped_indices) {
draw_set_indexes(draw, NULL, 0); draw_set_indexes(draw, NULL, 0);

View File

@ -72,7 +72,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
PIPE_TRANSFER_READ, PIPE_TRANSFER_READ,
&vb_transfer[i]); &vb_transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, map); draw_set_mapped_vertex_buffer(draw, i, map, ~0);
} }
} }
@ -112,7 +112,7 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
for (i = 0; i < svga->curr.num_vertex_buffers; i++) { for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
if (svga->curr.vb[i].buffer) { if (svga->curr.vb[i].buffer) {
pipe_buffer_unmap(&svga->pipe, vb_transfer[i]); pipe_buffer_unmap(&svga->pipe, vb_transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL, 0);
} }
} }

View File

@ -175,7 +175,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
map = pipe_buffer_map(pipe, vbuffers[attr].buffer, map = pipe_buffer_map(pipe, vbuffers[attr].buffer,
PIPE_TRANSFER_READ, PIPE_TRANSFER_READ,
&vb_transfer[attr]); &vb_transfer[attr]);
draw_set_mapped_vertex_buffer(draw, attr, map); draw_set_mapped_vertex_buffer(draw, attr, map,
vbuffers[attr].buffer->width0);
} }
else { else {
vbuffers[attr].buffer = NULL; vbuffers[attr].buffer = NULL;
@ -183,7 +184,8 @@ st_feedback_draw_vbo(struct gl_context *ctx,
vbuffers[attr].buffer_offset = 0; vbuffers[attr].buffer_offset = 0;
velements[attr].src_offset = 0; velements[attr].src_offset = 0;
draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer); draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer,
~0);
} }
/* common-case setup */ /* common-case setup */
@ -260,7 +262,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
for (attr = 0; attr < vp->num_inputs; attr++) { for (attr = 0; attr < vp->num_inputs; attr++) {
if (vb_transfer[attr]) if (vb_transfer[attr])
pipe_buffer_unmap(pipe, vb_transfer[attr]); pipe_buffer_unmap(pipe, vb_transfer[attr]);
draw_set_mapped_vertex_buffer(draw, attr, NULL); draw_set_mapped_vertex_buffer(draw, attr, NULL, 0);
pipe_resource_reference(&vbuffers[attr].buffer, NULL); pipe_resource_reference(&vbuffers[attr].buffer, NULL);
} }
draw_set_vertex_buffers(draw, 0, vp->num_inputs, NULL); draw_set_vertex_buffers(draw, 0, vp->num_inputs, NULL);