Am 16.01.2014 03:09, schrieb Zack Rusin: > It's possible to bind a smaller buffer as a constant buffer, than > what the shader actually uses/requires. This could cause nasty > crashes. This patch adds the architecture to pass the maximum > allowable constant buffer index to the jit to let it make > sure that the constant buffer indices are always within bounds. > The behavior follows the d3d10 spec, which says the overflow > should always return all zeros, and overflow is only defined > as access beyond the size of the currently bound buffer. Accesses > beyond the declared shader constant register size are not > considered an overflow and expected to return garbage but consistent > garbage (we follow the behavior which some wlk tests expect which > is to return the actual values from the bound buffer). > > Signed-off-by: Zack Rusin <za...@vmware.com> > --- > src/gallium/auxiliary/draw/draw_llvm.c | 42 ++++++---- > src/gallium/auxiliary/draw/draw_llvm.h | 32 +++++--- > .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 6 ++ > src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 2 + > src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 89 > ++++++++++++++++++---- > src/gallium/drivers/llvmpipe/lp_jit.c | 7 +- > src/gallium/drivers/llvmpipe/lp_jit.h | 5 ++ > src/gallium/drivers/llvmpipe/lp_setup.c | 7 +- > src/gallium/drivers/llvmpipe/lp_state_fs.c | 5 +- > 9 files changed, 152 insertions(+), 43 deletions(-) > > diff --git a/src/gallium/auxiliary/draw/draw_llvm.c > b/src/gallium/auxiliary/draw/draw_llvm.c > index 331039a..0bbb680 100644 > --- a/src/gallium/auxiliary/draw/draw_llvm.c > +++ b/src/gallium/auxiliary/draw/draw_llvm.c > @@ -242,17 +242,20 @@ create_jit_context_type(struct gallivm_state *gallivm, > { > LLVMTargetDataRef target = gallivm->target; > LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context); > + LLVMTypeRef int_type = LLVMInt32TypeInContext(gallivm->context); > LLVMTypeRef elem_types[DRAW_JIT_CTX_NUM_FIELDS]; > LLVMTypeRef context_type; > > elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* > vs_constants */ > LP_MAX_TGSI_CONST_BUFFERS); > - elem_types[1] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, > 4), > + elem_types[1] = LLVMArrayType(int_type, /* num_vs_constants */ > + LP_MAX_TGSI_CONST_BUFFERS); > + elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, > 4), > DRAW_TOTAL_CLIP_PLANES), 0); > - elem_types[2] = LLVMPointerType(float_type, 0); /* viewport */ > - elem_types[3] = LLVMArrayType(texture_type, > + elem_types[3] = LLVMPointerType(float_type, 0); /* viewport */ > + elem_types[4] = LLVMArrayType(texture_type, > PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures > */ > - elem_types[4] = LLVMArrayType(sampler_type, > + elem_types[5] = LLVMArrayType(sampler_type, > PIPE_MAX_SAMPLERS); /* samplers */ > context_type = LLVMStructTypeInContext(gallivm->context, elem_types, > Elements(elem_types), 0); > @@ -264,6 +267,8 @@ create_jit_context_type(struct gallivm_state *gallivm, > > 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, > + target, context_type, DRAW_JIT_CTX_NUM_CONSTANTS); > LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes, > target, context_type, DRAW_JIT_CTX_PLANES); > LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, viewport, > @@ -298,20 +303,22 @@ create_gs_jit_context_type(struct gallivm_state > *gallivm, > > elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* > constants */ > LP_MAX_TGSI_CONST_BUFFERS); > - elem_types[1] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, > 4), > + elem_types[1] = LLVMArrayType(int_type, /* num_constants */ > + LP_MAX_TGSI_CONST_BUFFERS); > + elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(float_type, > 4), > DRAW_TOTAL_CLIP_PLANES), 0); > - elem_types[2] = LLVMPointerType(float_type, 0); /* viewport */ > + elem_types[3] = LLVMPointerType(float_type, 0); /* viewport */ > > - elem_types[3] = LLVMArrayType(texture_type, > + elem_types[4] = LLVMArrayType(texture_type, > PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures > */ > - elem_types[4] = LLVMArrayType(sampler_type, > + elem_types[5] = LLVMArrayType(sampler_type, > PIPE_MAX_SAMPLERS); /* samplers */ > > - elem_types[5] = LLVMPointerType(LLVMPointerType(int_type, 0), 0); > - elem_types[6] = LLVMPointerType(LLVMVectorType(int_type, > - vector_length), 0); > + elem_types[6] = LLVMPointerType(LLVMPointerType(int_type, 0), 0); > elem_types[7] = LLVMPointerType(LLVMVectorType(int_type, > vector_length), 0); > + elem_types[8] = LLVMPointerType(LLVMVectorType(int_type, > + vector_length), 0); > > context_type = LLVMStructTypeInContext(gallivm->context, elem_types, > Elements(elem_types), 0); > @@ -323,6 +330,8 @@ create_gs_jit_context_type(struct gallivm_state *gallivm, > > LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, constants, > target, context_type, DRAW_GS_JIT_CTX_CONSTANTS); > + LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, num_constants, > + target, context_type, > DRAW_GS_JIT_CTX_NUM_CONSTANTS); > LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, planes, > target, context_type, DRAW_GS_JIT_CTX_PLANES); > LP_CHECK_MEMBER_OFFSET(struct draw_gs_jit_context, viewport, > @@ -617,7 +626,10 @@ generate_vs(struct draw_llvm_variant *variant, > { > struct draw_llvm *llvm = variant->llvm; > const struct tgsi_token *tokens = > llvm->draw->vs.vertex_shader->state.tokens; > - LLVMValueRef consts_ptr = draw_jit_context_vs_constants(variant->gallivm, > context_ptr); > + LLVMValueRef consts_ptr = > + draw_jit_context_vs_constants(variant->gallivm, context_ptr); > + LLVMValueRef num_consts_ptr = > + draw_jit_context_num_vs_constants(variant->gallivm, context_ptr); > struct lp_build_sampler_soa *sampler = 0; > > if (gallivm_debug & (GALLIVM_DEBUG_TGSI | GALLIVM_DEBUG_IR)) { > @@ -633,6 +645,7 @@ generate_vs(struct draw_llvm_variant *variant, > vs_type, > NULL /*struct lp_build_mask_context *mask*/, > consts_ptr, > + num_consts_ptr, > system_values, > inputs, > outputs, > @@ -2089,7 +2102,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, > unsigned i; > struct draw_gs_llvm_iface gs_iface; > const struct tgsi_token *tokens = variant->shader->base.state.tokens; > - LLVMValueRef consts_ptr; > + LLVMValueRef consts_ptr, num_consts_ptr; > LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS]; > struct lp_build_mask_context mask; > const struct tgsi_shader_info *gs_info = &variant->shader->base.info; > @@ -2163,6 +2176,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, > gs_type.length = vector_length; > > consts_ptr = draw_gs_jit_context_constants(variant->gallivm, context_ptr); > + num_consts_ptr = > + draw_gs_jit_context_num_constants(variant->gallivm, context_ptr); > > /* code generated texture sampling */ > sampler = draw_llvm_sampler_soa_create(variant->key.samplers, > @@ -2185,6 +2200,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, > gs_type, > &mask, > consts_ptr, > + num_consts_ptr, > &system_values, > NULL, > outputs, > diff --git a/src/gallium/auxiliary/draw/draw_llvm.h > b/src/gallium/auxiliary/draw/draw_llvm.h > index 1d238a2..2e465b2 100644 > --- a/src/gallium/auxiliary/draw/draw_llvm.h > +++ b/src/gallium/auxiliary/draw/draw_llvm.h > @@ -123,6 +123,7 @@ enum { > struct draw_jit_context > { > const float *vs_constants[LP_MAX_TGSI_CONST_BUFFERS]; > + int num_vs_constants[LP_MAX_TGSI_CONST_BUFFERS]; > float (*planes) [DRAW_TOTAL_CLIP_PLANES][4]; > float *viewport; > > @@ -131,17 +132,21 @@ struct draw_jit_context > }; > > enum { > - DRAW_JIT_CTX_CONSTANTS = 0, > - DRAW_JIT_CTX_PLANES = 1, > - DRAW_JIT_CTX_VIEWPORT = 2, > - DRAW_JIT_CTX_TEXTURES = 3, > - DRAW_JIT_CTX_SAMPLERS = 4, > + DRAW_JIT_CTX_CONSTANTS = 0, > + DRAW_JIT_CTX_NUM_CONSTANTS = 1, > + DRAW_JIT_CTX_PLANES = 2, > + DRAW_JIT_CTX_VIEWPORT = 3, > + DRAW_JIT_CTX_TEXTURES = 4, > + DRAW_JIT_CTX_SAMPLERS = 5, > DRAW_JIT_CTX_NUM_FIELDS > }; > > #define draw_jit_context_vs_constants(_gallivm, _ptr) \ > lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_CONSTANTS, > "vs_constants") > > +#define draw_jit_context_num_vs_constants(_gallivm, _ptr) \ > + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_NUM_CONSTANTS, > "num_vs_constants") > + > #define draw_jit_context_planes(_gallivm, _ptr) \ > lp_build_struct_get(_gallivm, _ptr, DRAW_JIT_CTX_PLANES, "planes") > > @@ -200,6 +205,7 @@ enum { > struct draw_gs_jit_context > { > const float *constants[LP_MAX_TGSI_CONST_BUFFERS]; > + int num_constants[LP_MAX_TGSI_CONST_BUFFERS]; > float (*planes) [DRAW_TOTAL_CLIP_PLANES][4]; > float *viewport; > > @@ -215,23 +221,27 @@ struct draw_gs_jit_context > > enum { > DRAW_GS_JIT_CTX_CONSTANTS = 0, > - DRAW_GS_JIT_CTX_PLANES = 1, > - DRAW_GS_JIT_CTX_VIEWPORT = 2, > + DRAW_GS_JIT_CTX_NUM_CONSTANTS = 1, > + DRAW_GS_JIT_CTX_PLANES = 2, > + DRAW_GS_JIT_CTX_VIEWPORT = 3, > /* Textures and samples are reserved for DRAW_JIT_CTX_TEXTURES > * and DRAW_JIT_CTX_SAMPLERS, because they both need > * to be at exactly the same locations as they are in the > * VS ctx structure for sampling to work. */ > DRAW_GS_JIT_CTX_TEXTURES = DRAW_JIT_CTX_TEXTURES, > DRAW_GS_JIT_CTX_SAMPLERS = DRAW_JIT_CTX_SAMPLERS, > - DRAW_GS_JIT_CTX_PRIM_LENGTHS = 5, > - DRAW_GS_JIT_CTX_EMITTED_VERTICES = 6, > - DRAW_GS_JIT_CTX_EMITTED_PRIMS = 7, > - DRAW_GS_JIT_CTX_NUM_FIELDS = 8 > + DRAW_GS_JIT_CTX_PRIM_LENGTHS = 6, > + DRAW_GS_JIT_CTX_EMITTED_VERTICES = 7, > + DRAW_GS_JIT_CTX_EMITTED_PRIMS = 8, > + DRAW_GS_JIT_CTX_NUM_FIELDS = 9 > }; > > #define draw_gs_jit_context_constants(_gallivm, _ptr) \ > lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_CONSTANTS, > "constants") > > +#define draw_gs_jit_context_num_constants(_gallivm, _ptr) \ > + lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_GS_JIT_CTX_NUM_CONSTANTS, > "num_constants") > + > #define draw_gs_jit_context_planes(_gallivm, _ptr) \ > lp_build_struct_get(_gallivm, _ptr, DRAW_GS_JIT_CTX_PLANES, "planes") > > 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 9f17241..5a6d059 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 > @@ -262,10 +262,16 @@ llvm_middle_end_bind_parameters(struct > draw_pt_middle_end *middle) > unsigned i; > > for (i = 0; i < Elements(fpme->llvm->jit_context.vs_constants); ++i) { > + int num_consts = > + ceil(draw->pt.user.vs_constants_size[i] / (sizeof(float) * 4)); I don't know what the ceil is supposed to do but it doesn't look like it could work since the division is all ints already.
> fpme->llvm->jit_context.vs_constants[i] = > draw->pt.user.vs_constants[i]; > + fpme->llvm->jit_context.num_vs_constants[i] = num_consts; > } > for (i = 0; i < Elements(fpme->llvm->gs_jit_context.constants); ++i) { > + int num_consts = > + ceil(draw->pt.user.gs_constants_size[i] / (sizeof(float) * 4)); Same as above. > fpme->llvm->gs_jit_context.constants[i] = > draw->pt.user.gs_constants[i]; > + fpme->llvm->gs_jit_context.num_constants[i] = num_consts; > } > > fpme->llvm->jit_context.planes = > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > index 881cd5b..4f988b8 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h > @@ -225,6 +225,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, > struct lp_type type, > struct lp_build_mask_context *mask, > LLVMValueRef consts_ptr, > + LLVMValueRef const_sizes_ptr, > const struct lp_bld_tgsi_system_values *system_values, > const LLVMValueRef (*inputs)[4], > LLVMValueRef (*outputs)[4], > @@ -433,6 +434,7 @@ struct lp_build_tgsi_soa_context > LLVMValueRef max_output_vertices_vec; > > LLVMValueRef consts_ptr; > + LLVMValueRef const_sizes_ptr; > const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS]; > LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS]; > > diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > index 6d8dc8c..0bf781b 100644 > --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c > @@ -789,11 +789,19 @@ gather_outputs(struct lp_build_tgsi_soa_context * bld) > static LLVMValueRef > build_gather(struct lp_build_context *bld, > LLVMValueRef base_ptr, > - LLVMValueRef indexes) > + LLVMValueRef indexes, > + LLVMValueRef *overflow_mask) > { > LLVMBuilderRef builder = bld->gallivm->builder; > LLVMValueRef res = bld->undef; > unsigned i; > + LLVMValueRef temp_ptr; > + > + if (overflow_mask) { > + temp_ptr = lp_build_alloca( > + bld->gallivm, > + lp_build_vec_type(bld->gallivm, bld->type), ""); > + } > > /* > * Loop over elements of index_vec, load scalar value, insert it into > 'res'. > @@ -802,11 +810,46 @@ build_gather(struct lp_build_context *bld, > LLVMValueRef ii = lp_build_const_int32(bld->gallivm, i); > LLVMValueRef index = LLVMBuildExtractElement(builder, > indexes, ii, ""); > - LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, > - &index, 1, "gather_ptr"); > - LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, ""); > + LLVMValueRef scalar_ptr, scalar; > + LLVMValueRef overflow; > + struct lp_build_if_state if_ctx; > + > + if (overflow_mask) { > + overflow = LLVMBuildExtractElement(builder, *overflow_mask, > + ii, ""); > + lp_build_if(&if_ctx, bld->gallivm, overflow); > + { > + LLVMValueRef val = LLVMBuildLoad(builder, temp_ptr, ""); > + val = LLVMBuildInsertElement( > + builder, val, > + LLVMConstNull(LLVMFloatTypeInContext(bld->gallivm->context)), > + ii, ""); > + LLVMBuildStore(builder, val, temp_ptr); > + } > + lp_build_else(&if_ctx); > + { > + LLVMValueRef val = LLVMBuildLoad(builder, temp_ptr, ""); > + > + scalar_ptr = LLVMBuildGEP(builder, base_ptr, > + &index, 1, "gather_ptr"); > + scalar = LLVMBuildLoad(builder, scalar_ptr, ""); > + > + val = LLVMBuildInsertElement(builder, val, scalar, ii, ""); > + > + LLVMBuildStore(builder, val, temp_ptr); > + } > + lp_build_endif(&if_ctx); > + } else { > + scalar_ptr = LLVMBuildGEP(builder, base_ptr, > + &index, 1, "gather_ptr"); > + scalar = LLVMBuildLoad(builder, scalar_ptr, ""); > + > + res = LLVMBuildInsertElement(builder, res, scalar, ii, ""); > + } > + } > > - res = LLVMBuildInsertElement(builder, res, scalar, ii, ""); > + if (overflow_mask) { > + res = LLVMBuildLoad(builder, temp_ptr, "gather_val"); > } > > return res; > @@ -912,12 +955,14 @@ get_indirect_index(struct lp_build_tgsi_soa_context > *bld, > > index = lp_build_add(uint_bld, base, rel); > > - max_index = lp_build_const_int_vec(bld->bld_base.base.gallivm, > - uint_bld->type, > - > bld->bld_base.info->file_max[reg_file]); > + if (reg_file != TGSI_FILE_CONSTANT) { > + max_index = lp_build_const_int_vec(bld->bld_base.base.gallivm, > + uint_bld->type, > + > bld->bld_base.info->file_max[reg_file]); > > - assert(!uint_bld->type.sign); > - index = lp_build_min(uint_bld, index, max_index); > + assert(!uint_bld->type.sign); > + index = lp_build_min(uint_bld, index, max_index); > + } > > return index; > } > @@ -996,6 +1041,7 @@ emit_fetch_constant( > unsigned dimension = 0; > LLVMValueRef dimension_index; > LLVMValueRef consts_ptr; > + LLVMValueRef num_consts; > LLVMValueRef res; > > /* XXX: Handle fetching xyzw components as a vector */ > @@ -1008,25 +1054,35 @@ emit_fetch_constant( > } > > dimension_index = lp_build_const_int32(gallivm, dimension); > - consts_ptr = lp_build_array_get(gallivm, bld->consts_ptr, > dimension_index); > + consts_ptr = > + lp_build_array_get(gallivm, bld->consts_ptr, dimension_index); > + num_consts = > + lp_build_array_get(gallivm, bld->const_sizes_ptr, dimension_index); > > if (reg->Register.Indirect) { > LLVMValueRef indirect_index; > LLVMValueRef swizzle_vec = > lp_build_const_int_vec(gallivm, uint_bld->type, swizzle); > LLVMValueRef index_vec; /* index into the const buffer */ > + LLVMValueRef overflow_mask; > > indirect_index = get_indirect_index(bld, > reg->Register.File, > reg->Register.Index, > ®->Indirect); > > + num_consts = lp_build_broadcast_scalar(uint_bld, num_consts); > + overflow_mask = LLVMBuildICmp(builder, LLVMIntUGE, > + indirect_index, > + num_consts, ""); > + > /* index_vec = indirect_index * 4 + swizzle */ > index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); > index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); > > /* Gather values from the constant buffer */ > - res = build_gather(&bld_base->base, consts_ptr, index_vec); > + res = build_gather(&bld_base->base, consts_ptr, index_vec, > + &overflow_mask); > } > else { > LLVMValueRef index; /* index into the const buffer */ > @@ -1044,6 +1100,7 @@ emit_fetch_constant( > struct lp_build_context *bld_fetch = stype_to_fetch(bld_base, stype); > res = LLVMBuildBitCast(builder, res, bld_fetch->vec_type, ""); > } > + > return res; > } > > @@ -1085,7 +1142,7 @@ emit_fetch_immediate( > imms_array = LLVMBuildBitCast(builder, bld->imms_array, fptr_type, ""); > > /* Gather values from the immediate register array */ > - res = build_gather(&bld_base->base, imms_array, index_vec); > + res = build_gather(&bld_base->base, imms_array, index_vec, 0); > } > else { > res = bld->immediates[reg->Register.Index][swizzle]; > @@ -1132,7 +1189,7 @@ emit_fetch_input( > inputs_array = LLVMBuildBitCast(builder, bld->inputs_array, fptr_type, > ""); > > /* Gather values from the input register array */ > - res = build_gather(&bld_base->base, inputs_array, index_vec); > + res = build_gather(&bld_base->base, inputs_array, index_vec, 0); > } else { > if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) { > LLVMValueRef lindex = lp_build_const_int32(gallivm, > @@ -1242,7 +1299,7 @@ emit_fetch_temporary( > temps_array = LLVMBuildBitCast(builder, bld->temps_array, fptr_type, > ""); > > /* Gather values from the temporary register array */ > - res = build_gather(&bld_base->base, temps_array, index_vec); > + res = build_gather(&bld_base->base, temps_array, index_vec, 0); > } > else { > LLVMValueRef temp_ptr; > @@ -3352,6 +3409,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, > struct lp_type type, > struct lp_build_mask_context *mask, > LLVMValueRef consts_ptr, > + LLVMValueRef const_sizes_ptr, > const struct lp_bld_tgsi_system_values *system_values, > const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS], > LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], > @@ -3379,6 +3437,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, > bld.inputs = inputs; > bld.outputs = outputs; > bld.consts_ptr = consts_ptr; > + bld.const_sizes_ptr = const_sizes_ptr; > bld.sampler = sampler; > bld.bld_base.info = info; > bld.indirect_files = info->indirect_files; > diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c > b/src/gallium/drivers/llvmpipe/lp_jit.c > index fa36fd3..075bd14 100644 > --- a/src/gallium/drivers/llvmpipe/lp_jit.c > +++ b/src/gallium/drivers/llvmpipe/lp_jit.c > @@ -166,7 +166,9 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp) > LLVMTypeRef context_type; > > elem_types[LP_JIT_CTX_CONSTANTS] = > - LLVMArrayType(LLVMPointerType(LLVMFloatTypeInContext(lc), 0), > LP_MAX_TGSI_CONST_BUFFERS); > + LLVMArrayType(LLVMPointerType(LLVMFloatTypeInContext(lc), 0), > LP_MAX_TGSI_CONST_BUFFERS); > + elem_types[LP_JIT_CTX_NUM_CONSTANTS] = > + LLVMArrayType(LLVMInt32TypeInContext(lc), > LP_MAX_TGSI_CONST_BUFFERS); > elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc); > elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = > elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc); > @@ -190,6 +192,9 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp) > LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants, > gallivm->target, context_type, > LP_JIT_CTX_CONSTANTS); > + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, num_constants, > + gallivm->target, context_type, > + LP_JIT_CTX_NUM_CONSTANTS); > LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, > gallivm->target, context_type, > LP_JIT_CTX_ALPHA_REF); > diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h > b/src/gallium/drivers/llvmpipe/lp_jit.h > index 8eefa7c..1325a8c 100644 > --- a/src/gallium/drivers/llvmpipe/lp_jit.h > +++ b/src/gallium/drivers/llvmpipe/lp_jit.h > @@ -121,6 +121,7 @@ enum { > struct lp_jit_context > { > const float *constants[LP_MAX_TGSI_CONST_BUFFERS]; > + int num_constants[LP_MAX_TGSI_CONST_BUFFERS]; > > float alpha_ref_value; > > @@ -142,6 +143,7 @@ struct lp_jit_context > */ > enum { > LP_JIT_CTX_CONSTANTS = 0, > + LP_JIT_CTX_NUM_CONSTANTS, > LP_JIT_CTX_ALPHA_REF, > LP_JIT_CTX_STENCIL_REF_FRONT, > LP_JIT_CTX_STENCIL_REF_BACK, > @@ -157,6 +159,9 @@ enum { > #define lp_jit_context_constants(_gallivm, _ptr) \ > lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_CONSTANTS, "constants") > > +#define lp_jit_context_num_constants(_gallivm, _ptr) \ > + lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_NUM_CONSTANTS, > "num_constants") > + > #define lp_jit_context_alpha_ref_value(_gallivm, _ptr) \ > lp_build_struct_get(_gallivm, _ptr, LP_JIT_CTX_ALPHA_REF, > "alpha_ref_value") > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c > b/src/gallium/drivers/llvmpipe/lp_setup.c > index 7f22231..3d33003 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup.c > @@ -984,6 +984,7 @@ try_update_scene_state( struct lp_setup_context *setup ) > struct pipe_resource *buffer = setup->constants[i].current.buffer; > const unsigned current_size = > setup->constants[i].current.buffer_size; > const ubyte *current_data = NULL; > + int num_constants; > > if (buffer) { > /* resource buffer */ > @@ -1024,7 +1025,11 @@ try_update_scene_state( struct lp_setup_context *setup > ) > setup->constants[i].stored_data = NULL; > } > > - setup->fs.current.jit_context.constants[i] = > setup->constants[i].stored_data; > + setup->fs.current.jit_context.constants[i] = > + setup->constants[i].stored_data; > + num_constants = > + ceil(setup->constants[i].stored_size / (sizeof(float) * 4)); Same as above. > + setup->fs.current.jit_context.num_constants[i] = num_constants; > setup->dirty |= LP_SETUP_NEW_FS; > } > } > diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c > b/src/gallium/drivers/llvmpipe/lp_state_fs.c > index eedafa3..31ed847 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c > @@ -262,7 +262,7 @@ generate_fs_loop(struct gallivm_state *gallivm, > const struct tgsi_token *tokens = shader->base.tokens; > LLVMTypeRef vec_type; > LLVMValueRef mask_ptr, mask_val; > - LLVMValueRef consts_ptr; > + LLVMValueRef consts_ptr, num_consts_ptr; > LLVMValueRef z; > LLVMValueRef z_value, s_value; > LLVMValueRef z_fb, s_fb; > @@ -336,6 +336,7 @@ generate_fs_loop(struct gallivm_state *gallivm, > vec_type = lp_build_vec_type(gallivm, type); > > consts_ptr = lp_jit_context_constants(gallivm, context_ptr); > + num_consts_ptr = lp_jit_context_num_constants(gallivm, context_ptr); > > lp_build_for_loop_begin(&loop_state, gallivm, > lp_build_const_int32(gallivm, 0), > @@ -414,7 +415,7 @@ generate_fs_loop(struct gallivm_state *gallivm, > > /* Build the actual shader */ > lp_build_tgsi_soa(gallivm, tokens, type, &mask, > - consts_ptr, &system_values, > + consts_ptr, num_consts_ptr, &system_values, > interp->inputs, > outputs, sampler, &shader->info.base, NULL); > > Otherwise looks good to me. Do you have a reference handy for the d3d10 requirement that buffer overflows must return 0 and could throw that in there as a comment somewhere along the overflow_mask handling? (Even if this isn't mentioned in the specs a comment would be nice in any case why this is required.) Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev