diff options
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 6 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 99 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.h | 16 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 4 |
10 files changed, 122 insertions, 31 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 6caa62ab31b..4eb1919b871 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -364,9 +364,11 @@ draw_set_vertex_elements(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) { - draw->pt.user.vbuffer[attr] = buffer; + draw->pt.user.vbuffer[attr].map = buffer; + draw->pt.user.vbuffer[attr].size = size; } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 94fac880c68..c7a40a1b1a2 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -215,7 +215,8 @@ void draw_set_indexes(struct draw_context *draw, const void *elements, unsigned elem_size); void draw_set_mapped_vertex_buffer(struct draw_context *draw, - unsigned attr, const void *buffer); + unsigned attr, const void *buffer, + size_t size); void draw_set_mapped_constant_buffer(struct draw_context *draw, diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 8e2ab1e3006..24b7be31362 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -78,6 +78,44 @@ draw_gs_llvm_iface(const struct lp_build_tgsi_gs_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 */ static LLVMTypeRef @@ -328,7 +366,8 @@ create_gs_jit_input_type(struct gallivm_state *gallivm) * Create LLVM type for struct pipe_vertex_buffer */ 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; 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[1] = LLVMInt32TypeInContext(gallivm->context); 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, Elements(elem_types), 0); @@ -422,7 +461,8 @@ static void create_jit_types(struct draw_llvm_variant *variant) { 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"); sampler_type = create_jit_sampler_type(gallivm, "sampler"); @@ -431,9 +471,9 @@ create_jit_types(struct draw_llvm_variant *variant) "draw_jit_context"); 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); - + vb_type = create_jit_vertex_buffer_type(gallivm, "pipe_vertex_buffer"); variant->vb_ptr_type = LLVMPointerType(vb_type, 0); } @@ -631,7 +671,6 @@ generate_vs(struct draw_llvm_variant *variant, } } - static void generate_fetch(struct gallivm_state *gallivm, LLVMValueRef vbuffers_ptr, @@ -641,7 +680,8 @@ generate_fetch(struct gallivm_state *gallivm, LLVMValueRef index, 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)); LLVMBuilderRef builder = gallivm->builder; LLVMValueRef indices = @@ -651,7 +691,14 @@ generate_fetch(struct gallivm_state *gallivm, &indices, 1, ""); LLVMValueRef vb_stride = draw_jit_vbuffer_stride(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 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) { /* array index = instance_id / instance_divisor */ @@ -662,8 +709,6 @@ generate_fetch(struct gallivm_state *gallivm, stride = LLVMBuildMul(builder, vb_stride, index, ""); - vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer"); - stride = LLVMBuildAdd(builder, stride, vb_buffer_offset, ""); @@ -671,14 +716,36 @@ generate_fetch(struct gallivm_state *gallivm, lp_build_const_int32(gallivm, velem->src_offset), ""); -/* lp_build_printf(gallivm, "vbuf index = %d, stride is %d\n", indices, stride);*/ - vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, ""); + buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGE, + 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); + */ + + 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, + lp_float32_vec4_type(), + map_ptr, + zero, zero, zero); + LLVMBuildStore(builder, val, temp_ptr); + } + lp_build_endif(&if_ctx); - *res = lp_build_fetch_rgba_aos(gallivm, - format_desc, - lp_float32_vec4_type(), - vbuffer_ptr, - zero, zero, zero); + *res = LLVMBuildLoad(builder, temp_ptr, "aos"); } static void diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 5909fc10a2d..d517b290666 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -173,6 +173,18 @@ enum { #define draw_jit_vbuffer_offset(_gallivm, _ptr) \ 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. @@ -246,7 +258,7 @@ enum { typedef int (*draw_jit_vert_func)(struct draw_jit_context *context, struct vertex_header *io, - const char *vbuffers[PIPE_MAX_ATTRIBS], + const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS], unsigned start, unsigned count, unsigned stride, @@ -257,7 +269,7 @@ typedef int typedef int (*draw_jit_vert_func_elts)(struct draw_jit_context *context, struct vertex_header *io, - const char *vbuffers[PIPE_MAX_ATTRIBS], + const struct draw_vertex_buffer vbuffers[PIPE_MAX_ATTRIBS], const unsigned *fetch_elts, unsigned fetch_count, unsigned stride, diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 25a8ae61498..84344c36773 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -67,6 +67,14 @@ struct draw_pt_front_end; /** + * Represents the mapped vertex buffer. + */ +struct draw_vertex_buffer { + const void *map; + size_t size; +}; + +/** * Basic vertex info. * Carry some useful information around with the vertices in the prim pipe. */ @@ -183,7 +191,7 @@ struct draw_context unsigned max_index; /** vertex arrays */ - const void *vbuffer[PIPE_MAX_ATTRIBS]; + struct draw_vertex_buffer vbuffer[PIPE_MAX_ATTRIBS]; /** constant buffers (for vertex/geometry shader) */ const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 602d076dce2..a797d65de8c 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -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++) { 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) { 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"); 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, draw->pt.vertex_buffer[i].stride, draw->pt.vertex_buffer[i].buffer_offset, - draw->pt.user.vbuffer[i]); + draw->pt.user.vbuffer[i].size, + draw->pt.user.vbuffer[i].map); } } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 9fab7b681fb..3740deab5a8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -159,7 +159,7 @@ draw_pt_fetch_run(struct pt_fetch *fetch, for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { translate->set_buffer(translate, 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].stride, 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++) { translate->set_buffer(translate, 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].stride, draw->pt.max_index); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index f30db1386cc..dc6decba70e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -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++) { feme->translate->set_buffer(feme->translate, 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].stride, draw->pt.max_index); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c index 870b23bbf58..d30cd412ef6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c @@ -159,7 +159,7 @@ fse_prepare(struct draw_pt_middle_end *middle, for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { fse->active->set_buffer( fse->active, 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].stride, draw->pt.max_index ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 1924c7351b2..bc99c169deb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -348,7 +348,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, if (fetch_info->linear) clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context, llvm_vert_info.verts, - (const char **)draw->pt.user.vbuffer, + draw->pt.user.vbuffer, fetch_info->start, fetch_info->count, fpme->vertex_size, @@ -357,7 +357,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, else clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, llvm_vert_info.verts, - (const char **)draw->pt.user.vbuffer, + draw->pt.user.vbuffer, fetch_info->elts, fetch_info->count, fpme->vertex_size, |