diff options
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.c | 42 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm.h | 32 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 6 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 111 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 5 |
9 files changed, 174 insertions, 43 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 331039aad6e..0bbb6804984 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 1d238a2a9c2..2e465b2239c 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 9f172418544..846e1d58052 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 = + draw->pt.user.vs_constants_size[i] / (sizeof(float) * 4); 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 = + draw->pt.user.gs_constants_size[i] / (sizeof(float) * 4); 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 881cd5ba829..4f988b8fa4d 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 6d8dc8c6f19..d9b21f831ca 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,54 @@ 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; + + /* + * overflow_mask is a boolean vector telling us which channels + * in the vector overflowed. We use the overflow behavior for + * constant buffers which is defined as: + * Out of bounds access to constant buffer returns 0 in all + * componenets. Out of bounds behavior is always with respect + * to the size of the buffer bound at that slot. + */ + 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, ""); - res = LLVMBuildInsertElement(builder, res, 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, ""); + } + } + + if (overflow_mask) { + res = LLVMBuildLoad(builder, temp_ptr, "gather_val"); } return res; @@ -912,12 +963,23 @@ 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]); + /* + * emit_fetch_constant handles constant buffer overflow so this code + * is pointless for them. + * Furthermore the D3D10 spec in section 6.5 says: + * If the constant buffer bound to a slot is larger than the size + * declared in the shader for that slot, implementations are allowed + * to return incorrect data (not necessarily 0) for indices that are + * larger than the declared size but smaller than the buffer size. + */ + 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 +1058,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 +1071,40 @@ 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); + /* All fetches are from the same constant buffer, so + * we need to propagate the size to a vector to do a + * vector comparison */ + num_consts = lp_build_broadcast_scalar(uint_bld, num_consts); + /* Construct a boolean vector telling us which channels + * overflow the bound constant buffer */ + 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 +1122,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 +1164,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, NULL); } else { res = bld->immediates[reg->Register.Index][swizzle]; @@ -1132,7 +1211,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, NULL); } else { if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) { LLVMValueRef lindex = lp_build_const_int32(gallivm, @@ -1242,7 +1321,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, NULL); } else { LLVMValueRef temp_ptr; @@ -3352,6 +3431,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 +3459,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 fa36fd3512e..075bd148e88 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 8eefa7c8479..1325a8cc482 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 7f2223129aa..58811b0edd3 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 = + setup->constants[i].stored_size / (sizeof(float) * 4); + 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 eedafa36838..31ed8478e9b 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); |