From 437ab1d6df7282770ee869180446db36c2dbdfa8 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 24 Apr 2012 15:19:31 +0200 Subject: gallium: add PIPE_CAP_USER_INDEX_BUFFERS and PIPE_CAP_USER_CONSTANT_BUFFERS --- src/gallium/drivers/svga/svga_screen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gallium/drivers/svga/svga_screen.c') diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 0db2dd37fe5..e6933a90b86 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -161,6 +161,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SWIZZLE: return 1; case PIPE_CAP_USER_VERTEX_BUFFERS: + case PIPE_CAP_USER_INDEX_BUFFERS: + case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: -- cgit v1.2.3 From 1b749dc34f8d83cf3dfa863279b1fe2b356d34b2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 24 Apr 2012 17:31:17 +0200 Subject: gallium: add PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT This is required for any serious constant buffer support. Constant buffer offsets on ATI and NVIDIA DX10 and DX11 GPUs must be a multiple of 256. In OpenGL, this can be queried via GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. --- src/gallium/docs/source/screen.rst | 2 ++ src/gallium/drivers/i915/i915_screen.c | 3 +++ src/gallium/drivers/llvmpipe/lp_screen.c | 2 ++ src/gallium/drivers/nv30/nv30_screen.c | 2 ++ src/gallium/drivers/nv50/nv50_screen.c | 2 ++ src/gallium/drivers/nvc0/nvc0_screen.c | 2 ++ src/gallium/drivers/r300/r300_screen.c | 3 +++ src/gallium/drivers/r600/r600_pipe.c | 3 +++ src/gallium/drivers/radeonsi/radeonsi_pipe.c | 3 +++ src/gallium/drivers/softpipe/sp_screen.c | 2 ++ src/gallium/drivers/svga/svga_screen.c | 2 ++ src/gallium/include/pipe/p_defines.h | 3 ++- 12 files changed, 28 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/svga/svga_screen.c') diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index b73c4d25c1d..f6c6f3fd119 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -116,6 +116,8 @@ The integer capabilities: * ``PIPE_CAP_USER_CONSTANT_BUFFERS``: Whether user constant buffers are supported. If not, the state tracker must upload constants which are not in hw resources. +* ``PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT``: Describes the required + alignment of pipe_constant_buffer::buffer_offset. diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 1b3c4be12c7..00468602c09 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -208,6 +208,9 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: return 0; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; + /* Features we can lie about (boolean caps). */ case PIPE_CAP_OCCLUSION_QUERY: return is->debug.lie ? 1 : 0; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 1a3e2bdac5a..40037a544bf 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -163,6 +163,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; default: return 0; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 2078c1995b0..26969ef938b 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -82,6 +82,8 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; /* nv4x capabilities */ case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_NPOT_TEXTURES: diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ad40cb49eb8..20a135b6039 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -154,6 +154,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 256; case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 7e6c1d40913..366e6fbb832 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -144,6 +144,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 256; case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index ff9d3952e7e..f84f3e5c58e 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -110,6 +110,9 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; + case PIPE_CAP_GLSL_FEATURE_LEVEL: return 120; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 1a8dbdb3de1..11f0fde177e 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -407,6 +407,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 256; + case PIPE_CAP_GLSL_FEATURE_LEVEL: return rscreen->glsl_feature_level; diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c index e2f438be142..aec5af277c5 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c @@ -349,6 +349,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 256; + case PIPE_CAP_GLSL_FEATURE_LEVEL: return debug_get_bool_option("R600_GLSL130", FALSE) ? 130 : 120; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index ec8acebf913..cdc78676655 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -142,6 +142,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; default: return 0; } diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index e6933a90b86..51c85838fe2 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -164,6 +164,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: + return 16; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: { diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 4d75dec3c25..398cb98248c 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -478,7 +478,8 @@ enum pipe_cap { PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY = 66, PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY = 67, PIPE_CAP_USER_INDEX_BUFFERS = 68, - PIPE_CAP_USER_CONSTANT_BUFFERS = 69 + PIPE_CAP_USER_CONSTANT_BUFFERS = 69, + PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 70 }; /** -- cgit v1.2.3 From 4552fd50d959ab99546cfa994f8ba5bdf5d66bc7 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 24 Apr 2012 20:58:47 +0200 Subject: gallium: add void *user_buffer in pipe_vertex_buffer This reduces CPU overhead in st_draw_vbo and removes a lot of unnecessary code in that function which was required only to comply with the gallium interface, but wasn't any useful really. Adapted drivers: i915, llvmpipe, r300, softpipe. No changes required in: r600, radeonsi. User vertex buffers have been disabled in nv30, nv50, nvc0 and svga to keep things working. --- src/gallium/auxiliary/draw/draw_llvm.c | 5 +- src/gallium/auxiliary/util/u_draw.c | 4 + src/gallium/auxiliary/util/u_vbuf.c | 17 ++- src/gallium/drivers/i915/i915_state.c | 4 +- src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 4 +- src/gallium/drivers/nv30/nv30_draw.c | 9 +- src/gallium/drivers/nv30/nv30_screen.c | 3 +- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/drivers/nvc0/nvc0_screen.c | 2 +- src/gallium/drivers/r300/r300_render.c | 8 +- src/gallium/drivers/softpipe/sp_draw_arrays.c | 4 +- src/gallium/drivers/svga/svga_screen.c | 1 + src/gallium/include/pipe/p_state.h | 1 + src/mesa/state_tracker/st_context.c | 5 - src/mesa/state_tracker/st_context.h | 12 --- src/mesa/state_tracker/st_draw.c | 142 +++----------------------- src/mesa/state_tracker/st_draw_feedback.c | 32 +++--- 17 files changed, 73 insertions(+), 182 deletions(-) (limited to 'src/gallium/drivers/svga/svga_screen.c') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 620d6dc8de3..7bf9d5e5d7a 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -236,12 +236,13 @@ static LLVMTypeRef create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name) { LLVMTargetDataRef target = gallivm->target; - LLVMTypeRef elem_types[3]; + LLVMTypeRef elem_types[4]; LLVMTypeRef vb_type; elem_types[0] = elem_types[1] = LLVMInt32TypeInContext(gallivm->context); - elem_types[2] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */ + elem_types[2] = + elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */ #if HAVE_LLVM >= 0x0300 vb_type = LLVMStructCreateNamed(gallivm->context, struct_name); diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c index d16575b7340..1f3eb887959 100644 --- a/src/gallium/auxiliary/util/u_draw.c +++ b/src/gallium/auxiliary/util/u_draw.c @@ -62,6 +62,10 @@ util_draw_max_index( const struct util_format_description *format_desc; unsigned format_size; + if (!buffer->buffer) { + continue; + } + assert(buffer->buffer->height0 == 1); assert(buffer->buffer->depth0 == 1); buffer_size = buffer->buffer->width0; diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 401c8a4a850..e60378c31c7 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -277,8 +277,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, unsigned offset = vb->buffer_offset + vb->stride * start_vertex; uint8_t *map; - if (vb->buffer->user_ptr) { - map = vb->buffer->user_ptr + offset; + if (vb->user_buffer) { + map = (uint8_t*)vb->user_buffer + offset; } else { unsigned size = vb->stride ? num_vertices * vb->stride : sizeof(double)*4; @@ -713,6 +713,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i]; 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; @@ -721,7 +722,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, mgr->nonzero_stride_vb_mask |= 1 << i; } - if (!vb->buffer) { + if (!vb->buffer && !vb->user_buffer) { pipe_resource_reference(&real_vb->buffer, NULL); continue; } @@ -733,7 +734,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, continue; } - if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) { + if (!mgr->caps.user_vertex_buffers && vb->user_buffer) { mgr->user_vb_mask |= 1 << i; pipe_resource_reference(&real_vb->buffer, NULL); continue; @@ -798,9 +799,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, continue; } - assert(vb->buffer); - - if (!vb->buffer->user_ptr) { + if (!vb->user_buffer) { continue; } @@ -837,7 +836,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, for (i = 0; i < nr_vbufs; i++) { unsigned start, end = end_offset[i]; struct pipe_vertex_buffer *real_vb; - uint8_t *ptr; + const uint8_t *ptr; if (!end) { continue; @@ -847,7 +846,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr, assert(start < end); real_vb = &mgr->real_vertex_buffer[i]; - ptr = mgr->vertex_buffer[i].buffer->user_ptr; + ptr = mgr->vertex_buffer[i].user_buffer; u_upload_data(mgr->uploader, start, end - start, ptr + start, &real_vb->buffer_offset, &real_vb->buffer); diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 40cef5a9d86..d38d1ede5d6 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -983,7 +983,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, /* map new */ for (i = 0; i < count; i++) { - void *buf = i915_buffer(buffers[i].buffer)->data; + const void *buf = buffers[i].user_buffer; + if (!buf) + buf = i915_buffer(buffers[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } } diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 239a596bce0..5a4a9bd6801 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -67,7 +67,9 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { - void *buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer); + const void *buf = lp->vertex_buffer[i].user_buffer; + if (!buf) + buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, buf); } diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c index 61e324606f2..c6907fa806f 100644 --- a/src/gallium/drivers/nv30/nv30_draw.c +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -366,7 +366,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct nv30_context *nv30 = nv30_context(pipe); struct draw_context *draw = nv30->draw; - struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *transferi = NULL; int i; @@ -403,7 +403,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } for (i = 0; i < nv30->num_vtxbufs; i++) { - void *map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer, + const void *map = nv30->vtxbuf[i].user_buffer; + if (!map) + 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); @@ -425,7 +427,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (info->indexed) pipe_buffer_unmap(pipe, transferi); for (i = 0; i < nv30->num_vtxbufs; i++) - pipe_buffer_unmap(pipe, transfer[i]); + if (transfer[i]) + pipe_buffer_unmap(pipe, transfer[i]); nv30->draw_dirty = 0; nv30_state_release(nv30); diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 26969ef938b..5d550d13b5e 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -78,10 +78,11 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - case PIPE_CAP_USER_VERTEX_BUFFERS: case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_USER_VERTEX_BUFFERS: + return 0; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: return 16; /* nv4x capabilities */ diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 20a135b6039..61925ac23c9 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -149,8 +149,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: - return 0; /* state trackers will know better */ case PIPE_CAP_USER_VERTEX_BUFFERS: + return 0; /* state trackers will know better */ case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 366e6fbb832..846b21ad6c9 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -139,8 +139,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: - return 0; /* state trackers will know better */ case PIPE_CAP_USER_VERTEX_BUFFERS: + return 0; /* state trackers will know better */ case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 99302dc8b0a..76165f51a1b 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -873,7 +873,10 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, indexed ? 256 : 6); for (i = 0; i < r300->nr_vertex_buffers; i++) { - if (r300->vertex_buffer[i].buffer) { + if (r300->vertex_buffer[i].user_buffer) { + draw_set_mapped_vertex_buffer(r300->draw, i, + r300->vertex_buffer[i].user_buffer); + } else if (r300->vertex_buffer[i].buffer) { void *buf = pipe_buffer_map(pipe, r300->vertex_buffer[i].buffer, PIPE_TRANSFER_READ | @@ -899,7 +902,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, for (i = 0; i < r300->nr_vertex_buffers; i++) { if (r300->vertex_buffer[i].buffer) { - pipe_buffer_unmap(pipe, vb_transfer[i]); + if (vb_transfer[i]) + pipe_buffer_unmap(pipe, vb_transfer[i]); draw_set_mapped_vertex_buffer(r300->draw, i, NULL); } } diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 27004071f02..f2ffe590f85 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -77,7 +77,9 @@ softpipe_draw_vbo(struct pipe_context *pipe, /* Map vertex buffers */ for (i = 0; i < sp->num_vertex_buffers; i++) { - void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data; + const void *buf = sp->vertex_buffer[i].user_buffer; + if (!buf) + buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 51c85838fe2..f37d1724657 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -161,6 +161,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SWIZZLE: return 1; case PIPE_CAP_USER_VERTEX_BUFFERS: + return 0; case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 42510a685bf..f281791eead 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -447,6 +447,7 @@ struct pipe_vertex_buffer unsigned stride; /**< stride to same attrib in next vertex, in bytes */ unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */ struct pipe_resource *buffer; /**< the actual buffer */ + const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */ }; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index a804e77af8b..d7124087b11 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -263,11 +263,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); } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 4e40d533e05..8b8d69e995a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -190,18 +190,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 fa7c18895c7..09f41abc13b 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -403,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, @@ -465,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); - } } /* @@ -485,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 */ @@ -498,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; @@ -537,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. @@ -566,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 */ @@ -896,9 +843,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; @@ -906,8 +851,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; @@ -915,18 +858,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; } @@ -937,8 +874,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; } @@ -949,14 +885,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; } @@ -982,7 +910,6 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; unsigned i, num_instances = 1; - unsigned max_index_plus_base; GLboolean new_array = st->dirty.st && (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; @@ -991,8 +918,6 @@ st_draw_vbo(struct gl_context *ctx, assert(ctx->NewState == 0x0); 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)) @@ -1001,16 +926,7 @@ st_draw_vbo(struct gl_context *ctx, 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. */ @@ -1022,9 +938,6 @@ st_draw_vbo(struct gl_context *ctx, 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. */ @@ -1041,8 +954,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; } @@ -1057,26 +969,6 @@ 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); - } - } - } - util_draw_init_info(&info); if (ib) { setup_index_buffer(st, ib, &ibuffer); diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index a559b733ac2..ee19898b3ea 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -108,7 +108,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; GLuint attr, i; const GLubyte *low_addr = NULL; @@ -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); } -- cgit v1.2.3 From bf469f4edc60bd1c5fd770cb231b8d5ab801427f Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 24 Apr 2012 21:14:44 +0200 Subject: gallium: add void *user_buffer in pipe_index_buffer Adapted drivers: i915, llvmpipe, r300, r600, radeonsi, softpipe. User index buffers have been disabled in nv30, nv50, nvc0 and svga to keep things working. --- src/gallium/auxiliary/util/u_index_modify.c | 83 +++++++++++++++--------- src/gallium/auxiliary/util/u_index_modify.h | 16 +++-- src/gallium/auxiliary/util/u_vbuf.c | 15 ++--- src/gallium/drivers/i915/i915_context.c | 9 ++- src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 9 ++- src/gallium/drivers/nv30/nv30_draw.c | 6 +- src/gallium/drivers/nv30/nv30_screen.c | 2 +- src/gallium/drivers/nv50/nv50_screen.c | 2 +- src/gallium/drivers/nvc0/nvc0_screen.c | 2 +- src/gallium/drivers/r300/r300_context.h | 3 +- src/gallium/drivers/r300/r300_render.c | 47 ++++++++------ src/gallium/drivers/r300/r300_render_translate.c | 25 ++++--- src/gallium/drivers/r300/r300_screen_buffer.c | 2 +- src/gallium/drivers/r300/r300_screen_buffer.h | 2 +- src/gallium/drivers/r600/r600_state_common.c | 6 +- src/gallium/drivers/r600/r600_translate.c | 2 +- src/gallium/drivers/radeonsi/r600_buffer.c | 4 +- src/gallium/drivers/radeonsi/r600_state_common.c | 2 +- src/gallium/drivers/radeonsi/r600_translate.c | 3 +- src/gallium/drivers/softpipe/sp_draw_arrays.c | 9 ++- src/gallium/drivers/svga/svga_screen.c | 2 +- src/gallium/include/pipe/p_state.h | 1 + src/mesa/state_tracker/st_draw.c | 17 ++--- 23 files changed, 151 insertions(+), 118 deletions(-) (limited to 'src/gallium/drivers/svga/svga_screen.c') diff --git a/src/gallium/auxiliary/util/u_index_modify.c b/src/gallium/auxiliary/util/u_index_modify.c index d0a28b5fdfa..5e3fd463eb4 100644 --- a/src/gallium/auxiliary/util/u_index_modify.c +++ b/src/gallium/auxiliary/util/u_index_modify.c @@ -27,21 +27,25 @@ /* Ubyte indices. */ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out) { - struct pipe_transfer *src_transfer; - unsigned char *in_map; + struct pipe_transfer *src_transfer = NULL; + const unsigned char *in_map; unsigned short *out_map = out; unsigned i; - in_map = pipe_buffer_map(context, elts, - PIPE_TRANSFER_READ | - PIPE_TRANSFER_UNSYNCHRONIZED, - &src_transfer); + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &src_transfer); + } in_map += start; for (i = 0; i < count; i++) { @@ -50,11 +54,13 @@ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, out_map++; } - pipe_buffer_unmap(context, src_transfer); + if (src_transfer) + pipe_buffer_unmap(context, src_transfer); } void util_shorten_ubyte_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count) @@ -70,31 +76,36 @@ void util_shorten_ubyte_elts(struct pipe_context *context, out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); - util_shorten_ubyte_elts_to_userptr(context, *elts, index_bias, + util_shorten_ubyte_elts_to_userptr(context, ib, index_bias, start, count, out_map); pipe_buffer_unmap(context, dst_transfer); - *elts = new_elts; + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; } /* Ushort indices. */ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out) { struct pipe_transfer *in_transfer = NULL; - unsigned short *in_map; + const unsigned short *in_map; unsigned short *out_map = out; unsigned i; - in_map = pipe_buffer_map(context, elts, - PIPE_TRANSFER_READ | - PIPE_TRANSFER_UNSYNCHRONIZED, - &in_transfer); + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &in_transfer); + } in_map += start; for (i = 0; i < count; i++) { @@ -103,11 +114,13 @@ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, out_map++; } - pipe_buffer_unmap(context, in_transfer); + if (in_transfer) + pipe_buffer_unmap(context, in_transfer); } void util_rebuild_ushort_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count) { @@ -122,31 +135,36 @@ void util_rebuild_ushort_elts(struct pipe_context *context, out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &out_transfer); - util_rebuild_ushort_elts_to_userptr(context, *elts, index_bias, + util_rebuild_ushort_elts_to_userptr(context, ib, index_bias, start, count, out_map); pipe_buffer_unmap(context, out_transfer); - *elts = new_elts; + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; } /* Uint indices. */ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out) { struct pipe_transfer *in_transfer = NULL; - unsigned int *in_map; + const unsigned int *in_map; unsigned int *out_map = out; unsigned i; - in_map = pipe_buffer_map(context, elts, - PIPE_TRANSFER_READ | - PIPE_TRANSFER_UNSYNCHRONIZED, - &in_transfer); + if (ib->user_buffer) { + in_map = ib->user_buffer; + } else { + in_map = pipe_buffer_map(context, ib->buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, + &in_transfer); + } in_map += start; for (i = 0; i < count; i++) { @@ -155,11 +173,13 @@ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, out_map++; } - pipe_buffer_unmap(context, in_transfer); + if (in_transfer) + pipe_buffer_unmap(context, in_transfer); } void util_rebuild_uint_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count) { @@ -174,9 +194,10 @@ void util_rebuild_uint_elts(struct pipe_context *context, out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &out_transfer); - util_rebuild_uint_elts_to_userptr(context, *elts, index_bias, + util_rebuild_uint_elts_to_userptr(context, ib, index_bias, start, count, out_map); pipe_buffer_unmap(context, out_transfer); - *elts = new_elts; + pipe_resource_reference(out_buf, NULL); + *out_buf = new_elts; } diff --git a/src/gallium/auxiliary/util/u_index_modify.h b/src/gallium/auxiliary/util/u_index_modify.h index 1e9de3dfac8..6afce50b984 100644 --- a/src/gallium/auxiliary/util/u_index_modify.h +++ b/src/gallium/auxiliary/util/u_index_modify.h @@ -25,16 +25,18 @@ struct pipe_context; struct pipe_resource; +struct pipe_index_buffer; void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out); void util_shorten_ubyte_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count); @@ -42,26 +44,28 @@ void util_shorten_ubyte_elts(struct pipe_context *context, void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out); void util_rebuild_ushort_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count); void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, - struct pipe_resource *elts, + struct pipe_index_buffer *ib, int index_bias, unsigned start, unsigned count, void *out); void util_rebuild_uint_elts(struct pipe_context *context, - struct pipe_resource **elts, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buf, int index_bias, unsigned start, unsigned count); diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index e60378c31c7..400fada1830 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -307,10 +307,10 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, unsigned offset = ib->offset + start_index * ib->index_size; uint8_t *map; - assert(ib->buffer && ib->index_size); + assert((ib->buffer || ib->user_buffer) && ib->index_size); - if (ib->buffer->user_ptr) { - map = ib->buffer->user_ptr + offset; + if (ib->user_buffer) { + map = (uint8_t*)ib->user_buffer + offset; } else { map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset, num_indices * ib->index_size, @@ -760,11 +760,10 @@ void u_vbuf_set_index_buffer(struct u_vbuf *mgr, { struct pipe_context *pipe = mgr->pipe; - if (ib && ib->buffer) { + if (ib) { assert(ib->offset % ib->index_size == 0); pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); - mgr->index_buffer.offset = ib->offset; - mgr->index_buffer.index_size = ib->index_size; + memcpy(&mgr->index_buffer, ib, sizeof(*ib)); } else { pipe_resource_reference(&mgr->index_buffer.buffer, NULL); } @@ -887,8 +886,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, unsigned i; unsigned restart_index = info->restart_index; - if (ib->buffer->user_ptr) { - indices = ib->buffer->user_ptr + + if (ib->user_buffer) { + indices = (uint8_t*)ib->user_buffer + ib->offset + info->start * ib->index_size; } else { indices = pipe_buffer_map_range(pipe, ib->buffer, diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 052a059c268..f3c7b30527c 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -53,7 +53,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; - void *mapped_indices = NULL; + const void *mapped_indices = NULL; /* @@ -67,8 +67,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* * Map index buffer, if present */ - if (info->indexed && i915->index_buffer.buffer) - mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; + if (info->indexed) { + mapped_indices = i915->index_buffer.user_buffer; + if (!mapped_indices) + mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; + } draw_set_mapped_index_buffer(draw, mapped_indices); if (i915->constants[PIPE_SHADER_VERTEX]) diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 5a4a9bd6801..225b80e3dfb 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -54,7 +54,7 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; - void *mapped_indices = NULL; + const void *mapped_indices = NULL; unsigned i; if (!llvmpipe_check_render_cond(lp)) @@ -74,8 +74,11 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } /* Map index buffer, if present */ - if (info->indexed && lp->index_buffer.buffer) - mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer); + if (info->indexed) { + mapped_indices = lp->index_buffer.user_buffer; + if (!mapped_indices) + mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer); + } draw_set_mapped_index_buffer(draw, mapped_indices); diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c index c6907fa806f..29e63953838 100644 --- a/src/gallium/drivers/nv30/nv30_draw.c +++ b/src/gallium/drivers/nv30/nv30_draw.c @@ -412,7 +412,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } if (info->indexed) { - void *map = pipe_buffer_map(pipe, nv30->idxbuf.buffer, + const void *map = nv30->idxbuf.user_buffer; + if (!map) + pipe_buffer_map(pipe, nv30->idxbuf.buffer, PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_READ, &transferi); draw_set_index_buffer(draw, &nv30->idxbuf); @@ -424,7 +426,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) draw_vbo(draw, info); draw_flush(draw); - if (info->indexed) + if (info->indexed && transferi) pipe_buffer_unmap(pipe, transferi); for (i = 0; i < nv30->num_vtxbufs; i++) if (transfer[i]) diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 5d550d13b5e..c3e50a58316 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -78,9 +78,9 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; + case PIPE_CAP_USER_INDEX_BUFFERS: case PIPE_CAP_USER_VERTEX_BUFFERS: return 0; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 61925ac23c9..a6dfbedf299 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -150,8 +150,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: case PIPE_CAP_USER_VERTEX_BUFFERS: - return 0; /* state trackers will know better */ case PIPE_CAP_USER_INDEX_BUFFERS: + return 0; /* state trackers will know better */ case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index 846b21ad6c9..5d6befd45b7 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -140,8 +140,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: case PIPE_CAP_USER_VERTEX_BUFFERS: - return 0; /* state trackers will know better */ case PIPE_CAP_USER_INDEX_BUFFERS: + return 0; /* state trackers will know better */ case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index ca57a5c7857..b58f514c358 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -692,7 +692,8 @@ void r300_stop_query(struct r300_context *r300); /* r300_render_translate.c */ void r300_translate_index_buffer(struct r300_context *r300, - struct pipe_resource **index_buffer, + struct pipe_index_buffer *ib, + struct pipe_resource **out_index_buffer, unsigned *index_size, unsigned index_offset, unsigned *start, unsigned count); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 76165f51a1b..56f480d3358 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -508,9 +508,9 @@ static void r300_emit_draw_elements(struct r300_context *r300, static void r300_draw_elements_immediate(struct r300_context *r300, const struct pipe_draw_info *info) { - uint8_t *ptr1; - uint16_t *ptr2; - uint32_t *ptr4; + const uint8_t *ptr1; + const uint16_t *ptr2; + const uint32_t *ptr4; unsigned index_size = r300->index_buffer.index_size; unsigned i, count_dwords = index_size == 4 ? info->count : (info->count + 1) / 2; @@ -529,7 +529,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300, switch (index_size) { case 1: - ptr1 = r300->index_buffer.buffer->user_ptr; + ptr1 = (uint8_t*)r300->index_buffer.user_buffer; ptr1 += info->start; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | @@ -553,7 +553,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300, break; case 2: - ptr2 = (uint16_t*)r300->index_buffer.buffer->user_ptr; + ptr2 = (uint16_t*)r300->index_buffer.user_buffer; ptr2 += info->start; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | @@ -572,7 +572,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300, break; case 4: - ptr4 = (uint32_t*)r300->index_buffer.buffer->user_ptr; + ptr4 = (uint32_t*)r300->index_buffer.user_buffer; ptr4 += info->start; OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | @@ -606,15 +606,15 @@ static void r300_draw_elements(struct r300_context *r300, uint16_t indices3[3]; if (info->index_bias && !r300->screen->caps.is_r500) { - r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset); + r300_split_index_bias(r300, info->index_bias, &buffer_offset, + &index_offset); } - r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset, - &start, count); + r300_translate_index_buffer(r300, &r300->index_buffer, &indexBuffer, + &indexSize, index_offset, &start, count); /* Fallback for misaligned ushort indices. */ - if (indexSize == 2 && (start & 1) && - !indexBuffer->user_ptr) { + if (indexSize == 2 && (start & 1) && indexBuffer) { /* If we got here, then orgIndexBuffer == indexBuffer. */ uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->cs_buf, r300->cs, @@ -632,10 +632,10 @@ static void r300_draw_elements(struct r300_context *r300, } r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->cs_buf); } else { - if (indexBuffer->user_ptr) + if (r300->index_buffer.user_buffer) r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count, - indexBuffer->user_ptr); + r300->index_buffer.user_buffer); } /* 19 dwords for emit_draw_elements. Give up if the function fails. */ @@ -795,7 +795,7 @@ static void r300_draw_vbo(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; - info.indexed = info.indexed && r300->index_buffer.buffer; + info.indexed = info.indexed; if (r300->skip_rendering || !u_trim_pipe_prim(info.mode, &info.count)) { @@ -824,7 +824,7 @@ static void r300_draw_vbo(struct pipe_context* pipe, if (info.instance_count <= 1) { if (info.count <= 8 && - r300->index_buffer.buffer->user_ptr) { + r300->index_buffer.user_buffer) { r300_draw_elements_immediate(r300, &info); } else { r300_draw_elements(r300, &info, -1); @@ -858,8 +858,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; struct pipe_transfer *ib_transfer = NULL; int i; - void *indices = NULL; - boolean indexed = info->indexed && r300->index_buffer.buffer; + const void *indices = NULL; + boolean indexed = info->indexed; if (r300->skip_rendering) { return; @@ -887,9 +887,13 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, } if (indexed) { - indices = pipe_buffer_map(pipe, r300->index_buffer.buffer, - PIPE_TRANSFER_READ | - PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer); + if (r300->index_buffer.user_buffer) { + indices = r300->index_buffer.user_buffer; + } else { + indices = pipe_buffer_map(pipe, r300->index_buffer.buffer, + PIPE_TRANSFER_READ | + PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer); + } } draw_set_mapped_index_buffer(r300->draw, indices); @@ -909,7 +913,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, } if (indexed) { - pipe_buffer_unmap(pipe, ib_transfer); + if (ib_transfer) + pipe_buffer_unmap(pipe, ib_transfer); draw_set_mapped_index_buffer(r300->draw, NULL); } } diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c index 022e8a7fc70..caeeec05909 100644 --- a/src/gallium/drivers/r300/r300_render_translate.c +++ b/src/gallium/drivers/r300/r300_render_translate.c @@ -26,55 +26,52 @@ void r300_translate_index_buffer(struct r300_context *r300, - struct pipe_resource **index_buffer, + struct pipe_index_buffer *ib, + struct pipe_resource **out_buffer, unsigned *index_size, unsigned index_offset, unsigned *start, unsigned count) { - struct pipe_resource *out_buffer = NULL; unsigned out_offset; void *ptr; switch (*index_size) { case 1: + *out_buffer = NULL; u_upload_alloc(r300->uploader, 0, count * 2, - &out_offset, &out_buffer, &ptr); + &out_offset, out_buffer, &ptr); util_shorten_ubyte_elts_to_userptr( - &r300->context, *index_buffer, index_offset, + &r300->context, ib, index_offset, *start, count, ptr); - *index_buffer = NULL; - pipe_resource_reference(index_buffer, out_buffer); *index_size = 2; *start = out_offset / 2; break; case 2: if (index_offset) { + *out_buffer = NULL; u_upload_alloc(r300->uploader, 0, count * 2, - &out_offset, &out_buffer, &ptr); + &out_offset, out_buffer, &ptr); - util_rebuild_ushort_elts_to_userptr(&r300->context, *index_buffer, + util_rebuild_ushort_elts_to_userptr(&r300->context, ib, index_offset, *start, count, ptr); - *index_buffer = NULL; - pipe_resource_reference(index_buffer, out_buffer); *start = out_offset / 2; } break; case 4: if (index_offset) { + *out_buffer = NULL; u_upload_alloc(r300->uploader, 0, count * 4, - &out_offset, &out_buffer, &ptr); + &out_offset, out_buffer, &ptr); - util_rebuild_uint_elts_to_userptr(&r300->context, *index_buffer, + util_rebuild_uint_elts_to_userptr(&r300->context, ib, index_offset, *start, count, ptr); - *index_buffer = NULL; - pipe_resource_reference(index_buffer, out_buffer); *start = out_offset / 4; } break; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index d05c9149287..b7deb5f49a5 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -35,7 +35,7 @@ void r300_upload_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, unsigned index_size, unsigned *start, - unsigned count, uint8_t *ptr) + unsigned count, const uint8_t *ptr) { unsigned index_offset; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h index 360ec509cc5..482b6e424ed 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -39,7 +39,7 @@ void r300_upload_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, unsigned index_size, unsigned *start, - unsigned count, uint8_t *ptr); + unsigned count, const uint8_t *ptr); struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 6f888df6a30..9e1f016f294 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -751,7 +751,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) uint8_t *ptr; if ((!info.count && (info.indexed || !info.count_from_stream_output)) || - (info.indexed && !rctx->index_buffer.buffer) || !r600_conv_pipe_prim(info.mode, &prim)) { assert(0); return; @@ -767,14 +766,15 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) if (info.indexed) { /* Initialize the index buffer struct. */ pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer); + ib.user_buffer = rctx->index_buffer.user_buffer; ib.index_size = rctx->index_buffer.index_size; ib.offset = rctx->index_buffer.offset + info.start * ib.index_size; /* Translate or upload, if needed. */ r600_translate_index_buffer(rctx, &ib, info.count); - ptr = ib.buffer->user_ptr; - if (ptr) { + ptr = (uint8_t*)ib.user_buffer; + if (!ib.buffer && ptr) { u_upload_data(rctx->uploader, 0, info.count * ib.index_size, ptr, &ib.offset, &ib.buffer); } diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c index af3b8cad3aa..c054c865e02 100644 --- a/src/gallium/drivers/r600/r600_translate.c +++ b/src/gallium/drivers/r600/r600_translate.c @@ -42,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600, &out_offset, &out_buffer, &ptr); util_shorten_ubyte_elts_to_userptr( - &r600->context, ib->buffer, 0, ib->offset, count, ptr); + &r600->context, ib, 0, ib->offset, count, ptr); pipe_resource_reference(&ib->buffer, NULL); ib->buffer = out_buffer; diff --git a/src/gallium/drivers/radeonsi/r600_buffer.c b/src/gallium/drivers/radeonsi/r600_buffer.c index 912c4ebcdc9..7e8e2ca6887 100644 --- a/src/gallium/drivers/radeonsi/r600_buffer.c +++ b/src/gallium/drivers/radeonsi/r600_buffer.c @@ -211,10 +211,8 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, void r600_upload_index_buffer(struct r600_context *rctx, struct pipe_index_buffer *ib, unsigned count) { - struct r600_resource *rbuffer = r600_resource(ib->buffer); - u_upload_data(rctx->uploader, 0, count * ib->index_size, - rbuffer->b.b.user_ptr, &ib->offset, &ib->buffer); + ib->user_buffer, &ib->offset, &ib->buffer); } void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer, diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c index 1970b52312d..05a201ce3bc 100644 --- a/src/gallium/drivers/radeonsi/r600_state_common.c +++ b/src/gallium/drivers/radeonsi/r600_state_common.c @@ -731,7 +731,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) /* Translate or upload, if needed. */ r600_translate_index_buffer(rctx, &ib, info.count); - if (ib.buffer->user_ptr) { + if (ib.user_buffer) { r600_upload_index_buffer(rctx, &ib, info.count); } diff --git a/src/gallium/drivers/radeonsi/r600_translate.c b/src/gallium/drivers/radeonsi/r600_translate.c index 985f1f6f8dc..8633d770d10 100644 --- a/src/gallium/drivers/radeonsi/r600_translate.c +++ b/src/gallium/drivers/radeonsi/r600_translate.c @@ -24,7 +24,6 @@ */ #include "util/u_index_modify.h" -#include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "radeonsi_pipe.h" @@ -43,7 +42,7 @@ void r600_translate_index_buffer(struct r600_context *r600, &out_offset, &out_buffer, &ptr); util_shorten_ubyte_elts_to_userptr( - &r600->context, ib->buffer, 0, ib->offset, count, ptr); + &r600->context, ib, 0, ib->offset, count, ptr); pipe_resource_reference(&ib->buffer, NULL); ib->buffer = out_buffer; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index f2ffe590f85..7a2274565d5 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -61,7 +61,7 @@ softpipe_draw_vbo(struct pipe_context *pipe, { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; - void *mapped_indices = NULL; + const void *mapped_indices = NULL; unsigned i; if (!softpipe_check_render_cond(sp)) @@ -84,8 +84,11 @@ softpipe_draw_vbo(struct pipe_context *pipe, } /* Map index buffer, if present */ - if (info->indexed && sp->index_buffer.buffer) - mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data; + if (info->indexed) { + mapped_indices = sp->index_buffer.user_buffer; + if (!mapped_indices) + mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data; + } draw_set_mapped_index_buffer(draw, mapped_indices); diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index f37d1724657..ac2d35e5ea4 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -161,8 +161,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SWIZZLE: return 1; case PIPE_CAP_USER_VERTEX_BUFFERS: - return 0; case PIPE_CAP_USER_INDEX_BUFFERS: + return 0; case PIPE_CAP_USER_CONSTANT_BUFFERS: return 1; case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index f281791eead..ceb6c6b7ef1 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -517,6 +517,7 @@ struct pipe_index_buffer unsigned index_size; /**< size of an index, in bytes */ unsigned offset; /**< offset to start of data in buffer, in bytes */ struct pipe_resource *buffer; /**< the actual buffer */ + const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */ }; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 09f41abc13b..3789083b36b 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -581,7 +581,6 @@ setup_index_buffer(struct st_context *st, const struct _mesa_index_buffer *ib, struct pipe_index_buffer *ibuffer) { - struct pipe_context *pipe = st->pipe; struct gl_buffer_object *bufobj = ib->obj; ibuffer->index_size = vbo_sizeof_ib_type(ib->type); @@ -589,8 +588,7 @@ setup_index_buffer(struct st_context *st, /* get/create the index buffer object */ if (_mesa_is_bufferobj(bufobj)) { /* indices are in a real VBO */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - pipe_resource_reference(&ibuffer->buffer, stobj->buffer); + ibuffer->buffer = st_buffer_object(bufobj)->buffer; ibuffer->offset = pointer_to_offset(ib->ptr); } else if (st->indexbuf_uploader) { @@ -599,10 +597,7 @@ setup_index_buffer(struct st_context *st, } else { /* indices 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); + ibuffer->user_buffer = ib->ptr; } cso_set_index_buffer(st->cso_context, ibuffer); @@ -760,10 +755,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; @@ -1021,7 +1016,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); + } } -- cgit v1.2.3