diff options
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_llvm.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 99 |
1 files changed, 83 insertions, 16 deletions
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 |