diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-08-26 16:59:42 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-08-26 16:59:42 +0000 |
commit | 81ece42815e80818f160cdd85fab57d65b56ad15 (patch) | |
tree | 1059ff094da1aa50334115952fcb1cfcbda3acc6 /lib/mesa/src/gallium/auxiliary/draw | |
parent | b0244145d5bb49623d58f6b5cab8143ada692b60 (diff) |
Revert to Mesa 13.0.6 to hopefully address rendering issues a handful of
people have reported with xpdf/fvwm on ivy bridge with modesetting driver.
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/draw')
12 files changed, 419 insertions, 280 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_context.c b/lib/mesa/src/gallium/auxiliary/draw/draw_context.c index ee009c1fb..56abcff5a 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_context.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_context.c @@ -72,7 +72,7 @@ draw_create_context(struct pipe_context *pipe, void *context, boolean try_llvm) { struct draw_context *draw = CALLOC_STRUCT( draw_context ); - if (draw == NULL) + if (!draw) goto err_out; /* we need correct cpu caps for disabling denorms in draw_vbo() */ @@ -556,7 +556,7 @@ draw_alloc_extra_vertex_attrib(struct draw_context *draw, num_outputs = draw_current_shader_outputs(draw); n = draw->extra_shader_outputs.num; - assert(n < Elements(draw->extra_shader_outputs.semantic_name)); + assert(n < ARRAY_SIZE(draw->extra_shader_outputs.semantic_name)); draw->extra_shader_outputs.semantic_name[n] = semantic_name; draw->extra_shader_outputs.semantic_index[n] = semantic_index; @@ -731,7 +731,41 @@ draw_texture_sampler(struct draw_context *draw, } } +/** + * Provide TGSI image objects for vertex/geometry shaders that use + * texture fetches. This state only needs to be set once per context. + * This might only be used by software drivers for the time being. + */ +void +draw_image(struct draw_context *draw, + uint shader, + struct tgsi_image *image) +{ + if (shader == PIPE_SHADER_VERTEX) { + draw->vs.tgsi.image = image; + } else { + debug_assert(shader == PIPE_SHADER_GEOMETRY); + draw->gs.tgsi.image = image; + } +} +/** + * Provide TGSI buffer objects for vertex/geometry shaders that use + * load/store/atomic ops. This state only needs to be set once per context. + * This might only be used by software drivers for the time being. + */ +void +draw_buffer(struct draw_context *draw, + uint shader, + struct tgsi_buffer *buffer) +{ + if (shader == PIPE_SHADER_VERTEX) { + draw->vs.tgsi.buffer = buffer; + } else { + debug_assert(shader == PIPE_SHADER_GEOMETRY); + draw->gs.tgsi.buffer = buffer; + } +} void draw_set_render( struct draw_context *draw, @@ -853,12 +887,12 @@ draw_current_shader_clipvertex_output(const struct draw_context *draw) } uint -draw_current_shader_clipdistance_output(const struct draw_context *draw, int index) +draw_current_shader_ccdistance_output(const struct draw_context *draw, int index) { debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT); if (draw->gs.geometry_shader) - return draw->gs.geometry_shader->clipdistance_output[index]; - return draw->vs.clipdistance_output[index]; + return draw->gs.geometry_shader->ccdistance_output[index]; + return draw->vs.ccdistance_output[index]; } @@ -870,16 +904,6 @@ draw_current_shader_num_written_clipdistances(const struct draw_context *draw) return draw->vs.vertex_shader->info.num_written_clipdistance; } - -uint -draw_current_shader_culldistance_output(const struct draw_context *draw, int index) -{ - debug_assert(index < PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT); - if (draw->gs.geometry_shader) - return draw->gs.geometry_shader->culldistance_output[index]; - return draw->vs.vertex_shader->culldistance_output[index]; -} - uint draw_current_shader_num_written_culldistances(const struct draw_context *draw) { @@ -940,7 +964,7 @@ draw_set_mapped_so_targets(struct draw_context *draw, void draw_set_sampler_views(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_view **views, unsigned num) { @@ -961,7 +985,7 @@ draw_set_sampler_views(struct draw_context *draw, void draw_set_samplers(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_state **samplers, unsigned num) { diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_context.h b/lib/mesa/src/gallium/auxiliary/draw/draw_context.h index a5a6df5b7..145fc2ed4 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_context.h +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_context.h @@ -39,7 +39,6 @@ #include "pipe/p_state.h" -#include "tgsi/tgsi_exec.h" struct pipe_context; struct draw_context; @@ -48,6 +47,8 @@ struct draw_vertex_shader; struct draw_geometry_shader; struct draw_fragment_shader; struct tgsi_sampler; +struct tgsi_image; +struct tgsi_buffer; /* * structure to contain driver internal information @@ -155,13 +156,23 @@ draw_texture_sampler(struct draw_context *draw, struct tgsi_sampler *sampler); void +draw_image(struct draw_context *draw, + uint shader_type, + struct tgsi_image *image); + +void +draw_buffer(struct draw_context *draw, + uint shader_type, + struct tgsi_buffer *buffer); + +void draw_set_sampler_views(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_view **views, unsigned num); void draw_set_samplers(struct draw_context *draw, - unsigned shader_stage, + enum pipe_shader_type shader_stage, struct pipe_sampler_state **samplers, unsigned num); diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.c b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.c index b1e1bcbee..2f82d9dee 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.c @@ -95,7 +95,7 @@ create_jit_dvbuffer_type(struct gallivm_state *gallivm, elem_types[DRAW_JIT_DVBUFFER_SIZE] = int32_type; dvbuffer_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct draw_vertex_buffer, map, @@ -132,7 +132,7 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name) LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS); texture_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width, @@ -186,8 +186,9 @@ create_jit_sampler_type(struct gallivm_state *gallivm, const char *struct_name) LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); sampler_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); + (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, min_lod, target, sampler_type, DRAW_JIT_SAMPLER_MIN_LOD); @@ -233,7 +234,9 @@ create_jit_context_type(struct gallivm_state *gallivm, elem_types[5] = LLVMArrayType(sampler_type, PIPE_MAX_SAMPLERS); /* samplers */ context_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); + + (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_constants, target, context_type, DRAW_JIT_CTX_CONSTANTS); LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, num_vs_constants, @@ -290,7 +293,7 @@ create_gs_jit_context_type(struct gallivm_state *gallivm, vector_length), 0); context_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, constants, @@ -354,7 +357,7 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm, elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); vb_type = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); (void) target; /* silence unused var warning for non-debug build */ LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride, @@ -375,19 +378,18 @@ static LLVMTypeRef create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems) { LLVMTargetDataRef target = gallivm->target; - LLVMTypeRef elem_types[4]; + LLVMTypeRef elem_types[3]; LLVMTypeRef vertex_header; char struct_name[24]; util_snprintf(struct_name, 23, "vertex_header%d", data_elems); elem_types[DRAW_JIT_VERTEX_VERTEX_ID] = LLVMIntTypeInContext(gallivm->context, 32); - elem_types[DRAW_JIT_VERTEX_CLIP] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); - elem_types[DRAW_JIT_VERTEX_PRE_CLIP_POS] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); + elem_types[DRAW_JIT_VERTEX_CLIP_POS] = LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4); elem_types[DRAW_JIT_VERTEX_DATA] = LLVMArrayType(elem_types[1], data_elems); vertex_header = LLVMStructTypeInContext(gallivm->context, elem_types, - Elements(elem_types), 0); + ARRAY_SIZE(elem_types), 0); /* these are bit-fields and we can't take address of them LP_CHECK_MEMBER_OFFSET(struct vertex_header, clipmask, @@ -403,12 +405,10 @@ create_jit_vertex_header(struct gallivm_state *gallivm, int data_elems) target, vertex_header, DRAW_JIT_VERTEX_VERTEX_ID); */ - LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip, - target, vertex_header, - DRAW_JIT_VERTEX_CLIP); - LP_CHECK_MEMBER_OFFSET(struct vertex_header, pre_clip_pos, + (void) target; /* silence unused var warning for non-debug build */ + LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip_pos, target, vertex_header, - DRAW_JIT_VERTEX_PRE_CLIP_POS); + DRAW_JIT_VERTEX_CLIP_POS); LP_CHECK_MEMBER_OFFSET(struct vertex_header, data, target, vertex_header, DRAW_JIT_VERTEX_DATA); @@ -551,7 +551,7 @@ draw_llvm_create_variant(struct draw_llvm *llvm, variant = MALLOC(sizeof *variant + shader->variant_key_size - sizeof variant->key); - if (variant == NULL) + if (!variant) return NULL; variant->llvm = llvm; @@ -625,6 +625,7 @@ generate_vs(struct draw_llvm_variant *variant, inputs, outputs, context_ptr, + NULL, draw_sampler, &llvm->draw->vs.vertex_shader->info, NULL); @@ -658,80 +659,42 @@ generate_vs(struct draw_llvm_variant *variant, static void generate_fetch(struct gallivm_state *gallivm, struct draw_context *draw, - LLVMValueRef vbuffers_ptr, + const struct util_format_description *format_desc, + LLVMValueRef vb_stride, + LLVMValueRef stride_fixed, + LLVMValueRef map_ptr, + LLVMValueRef buffer_size_adj, + LLVMValueRef ofbit, LLVMValueRef *res, - struct pipe_vertex_element *velem, - LLVMValueRef vbuf, - LLVMValueRef index, - LLVMValueRef instance_id, - LLVMValueRef start_instance) + LLVMValueRef index) { - 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 = - LLVMConstInt(LLVMInt64TypeInContext(gallivm->context), - velem->vertex_buffer_index, 0); - LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr, - &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 needed_buffer_size; LLVMValueRef temp_ptr = lp_build_alloca(gallivm, lp_build_vec_type(gallivm, lp_float32_vec4_type()), ""); - LLVMValueRef ofbit = NULL; struct lp_build_if_state if_ctx; - if (velem->instance_divisor) { - /* Index is equal to the start instance plus the number of current - * instance divided by the divisor. In this case we compute it as: - * index = start_instance + (instance_id / divisor) - */ - LLVMValueRef current_instance; - current_instance = LLVMBuildUDiv(builder, instance_id, - lp_build_const_int32(gallivm, velem->instance_divisor), - "instance_divisor"); - index = lp_build_uadd_overflow(gallivm, start_instance, - current_instance, &ofbit); + if (format_desc->format == PIPE_FORMAT_NONE) { + *res = lp_build_const_vec(gallivm, lp_float32_vec4_type(), 0); + return; } stride = lp_build_umul_overflow(gallivm, vb_stride, index, &ofbit); - stride = lp_build_uadd_overflow(gallivm, stride, vb_buffer_offset, &ofbit); - stride = lp_build_uadd_overflow( - gallivm, stride, - lp_build_const_int32(gallivm, velem->src_offset), &ofbit); - needed_buffer_size = lp_build_uadd_overflow( - gallivm, stride, - lp_build_const_int32(gallivm, - util_format_get_blocksize(velem->src_format)), - &ofbit); + stride = lp_build_uadd_overflow(gallivm, stride, stride_fixed, &ofbit); buffer_overflowed = LLVMBuildICmp(builder, LLVMIntUGT, - needed_buffer_size, buffer_size, + stride, buffer_size_adj, "buffer_overflowed"); buffer_overflowed = LLVMBuildOr(builder, buffer_overflowed, ofbit, ""); -#if 0 - lp_build_printf(gallivm, "vbuf index = %u, vb_stride is %u\n", - index, vb_stride); - lp_build_printf(gallivm, " vb_buffer_offset = %u, src_offset is %u\n", - vb_buffer_offset, - lp_build_const_int32(gallivm, velem->src_offset)); - lp_build_print_value(gallivm, " blocksize = ", - lp_build_const_int32( - gallivm, - util_format_get_blocksize(velem->src_format))); - lp_build_printf(gallivm, " instance_id = %u\n", instance_id); - lp_build_printf(gallivm, " stride = %u\n", stride); - lp_build_printf(gallivm, " buffer size = %u\n", buffer_size); - lp_build_printf(gallivm, " needed_buffer_size = %u\n", needed_buffer_size); - lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed); -#endif + + if (0) { + lp_build_printf(gallivm, " stride = %u\n", stride); + lp_build_printf(gallivm, " buffer size adj = %u\n", buffer_size_adj); + lp_build_print_value(gallivm, " buffer overflowed = ", buffer_overflowed); + } lp_build_if(&if_ctx, gallivm, buffer_overflowed); { @@ -749,7 +712,8 @@ generate_fetch(struct gallivm_state *gallivm, lp_float32_vec4_type(), FALSE, map_ptr, - zero, zero, zero); + zero, zero, zero, + NULL); LLVMBuildStore(builder, val, temp_ptr); } lp_build_endif(&if_ctx); @@ -759,36 +723,34 @@ generate_fetch(struct gallivm_state *gallivm, static void convert_to_soa(struct gallivm_state *gallivm, - LLVMValueRef (*src_aos)[LP_MAX_VECTOR_WIDTH / 32], + LLVMValueRef src_aos[LP_MAX_VECTOR_WIDTH / 32], LLVMValueRef (*dst_soa)[TGSI_NUM_CHANNELS], - unsigned num_attribs, const struct lp_type soa_type) + unsigned attrib, const struct lp_type soa_type) { - unsigned i, j, k; + unsigned j, k; struct lp_type aos_channel_type = soa_type; + LLVMValueRef aos_channels[TGSI_NUM_CHANNELS]; + unsigned pixels_per_channel = soa_type.length / TGSI_NUM_CHANNELS; + debug_assert(TGSI_NUM_CHANNELS == 4); debug_assert((soa_type.length % TGSI_NUM_CHANNELS) == 0); aos_channel_type.length >>= 1; - for (i = 0; i < num_attribs; ++i) { - LLVMValueRef aos_channels[TGSI_NUM_CHANNELS]; - unsigned pixels_per_channel = soa_type.length / TGSI_NUM_CHANNELS; - - for (j = 0; j < TGSI_NUM_CHANNELS; ++j) { - LLVMValueRef channel[LP_MAX_VECTOR_LENGTH] = { 0 }; + for (j = 0; j < TGSI_NUM_CHANNELS; ++j) { + LLVMValueRef channel[LP_MAX_VECTOR_LENGTH] = { 0 }; - assert(pixels_per_channel <= LP_MAX_VECTOR_LENGTH); + assert(pixels_per_channel <= LP_MAX_VECTOR_LENGTH); - for (k = 0; k < pixels_per_channel; ++k) { - channel[k] = src_aos[i][j + TGSI_NUM_CHANNELS * k]; - } - - aos_channels[j] = lp_build_concat(gallivm, channel, aos_channel_type, pixels_per_channel); + for (k = 0; k < pixels_per_channel; ++k) { + channel[k] = src_aos[j + TGSI_NUM_CHANNELS * k]; } - lp_build_transpose_aos(gallivm, soa_type, aos_channels, dst_soa[i]); + aos_channels[j] = lp_build_concat(gallivm, channel, aos_channel_type, pixels_per_channel); } + + lp_build_transpose_aos(gallivm, soa_type, aos_channels, dst_soa[attrib]); } @@ -815,7 +777,7 @@ store_aos(struct gallivm_state *gallivm, #endif /* Unaligned store due to the vertex header */ - lp_set_store_alignment(LLVMBuildStore(builder, value, data_ptr), sizeof(float)); + LLVMSetAlignment(LLVMBuildStore(builder, value, data_ptr), sizeof(float)); } /** @@ -824,7 +786,7 @@ store_aos(struct gallivm_state *gallivm, * struct vertex_header { * unsigned clipmask:DRAW_TOTAL_CLIP_PLANES; * unsigned edgeflag:1; - * unsigned have_clipdist:1; + * unsigned pad:1; * unsigned vertex_id:16; * [...] * } @@ -836,7 +798,7 @@ store_aos(struct gallivm_state *gallivm, * { * return (x >> 16) | // vertex_id * ((x & 0x3fff) << 18) | // clipmask - * ((x & 0x4000) << 3) | // have_clipdist + * ((x & 0x4000) << 3) | // pad * ((x & 0x8000) << 1); // edgeflag * } */ @@ -848,19 +810,23 @@ adjust_mask(struct gallivm_state *gallivm, LLVMBuilderRef builder = gallivm->builder; LLVMValueRef vertex_id; LLVMValueRef clipmask; - LLVMValueRef have_clipdist; + LLVMValueRef pad; LLVMValueRef edgeflag; vertex_id = LLVMBuildLShr(builder, mask, lp_build_const_int32(gallivm, 16), ""); clipmask = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x3fff), ""); clipmask = LLVMBuildShl(builder, clipmask, lp_build_const_int32(gallivm, 18), ""); - have_clipdist = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x4000), ""); - have_clipdist = LLVMBuildShl(builder, have_clipdist, lp_build_const_int32(gallivm, 3), ""); + if (0) { + pad = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x4000), ""); + pad = LLVMBuildShl(builder, pad, lp_build_const_int32(gallivm, 3), ""); + } edgeflag = LLVMBuildAnd(builder, mask, lp_build_const_int32(gallivm, 0x8000), ""); edgeflag = LLVMBuildShl(builder, edgeflag, lp_build_const_int32(gallivm, 1), ""); mask = LLVMBuildOr(builder, vertex_id, clipmask, ""); - mask = LLVMBuildOr(builder, mask, have_clipdist, ""); + if (0) { + mask = LLVMBuildOr(builder, mask, pad, ""); + } mask = LLVMBuildOr(builder, mask, edgeflag, ""); #endif return mask; @@ -875,7 +841,7 @@ store_aos_array(struct gallivm_state *gallivm, int attrib, int num_outputs, LLVMValueRef clipmask, - boolean have_clipdist) + boolean need_edgeflag) { LLVMBuilderRef builder = gallivm->builder; LLVMValueRef attr_index = lp_build_const_int32(gallivm, attrib); @@ -906,11 +872,15 @@ store_aos_array(struct gallivm_state *gallivm, * code here. See struct vertex_header in draw_private.h. */ assert(DRAW_TOTAL_CLIP_PLANES==14); - /* initialize vertex id:16 = 0xffff, have_clipdist:1 = 0, edgeflag:1 = 1 */ - vertex_id_pad_edgeflag = (0xffff << 16) | (1 << DRAW_TOTAL_CLIP_PLANES); - if (have_clipdist) - vertex_id_pad_edgeflag |= 1 << (DRAW_TOTAL_CLIP_PLANES+1); - val = lp_build_const_int_vec(gallivm, lp_int_type(soa_type), vertex_id_pad_edgeflag); + /* initialize vertex id:16 = 0xffff, pad:1 = 0, edgeflag:1 = 1 */ + if (!need_edgeflag) { + vertex_id_pad_edgeflag = (0xffff << 16) | (1 << DRAW_TOTAL_CLIP_PLANES); + } + else { + vertex_id_pad_edgeflag = (0xffff << 16); + } + val = lp_build_const_int_vec(gallivm, lp_int_type(soa_type), + vertex_id_pad_edgeflag); /* OR with the clipmask */ cliptmp = LLVMBuildOr(builder, val, clipmask, ""); for (i = 0; i < vector_length; i++) { @@ -940,7 +910,7 @@ convert_to_aos(struct gallivm_state *gallivm, LLVMValueRef clipmask, int num_outputs, struct lp_type soa_type, - boolean have_clipdist) + boolean need_edgeflag) { LLVMBuilderRef builder = gallivm->builder; unsigned chan, attrib, i; @@ -996,7 +966,8 @@ convert_to_aos(struct gallivm_state *gallivm, aos, attrib, num_outputs, - clipmask, have_clipdist); + clipmask, + need_edgeflag); } #if DEBUG_STORE lp_build_printf(gallivm, " # storing end\n"); @@ -1012,7 +983,7 @@ store_clip(struct gallivm_state *gallivm, const struct lp_type vs_type, LLVMValueRef io_ptr, LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], - boolean pre_clip_pos, int idx) + int idx) { LLVMBuilderRef builder = gallivm->builder; LLVMValueRef soa[4]; @@ -1039,14 +1010,8 @@ store_clip(struct gallivm_state *gallivm, soa[2] = LLVMBuildLoad(builder, outputs[idx][2], ""); /*z0 z1 .. zn*/ soa[3] = LLVMBuildLoad(builder, outputs[idx][3], ""); /*w0 w1 .. wn*/ - if (!pre_clip_pos) { - for (i = 0; i < vs_type.length; i++) { - clip_ptrs[i] = draw_jit_header_clip(gallivm, io_ptrs[i]); - } - } else { - for (i = 0; i < vs_type.length; i++) { - clip_ptrs[i] = draw_jit_header_pre_clip_pos(gallivm, io_ptrs[i]); - } + for (i = 0; i < vs_type.length; i++) { + clip_ptrs[i] = draw_jit_header_clip_pos(gallivm, io_ptrs[i]); } lp_build_transpose_aos(gallivm, vs_type, soa, soa); @@ -1064,7 +1029,7 @@ store_clip(struct gallivm_state *gallivm, clip_ptr = LLVMBuildPointerCast(builder, clip_ptr, clip_ptr_type, ""); /* Unaligned store */ - lp_set_store_alignment(LLVMBuildStore(builder, aos[j], clip_ptr), sizeof(float)); + LLVMSetAlignment(LLVMBuildStore(builder, aos[j], clip_ptr), sizeof(float)); } } @@ -1118,10 +1083,8 @@ generate_viewport(struct draw_llvm_variant *variant, /* divide by w */ out = LLVMBuildFMul(builder, out, out3, ""); - /* mult by scale */ - out = LLVMBuildFMul(builder, out, scale, ""); - /* add translation */ - out = LLVMBuildFAdd(builder, out, trans, ""); + /* mult by scale, add translation */ + out = lp_build_fmuladd(builder, out, scale, trans); /* store transformed outputs */ LLVMBuildStore(builder, out, outputs[pos][i]); @@ -1138,11 +1101,7 @@ generate_clipmask(struct draw_llvm *llvm, struct gallivm_state *gallivm, struct lp_type vs_type, LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], - boolean clip_xy, - boolean clip_z, - boolean clip_user, - boolean clip_halfz, - unsigned ucp_enable, + struct draw_llvm_variant_key *key, LLVMValueRef context_ptr, boolean *have_clipdist) { @@ -1158,11 +1117,13 @@ generate_clipmask(struct draw_llvm *llvm, const unsigned pos = llvm->draw->vs.position_output; const unsigned cv = llvm->draw->vs.clipvertex_output; int num_written_clipdistance = llvm->draw->vs.vertex_shader->info.num_written_clipdistance; - bool have_cd = false; + boolean have_cd = false; + boolean clip_user = key->clip_user; + unsigned ucp_enable = key->ucp_enable; unsigned cd[2]; - cd[0] = llvm->draw->vs.clipdistance_output[0]; - cd[1] = llvm->draw->vs.clipdistance_output[1]; + cd[0] = llvm->draw->vs.ccdistance_output[0]; + cd[1] = llvm->draw->vs.ccdistance_output[1]; if (cd[0] != pos || cd[1] != pos) have_cd = true; @@ -1198,8 +1159,16 @@ generate_clipmask(struct draw_llvm *llvm, cv_w = pos_w; } + /* + * Be careful with the comparisons and NaNs (using llvm's unordered + * comparisons here). + */ /* Cliptest, for hardwired planes */ - if (clip_xy) { + /* + * XXX should take guardband into account (currently not in key). + * Otherwise might run the draw pipeline stages for nothing. + */ + if (key->clip_xy) { /* plane 1 */ test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w); temp = shift; @@ -1227,9 +1196,9 @@ generate_clipmask(struct draw_llvm *llvm, mask = LLVMBuildOr(builder, mask, test, ""); } - if (clip_z) { + if (key->clip_z) { temp = lp_build_const_int_vec(gallivm, i32_type, 16); - if (clip_halfz) { + if (key->clip_halfz) { /* plane 5 */ test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, pos_z); test = LLVMBuildAnd(builder, test, temp, ""); @@ -1292,22 +1261,19 @@ generate_clipmask(struct draw_llvm *llvm, plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_y"); planes = lp_build_broadcast(gallivm, vs_type_llvm, plane1); - test = LLVMBuildFMul(builder, planes, cv_y, ""); - sum = LLVMBuildFAdd(builder, sum, test, ""); + sum = lp_build_fmuladd(builder, planes, cv_y, sum); indices[2] = lp_build_const_int32(gallivm, 2); plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_z"); planes = lp_build_broadcast(gallivm, vs_type_llvm, plane1); - test = LLVMBuildFMul(builder, planes, cv_z, ""); - sum = LLVMBuildFAdd(builder, sum, test, ""); + sum = lp_build_fmuladd(builder, planes, cv_z, sum); indices[2] = lp_build_const_int32(gallivm, 3); plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_w"); planes = lp_build_broadcast(gallivm, vs_type_llvm, plane1); - test = LLVMBuildFMul(builder, planes, cv_w, ""); - sum = LLVMBuildFAdd(builder, sum, test, ""); + sum = lp_build_fmuladd(builder, planes, cv_w, sum); test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, sum); temp = lp_build_const_int_vec(gallivm, i32_type, 1LL << plane_idx); @@ -1316,6 +1282,20 @@ generate_clipmask(struct draw_llvm *llvm, } } } + if (key->need_edgeflags) { + /* + * This isn't really part of clipmask but stored the same in vertex + * header later, so do it here. + */ + unsigned edge_attr = llvm->draw->vs.edgeflag_output; + LLVMValueRef one = lp_build_const_vec(gallivm, f32_type, 1.0); + LLVMValueRef edgeflag = LLVMBuildLoad(builder, outputs[edge_attr][0], ""); + test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_EQUAL, one, edgeflag); + temp = lp_build_const_int_vec(gallivm, i32_type, + 1LL << DRAW_TOTAL_CLIP_PLANES); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } return mask; } @@ -1327,7 +1307,8 @@ generate_clipmask(struct draw_llvm *llvm, static LLVMValueRef clipmask_booli32(struct gallivm_state *gallivm, const struct lp_type vs_type, - LLVMValueRef clipmask_bool_ptr) + LLVMValueRef clipmask_bool_ptr, + boolean edgeflag_in_clipmask) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef int32_type = LLVMInt32TypeInContext(gallivm->context); @@ -1337,8 +1318,18 @@ clipmask_booli32(struct gallivm_state *gallivm, int i; /* - * Can do this with log2(vector length) pack instructions and one extract - * (as we don't actually need a or) with sse2 which would be way better. + * We need to invert the edgeflag bit from the clipmask here + * (because the result is really if we want to run the pipeline or not + * and we (may) need it if edgeflag was 0). + */ + if (edgeflag_in_clipmask) { + struct lp_type i32_type = lp_int_type(vs_type); + LLVMValueRef edge = lp_build_const_int_vec(gallivm, i32_type, + 1LL << DRAW_TOTAL_CLIP_PLANES); + clipmask_bool = LLVMBuildXor(builder, clipmask_bool, edge, ""); + } + /* + * Could do much better with just cmp/movmskps. */ for (i=0; i < vs_type.length; i++) { temp = LLVMBuildExtractElement(builder, clipmask_bool, @@ -1499,7 +1490,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, LLVMTypeRef int32_type = LLVMInt32TypeInContext(context); LLVMTypeRef arg_types[11]; unsigned num_arg_types = - elts ? Elements(arg_types) : Elements(arg_types) - 1; + elts ? ARRAY_SIZE(arg_types) : ARRAY_SIZE(arg_types) - 1; LLVMTypeRef func_type; LLVMValueRef context_ptr; LLVMBasicBlockRef block; @@ -1513,6 +1504,13 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef zero = lp_build_const_int32(gallivm, 0); LLVMValueRef one = lp_build_const_int32(gallivm, 1); + LLVMValueRef vb_stride[PIPE_MAX_SHADER_INPUTS]; + LLVMValueRef map_ptr[PIPE_MAX_SHADER_INPUTS]; + LLVMValueRef buffer_size_adj[PIPE_MAX_SHADER_INPUTS]; + LLVMValueRef stride_fixed[PIPE_MAX_SHADER_INPUTS]; + LLVMValueRef ofbit[PIPE_MAX_SHADER_INPUTS]; + LLVMValueRef instance_index[PIPE_MAX_SHADER_INPUTS]; + struct draw_context *draw = llvm->draw; const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; @@ -1534,8 +1532,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, const boolean bypass_viewport = key->has_gs || key->bypass_viewport || llvm->draw->vs.vertex_shader->info.writes_viewport_index; const boolean enable_cliptest = !key->has_gs && (key->clip_xy || - key->clip_z || - key->clip_user); + key->clip_z || + key->clip_user || + key->need_edgeflags); LLVMValueRef variant_func; const unsigned pos = llvm->draw->vs.position_output; const unsigned cv = llvm->draw->vs.clipvertex_output; @@ -1581,6 +1580,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, context_ptr = LLVMGetParam(variant_func, 0); io_ptr = LLVMGetParam(variant_func, 1); vbuffers_ptr = LLVMGetParam(variant_func, 2); + /* + * XXX: stride is actually unused. The stride we use is strictly calculated + * from the number of outputs (including the draw_extra outputs). + * Should probably fix some day (we need a new vs just because of extra + * outputs which the generated vs won't touch). + */ stride = LLVMGetParam(variant_func, 5 + (elts ? 1 : 0)); vb_ptr = LLVMGetParam(variant_func, 6 + (elts ? 1 : 0)); system_values.instance_id = LLVMGetParam(variant_func, 7 + (elts ? 1 : 0)); @@ -1650,14 +1655,67 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, fetch_max = LLVMBuildSub(builder, end, one, "fetch_max"); + /* + * Pre-calculate everything which is constant per shader invocation. + */ + for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { + LLVMValueRef vb_buffer_offset, buffer_size; + LLVMValueRef vb_info, vbuffer_ptr; + struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; + LLVMValueRef vb_index = + lp_build_const_int32(gallivm, velem->vertex_buffer_index); + LLVMValueRef bsize = lp_build_const_int32(gallivm, + util_format_get_blocksize(velem->src_format)); + LLVMValueRef src_offset = lp_build_const_int32(gallivm, + velem->src_offset); + + vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr, &vb_index, 1, ""); + vb_info = LLVMBuildGEP(builder, vb_ptr, &vb_index, 1, ""); + vb_stride[j] = draw_jit_vbuffer_stride(gallivm, vb_info); + vb_buffer_offset = draw_jit_vbuffer_offset(gallivm, vb_info); + map_ptr[j] = draw_jit_dvbuffer_map(gallivm, vbuffer_ptr); + buffer_size = draw_jit_dvbuffer_size(gallivm, vbuffer_ptr); + + ofbit[j] = NULL; + stride_fixed[j] = lp_build_uadd_overflow(gallivm, vb_buffer_offset, + src_offset, &ofbit[j]); + buffer_size_adj[j] = lp_build_usub_overflow(gallivm, buffer_size, bsize, + &ofbit[j]); + + if (velem->instance_divisor) { + /* Index is equal to the start instance plus the number of current + * instance divided by the divisor. In this case we compute it as: + * index = start_instance + (instance_id / divisor) + */ + LLVMValueRef current_instance; + current_instance = LLVMBuildUDiv(builder, system_values.instance_id, + lp_build_const_int32(gallivm, + velem->instance_divisor), + "instance_divisor"); + instance_index[j] = lp_build_uadd_overflow(gallivm, start_instance, + current_instance, &ofbit[j]); + } + + if (0) { + lp_build_printf(gallivm, "vbuf index = %u, vb_stride is %u\n", + vb_index, vb_stride[j]); + lp_build_printf(gallivm, " vb_buffer_offset = %u, src_offset is %u\n", + vb_buffer_offset, src_offset); + lp_build_print_value(gallivm, " blocksize = ", bsize); + lp_build_printf(gallivm, " instance_id = %u\n", system_values.instance_id); + lp_build_printf(gallivm, " buffer size = %u\n", buffer_size); + } + } + lp_build_loop_begin(&lp_loop, gallivm, zero); { LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS]; - LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][LP_MAX_VECTOR_WIDTH / 32] = { { 0 } }; + LLVMValueRef aos_attribs[LP_MAX_VECTOR_WIDTH / 32] = { 0 }; LLVMValueRef io; LLVMValueRef clipmask; /* holds the clipmask value */ LLVMValueRef true_index_array = lp_build_zero(gallivm, lp_type_uint_vec(32, 32*vector_length)); + LLVMValueRef true_indices[LP_MAX_VECTOR_WIDTH / 32]; const LLVMValueRef (*ptr_aos)[TGSI_NUM_CHANNELS]; io_itr = lp_loop.counter; @@ -1667,6 +1725,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, lp_build_printf(gallivm, " --- io %d = %p, loop counter %d\n", io_itr, io, lp_loop.counter); #endif + for (i = 0; i < vector_length; ++i) { LLVMValueRef vert_index = LLVMBuildAdd(builder, @@ -1716,22 +1775,25 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, lp_build_endif(&if_ctx); true_index = LLVMBuildLoad(builder, index_ptr, "true_index"); } + true_indices[i] = true_index; true_index_array = LLVMBuildInsertElement( gallivm->builder, true_index_array, true_index, lp_build_const_int32(gallivm, i), ""); + } + + for (j = 0; j < key->nr_vertex_elements; ++j) { + struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; + const struct util_format_description *format_desc = + util_format_description(velem->src_format); - for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { - struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; - LLVMValueRef vb_index = - lp_build_const_int32(gallivm, velem->vertex_buffer_index); - LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr, &vb_index, 1, ""); - generate_fetch(gallivm, draw, vbuffers_ptr, - &aos_attribs[j][i], velem, vb, true_index, - system_values.instance_id, start_instance); + for (i = 0; i < vector_length; ++i) { + generate_fetch(gallivm, draw, format_desc, + vb_stride[j], stride_fixed[j], map_ptr[j], + buffer_size_adj[j], ofbit[j], &aos_attribs[i], + velem->instance_divisor ? instance_index[j] : true_indices[i]); } + convert_to_soa(gallivm, aos_attribs, inputs, j, vs_type); } - convert_to_soa(gallivm, aos_attribs, inputs, - draw->pt.nr_vertex_elements, vs_type); /* In the paths with elts vertex id has to be unaffected by the * index bias and because indices inside our elements array have @@ -1764,8 +1826,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, if (pos != -1 && cv != -1) { /* store original positions in clip before further manipulation */ - store_clip(gallivm, vs_type, io, outputs, FALSE, key->clip_user ? cv : pos); - store_clip(gallivm, vs_type, io, outputs, TRUE, pos); + store_clip(gallivm, vs_type, io, outputs, pos); /* do cliptest */ if (enable_cliptest) { @@ -1775,11 +1836,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, gallivm, vs_type, outputs, - key->clip_xy, - key->clip_z, - key->clip_user, - key->clip_halfz, - key->ucp_enable, + key, context_ptr, &have_clipdist); temp = LLVMBuildOr(builder, clipmask, temp, ""); /* store temporary clipping boolean value */ @@ -1804,14 +1861,15 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant, */ convert_to_aos(gallivm, io, NULL, outputs, clipmask, vs_info->num_outputs, vs_type, - have_clipdist); + enable_cliptest && key->need_edgeflags); } lp_build_loop_end_cond(&lp_loop, count, step, LLVMIntUGE); sampler->destroy(sampler); /* return clipping boolean value for function */ - ret = clipmask_booli32(gallivm, vs_type, clipmask_bool_ptr); + ret = clipmask_booli32(gallivm, vs_type, clipmask_bool_ptr, + enable_cliptest && key->need_edgeflags); LLVMBuildRet(builder, ret); @@ -1828,16 +1886,9 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key = (struct draw_llvm_variant_key *)store; - key->clamp_vertex_color = llvm->draw->rasterizer->clamp_vertex_color; /**/ + memset(key, 0, offsetof(struct draw_llvm_variant_key, vertex_element[0])); - /* Presumably all variants of the shader should have the same - * number of vertex elements - ie the number of shader inputs. - * NOTE: we NEED to store the needed number of needed inputs - * here, not the number of provided elements to match keysize - * (and the offset of sampler state in the key). - */ - key->nr_vertex_elements = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_INPUT] + 1; - assert(key->nr_vertex_elements <= llvm->draw->pt.nr_vertex_elements); + key->clamp_vertex_color = llvm->draw->rasterizer->clamp_vertex_color; /**/ /* will have to rig this up properly later */ key->clip_xy = llvm->draw->clip_xy; @@ -1845,11 +1896,11 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->clip_user = llvm->draw->clip_user; key->bypass_viewport = llvm->draw->bypass_viewport; key->clip_halfz = llvm->draw->rasterizer->clip_halfz; + /* XXX assumes edgeflag output not at 0 */ key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); key->ucp_enable = llvm->draw->rasterizer->clip_plane_enable; key->has_gs = llvm->draw->gs.geometry_shader != NULL; key->num_outputs = draw_total_vs_outputs(llvm->draw); - key->pad1 = 0; /* All variants of this shader will have the same value for * nr_samplers. Not yet trying to compact away holes in the @@ -1864,13 +1915,34 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->nr_sampler_views = key->nr_samplers; } - draw_sampler = draw_llvm_variant_key_samplers(key); - + /* Presumably all variants of the shader should have the same + * number of vertex elements - ie the number of shader inputs. + * NOTE: we NEED to store the needed number of needed inputs + * here, not the number of provided elements to match keysize + * (and the offset of sampler state in the key). + * If we have excess number of vertex elements, this is valid, + * but the excess ones don't matter. + * If we don't have enough vertex elements (which looks not really + * valid but we'll handle it gracefully) fill out missing ones with + * zero (we'll recognize these later by PIPE_FORMAT_NONE). + */ + key->nr_vertex_elements = + llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_INPUT] + 1; + + if (llvm->draw->pt.nr_vertex_elements < key->nr_vertex_elements) { + debug_printf("draw: vs with %d inputs but only have %d vertex elements\n", + key->nr_vertex_elements, llvm->draw->pt.nr_vertex_elements); + memset(key->vertex_element, 0, + sizeof(struct pipe_vertex_element) * key->nr_vertex_elements); + } memcpy(key->vertex_element, llvm->draw->pt.vertex_element, - sizeof(struct pipe_vertex_element) * key->nr_vertex_elements); + sizeof(struct pipe_vertex_element) * + MIN2(key->nr_vertex_elements, llvm->draw->pt.nr_vertex_elements)); - memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); + draw_sampler = draw_llvm_variant_key_samplers(key); + memset(draw_sampler, 0, + MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler); for (i = 0 ; i < key->nr_samplers; i++) { lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state, @@ -1932,11 +2004,11 @@ draw_llvm_set_mapped_texture(struct draw_context *draw, shader_stage == PIPE_SHADER_GEOMETRY); if (shader_stage == PIPE_SHADER_VERTEX) { - assert(sview_idx < Elements(draw->llvm->jit_context.textures)); + assert(sview_idx < ARRAY_SIZE(draw->llvm->jit_context.textures)); jit_tex = &draw->llvm->jit_context.textures[sview_idx]; } else if (shader_stage == PIPE_SHADER_GEOMETRY) { - assert(sview_idx < Elements(draw->llvm->gs_jit_context.textures)); + assert(sview_idx < ARRAY_SIZE(draw->llvm->gs_jit_context.textures)); jit_tex = &draw->llvm->gs_jit_context.textures[sview_idx]; } else { @@ -2107,7 +2179,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, LLVMVectorType(int32_type, vector_length), 0); /* prim_id_ptr */ arg_types[6] = int32_type; - func_type = LLVMFunctionType(int32_type, arg_types, Elements(arg_types), 0); + func_type = LLVMFunctionType(int32_type, arg_types, ARRAY_SIZE(arg_types), 0); variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); @@ -2115,7 +2187,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); - for (i = 0; i < Elements(arg_types); ++i) + for (i = 0; i < ARRAY_SIZE(arg_types); ++i) if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) LLVMAddAttribute(LLVMGetParam(variant_func, i), LLVMNoAliasAttribute); @@ -2193,6 +2265,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, NULL, outputs, context_ptr, + NULL, sampler, &llvm->draw->gs.geometry_shader->info, (const struct lp_build_tgsi_gs_iface *)&gs_iface); @@ -2221,7 +2294,7 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm, variant = MALLOC(sizeof *variant + shader->variant_key_size - sizeof variant->key); - if (variant == NULL) + if (!variant) return NULL; variant->llvm = llvm; @@ -2280,6 +2353,8 @@ draw_gs_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key = (struct draw_gs_llvm_variant_key *)store; + memset(key, 0, offsetof(struct draw_gs_llvm_variant_key, samplers[0])); + key->num_outputs = draw_total_gs_outputs(llvm->draw); /* All variants of this shader will have the same value for diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.h b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.h index d153c166e..271433c8e 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.h +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_llvm.h @@ -104,8 +104,7 @@ enum { enum { DRAW_JIT_VERTEX_VERTEX_ID = 0, - DRAW_JIT_VERTEX_CLIP, - DRAW_JIT_VERTEX_PRE_CLIP_POS, + DRAW_JIT_VERTEX_CLIP_POS, DRAW_JIT_VERTEX_DATA }; @@ -162,11 +161,8 @@ enum { #define draw_jit_header_id(_gallivm, _ptr) \ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_VERTEX_ID, "id") -#define draw_jit_header_clip(_gallivm, _ptr) \ - lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_CLIP, "clip") - -#define draw_jit_header_pre_clip_pos(_gallivm, _ptr) \ - lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_PRE_CLIP_POS, "pre_clip_pos") +#define draw_jit_header_clip_pos(_gallivm, _ptr) \ + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_CLIP_POS, "clip_pos") #define draw_jit_header_data(_gallivm, _ptr) \ lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_DATA, "data") @@ -315,12 +311,8 @@ struct draw_llvm_variant_key unsigned need_edgeflags:1; unsigned has_gs:1; unsigned num_outputs:8; - /* - * it is important there are no holes in this struct - * (and all padding gets zeroed). - */ unsigned ucp_enable:PIPE_MAX_CLIP_PLANES; - unsigned pad1:24-PIPE_MAX_CLIP_PLANES; + /* note padding here - must use memset */ /* Variable number of vertex elements: */ @@ -336,6 +328,7 @@ struct draw_gs_llvm_variant_key unsigned nr_samplers:8; unsigned nr_sampler_views:8; unsigned num_outputs:8; + /* note padding here - must use memset */ struct draw_sampler_static_state samplers[1]; }; diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 85d24b7a6..c236caa3e 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -118,10 +118,12 @@ struct aaline_stage void (*driver_bind_fs_state)(struct pipe_context *, void *); void (*driver_delete_fs_state)(struct pipe_context *, void *); - void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, unsigned, + void (*driver_bind_sampler_states)(struct pipe_context *, + enum pipe_shader_type, unsigned, unsigned, void **); - void (*driver_set_sampler_views)(struct pipe_context *, unsigned shader, + void (*driver_set_sampler_views)(struct pipe_context *, + enum pipe_shader_type shader, unsigned start, unsigned count, struct pipe_sampler_view **); }; @@ -163,7 +165,7 @@ aa_transform_decl(struct tgsi_transform_context *ctx, uint i; for (i = decl->Range.First; i <= decl->Range.Last; i++) { - aactx->samplersUsed |= 1 << i; + aactx->samplersUsed |= 1u << i; } } else if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { @@ -208,9 +210,11 @@ aa_transform_prolog(struct tgsi_transform_context *ctx) struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; uint i; + STATIC_ASSERT(sizeof(aactx->samplersUsed) * 8 >= PIPE_MAX_SAMPLERS); + /* find free sampler */ aactx->freeSampler = free_bit(aactx->samplersUsed); - if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) + if (aactx->freeSampler < 0 || aactx->freeSampler >= PIPE_MAX_SAMPLERS) aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; /* find two free temp regs */ @@ -264,11 +268,11 @@ aa_transform_epilog(struct tgsi_transform_context *ctx) if (aactx->colorOutput != -1) { /* insert texture sampling code for antialiasing. */ - /* TEX texTemp, input_coord, sampler */ - tgsi_transform_tex_2d_inst(ctx, - TGSI_FILE_TEMPORARY, aactx->texTemp, - TGSI_FILE_INPUT, aactx->maxInput + 1, - aactx->freeSampler); + /* TEX texTemp, input_coord, sampler, 2D */ + tgsi_transform_tex_inst(ctx, + TGSI_FILE_TEMPORARY, aactx->texTemp, + TGSI_FILE_INPUT, aactx->maxInput + 1, + TGSI_TEXTURE_2D, aactx->freeSampler); /* MOV rgb */ tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV, @@ -429,7 +433,7 @@ aaline_create_texture(struct aaline_stage *aaline) PIPE_TRANSFER_WRITE, &box, &transfer); - if (data == NULL) + if (!data) return FALSE; for (i = 0; i < size; i++) { @@ -646,6 +650,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) struct pipe_context *pipe = draw->pipe; const struct pipe_rasterizer_state *rast = draw->rasterizer; uint num_samplers; + uint num_sampler_views; void *r; assert(draw->rasterizer->line_smooth); @@ -667,9 +672,9 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) draw_aaline_prepare_outputs(draw, draw->pipeline.aaline); /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers); - num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); + /* we'll use sampler/texture[aaline->sampler_unit] for the alpha texture */ + num_samplers = MAX2(aaline->num_samplers, aaline->fs->sampler_unit + 1); + num_sampler_views = MAX2(num_samplers, aaline->num_sampler_views); aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit], @@ -681,7 +686,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) num_samplers, aaline->state.sampler); aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, - num_samplers, aaline->state.sampler_views); + num_sampler_views, aaline->state.sampler_views); /* Disable triangle culling, stippling, unfilled mode etc. */ r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade); @@ -774,7 +779,7 @@ static struct aaline_stage * draw_aaline_stage(struct draw_context *draw) { struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); - if (aaline == NULL) + if (!aaline) return NULL; aaline->stage.draw = draw; @@ -793,8 +798,7 @@ draw_aaline_stage(struct draw_context *draw) return aaline; fail: - if (aaline) - aaline->stage.destroy(&aaline->stage); + aaline->stage.destroy(&aaline->stage); return NULL; } @@ -824,12 +828,12 @@ aaline_create_fs_state(struct pipe_context *pipe, struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = NULL; - if (aaline == NULL) + if (!aaline) return NULL; aafs = CALLOC_STRUCT(aaline_fragment_shader); - if (aafs == NULL) + if (!aafs) return NULL; aafs->state.tokens = tgsi_dup_tokens(fs->tokens); @@ -847,7 +851,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs) struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - if (aaline == NULL) { + if (!aaline) { return; } @@ -864,11 +868,11 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs) struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - if (aafs == NULL) { + if (!aafs) { return; } - if (aaline != NULL) { + if (aaline) { /* pass-through */ aaline->driver_delete_fs_state(pipe, aafs->driver_fs); @@ -882,14 +886,15 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs) static void -aaline_bind_sampler_states(struct pipe_context *pipe, unsigned shader, +aaline_bind_sampler_states(struct pipe_context *pipe, + enum pipe_shader_type shader, unsigned start, unsigned num, void **sampler) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); assert(start == 0); - if (aaline == NULL) { + if (!aaline) { return; } @@ -905,14 +910,15 @@ aaline_bind_sampler_states(struct pipe_context *pipe, unsigned shader, static void -aaline_set_sampler_views(struct pipe_context *pipe, unsigned shader, +aaline_set_sampler_views(struct pipe_context *pipe, + enum pipe_shader_type shader, unsigned start, unsigned num, struct pipe_sampler_view **views) { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); uint i; - if (aaline == NULL) { + if (!aaline) { return; } @@ -938,7 +944,7 @@ draw_aaline_prepare_outputs(struct draw_context *draw, const struct pipe_rasterizer_state *rast = draw->rasterizer; /* update vertex attrib info */ - aaline->pos_slot = draw_current_shader_position_output(draw);; + aaline->pos_slot = draw_current_shader_position_output(draw); if (!rast->line_smooth) return; diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 391892329..33ef8ec17 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -240,7 +240,8 @@ aa_transform_prolog(struct tgsi_transform_context *ctx) TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W); /* KILL_IF -tmp0.yyyy; # if -tmp0.y < 0, KILL */ - tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y); + tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0, + TGSI_SWIZZLE_Y, TRUE); /* compute coverage factor = (1-d)/(1-k) */ @@ -661,7 +662,7 @@ static struct aapoint_stage * draw_aapoint_stage(struct draw_context *draw) { struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); - if (aapoint == NULL) + if (!aapoint) goto fail; aapoint->stage.draw = draw; @@ -706,7 +707,7 @@ aapoint_create_fs_state(struct pipe_context *pipe, { struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); - if (aafs == NULL) + if (!aafs) return NULL; aafs->state.tokens = tgsi_dup_tokens(fs->tokens); @@ -766,7 +767,7 @@ draw_install_aapoint_stage(struct draw_context *draw, * Create / install AA point drawing / prim stage */ aapoint = draw_aapoint_stage( draw ); - if (aapoint == NULL) + if (!aapoint) return FALSE; /* save original driver functions */ diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_validate.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_validate.c index e69d84a37..01d07593d 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -326,7 +326,7 @@ static void validate_destroy( struct draw_stage *stage ) struct draw_stage *draw_validate_stage( struct draw_context *draw ) { struct draw_stage *stage = CALLOC_STRUCT(draw_stage); - if (stage == NULL) + if (!stage) return NULL; stage->draw = draw; diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 5cc866d7e..6df7149b5 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -74,9 +74,10 @@ struct vbuf_stage { unsigned max_indices; unsigned nr_indices; - /* Cache point size somewhere it's address won't change: + /* Cache point size somewhere its address won't change: */ float point_size; + float zero4[4]; struct translate_cache *cache; }; @@ -205,6 +206,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) struct translate_key hw_key; unsigned dst_offset; unsigned i; + const struct vertex_info *vinfo; vbuf->render->set_primitive(vbuf->render, prim); @@ -215,27 +217,33 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) * state change. */ vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); + vinfo = vbuf->vinfo; + vbuf->vertex_size = vinfo->size * sizeof(float); /* Translate from pipeline vertices to hw vertices. */ dst_offset = 0; - for (i = 0; i < vbuf->vinfo->num_attribs; i++) { + for (i = 0; i < vinfo->num_attribs; i++) { unsigned emit_sz = 0; unsigned src_buffer = 0; enum pipe_format output_format; - unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 * sizeof(float) ); + unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) ); - output_format = draw_translate_vinfo_format(vbuf->vinfo->attrib[i].emit); - emit_sz = draw_translate_vinfo_size(vbuf->vinfo->attrib[i].emit); + output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit); + emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit); /* doesn't handle EMIT_OMIT */ assert(emit_sz != 0); - if (vbuf->vinfo->attrib[i].emit == EMIT_1F_PSIZE) { - src_buffer = 1; - src_offset = 0; + if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) { + src_buffer = 1; + src_offset = 0; + } + else if (vinfo->attrib[i].src_index == DRAW_ATTR_NONEXIST) { + /* elements which don't exist will get assigned zeros */ + src_buffer = 2; + src_offset = 0; } hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; @@ -249,7 +257,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) dst_offset += emit_sz; } - hw_key.nr_elements = vbuf->vinfo->num_attribs; + hw_key.nr_elements = vinfo->num_attribs; hw_key.output_stride = vbuf->vertex_size; /* Don't bother with caching at this stage: @@ -261,6 +269,7 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim ) vbuf->translate = translate_cache_find(vbuf->cache, &hw_key); vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0, ~0); + vbuf->translate->set_buffer(vbuf->translate, 2, &vbuf->zero4[0], 0, ~0); } vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; @@ -426,9 +435,9 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, struct vbuf_render *render ) { struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - if (vbuf == NULL) + if (!vbuf) goto fail; - + vbuf->stage.draw = draw; vbuf->stage.name = "vbuf"; vbuf->stage.point = vbuf_first_point; @@ -437,29 +446,30 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->stage.flush = vbuf_flush; vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; vbuf->stage.destroy = vbuf_destroy; - + vbuf->render = render; vbuf->max_indices = MIN2(render->max_indices, UNDEFINED_VERTEX_ID-1); - vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * - sizeof(vbuf->indices[0]), - 16 ); + vbuf->indices = (ushort *) align_malloc(vbuf->max_indices * + sizeof(vbuf->indices[0]), + 16); if (!vbuf->indices) goto fail; vbuf->cache = translate_cache_create(); - if (!vbuf->cache) + if (!vbuf->cache) goto fail; - - + vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; - + + vbuf->zero4[0] = vbuf->zero4[1] = vbuf->zero4[2] = vbuf->zero4[3] = 0.0f; + return &vbuf->stage; - fail: +fail: if (vbuf) vbuf_destroy(&vbuf->stage); - + return NULL; } diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 38ac11a9a..ae4a00eb6 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -202,7 +202,7 @@ static void wideline_destroy( struct draw_stage *stage ) struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) { struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); - if (wide == NULL) + if (!wide) goto fail; wide->stage.draw = draw; diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_private.h b/lib/mesa/src/gallium/auxiliary/draw/draw_private.h index 0ad94bb03..a6aa61052 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_private.h +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_private.h @@ -66,6 +66,8 @@ struct draw_stage; struct vbuf_render; struct tgsi_exec_machine; struct tgsi_sampler; +struct tgsi_image; +struct tgsi_buffer; struct draw_pt_front_end; struct draw_assembler; struct draw_llvm; @@ -86,11 +88,10 @@ struct draw_vertex_buffer { struct vertex_header { unsigned clipmask:DRAW_TOTAL_CLIP_PLANES; unsigned edgeflag:1; - unsigned have_clipdist:1; + unsigned pad:1; unsigned vertex_id:16; - float clip[4]; - float pre_clip_pos[4]; + float clip_pos[4]; /* This will probably become float (*data)[4] soon: */ @@ -261,13 +262,15 @@ struct draw_context uint position_output; uint edgeflag_output; uint clipvertex_output; - uint clipdistance_output[2]; + uint ccdistance_output[2]; /** Fields for TGSI interpreter / execution */ struct { struct tgsi_exec_machine *machine; struct tgsi_sampler *sampler; + struct tgsi_image *image; + struct tgsi_buffer *buffer; } tgsi; struct translate *fetch; @@ -287,6 +290,8 @@ struct draw_context struct tgsi_exec_machine *machine; struct tgsi_sampler *sampler; + struct tgsi_image *image; + struct tgsi_buffer *buffer; } tgsi; } gs; @@ -355,8 +360,9 @@ struct draw_vertex_info { }; /* these flags are set if the primitive is a segment of a larger one */ -#define DRAW_SPLIT_BEFORE 0x1 -#define DRAW_SPLIT_AFTER 0x2 +#define DRAW_SPLIT_BEFORE 0x1 +#define DRAW_SPLIT_AFTER 0x2 +#define DRAW_LINE_LOOP_AS_STRIP 0x4 struct draw_prim_info { boolean linear; @@ -400,9 +406,8 @@ uint draw_current_shader_outputs(const struct draw_context *draw); uint draw_current_shader_position_output(const struct draw_context *draw); uint draw_current_shader_viewport_index_output(const struct draw_context *draw); uint draw_current_shader_clipvertex_output(const struct draw_context *draw); -uint draw_current_shader_clipdistance_output(const struct draw_context *draw, int index); +uint draw_current_shader_ccdistance_output(const struct draw_context *draw, int index); uint draw_current_shader_num_written_clipdistances(const struct draw_context *draw); -uint draw_current_shader_culldistance_output(const struct draw_context *draw, int index); uint draw_current_shader_num_written_culldistances(const struct draw_context *draw); int draw_alloc_extra_vertex_attrib(struct draw_context *draw, uint semantic_name, uint semantic_index); diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index e42c4af0e..4033eddca 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -277,7 +277,7 @@ llvm_middle_end_bind_parameters(struct draw_pt_middle_end *middle) struct draw_llvm *llvm = fpme->llvm; unsigned i; - for (i = 0; i < Elements(llvm->jit_context.vs_constants); ++i) { + for (i = 0; i < ARRAY_SIZE(llvm->jit_context.vs_constants); ++i) { int num_consts = draw->pt.user.vs_constants_size[i] / (sizeof(float) * 4); llvm->jit_context.vs_constants[i] = draw->pt.user.vs_constants[i]; @@ -286,7 +286,7 @@ llvm_middle_end_bind_parameters(struct draw_pt_middle_end *middle) llvm->jit_context.vs_constants[i] = fake_const_buf; } } - for (i = 0; i < Elements(llvm->gs_jit_context.constants); ++i) { + for (i = 0; i < ARRAY_SIZE(llvm->gs_jit_context.constants); ++i) { int num_consts = draw->pt.user.gs_constants_size[i] / (sizeof(float) * 4); llvm->gs_jit_context.constants[i] = draw->pt.user.gs_constants[i]; @@ -453,6 +453,7 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle, draw->vs.vertex_shader->info.writes_viewport_index)) { clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info ); } + /* "clipped" also includes non-one edgeflag */ if (clipped) { opt |= PT_PIPELINE; } @@ -473,6 +474,16 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle, } +static inline unsigned +prim_type(unsigned prim, unsigned flags) +{ + if (flags & DRAW_LINE_LOOP_AS_STRIP) + return PIPE_PRIM_LINE_STRIP; + else + return prim; +} + + static void llvm_middle_end_run(struct draw_pt_middle_end *middle, const unsigned *fetch_elts, @@ -494,7 +505,7 @@ llvm_middle_end_run(struct draw_pt_middle_end *middle, prim_info.start = 0; prim_info.count = draw_count; prim_info.elts = draw_elts; - prim_info.prim = fpme->input_prim; + prim_info.prim = prim_type(fpme->input_prim, prim_flags); prim_info.flags = prim_flags; prim_info.primitive_count = 1; prim_info.primitive_lengths = &draw_count; @@ -522,7 +533,7 @@ llvm_middle_end_linear_run(struct draw_pt_middle_end *middle, prim_info.start = 0; prim_info.count = count; prim_info.elts = NULL; - prim_info.prim = fpme->input_prim; + prim_info.prim = prim_type(fpme->input_prim, prim_flags); prim_info.flags = prim_flags; prim_info.primitive_count = 1; prim_info.primitive_lengths = &count; @@ -552,7 +563,7 @@ llvm_middle_end_linear_run_elts(struct draw_pt_middle_end *middle, prim_info.start = 0; prim_info.count = draw_count; prim_info.elts = draw_elts; - prim_info.prim = fpme->input_prim; + prim_info.prim = prim_type(fpme->input_prim, prim_flags); prim_info.flags = prim_flags; prim_info.primitive_count = 1; prim_info.primitive_lengths = &draw_count; diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h index 0afabb013..6da79b949 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h @@ -249,6 +249,9 @@ vsplit_segment_loop_linear(struct vsplit_frontend *vsplit, unsigned flags, assert(icount + !!close_loop <= vsplit->segment_size); + /* need to draw the sections of the line loop as line strips */ + flags |= DRAW_LINE_LOOP_AS_STRIP; + if (close_loop) { for (nr = 0; nr < icount; nr++) vsplit->fetch_elts[nr] = istart + nr; |