diff options
author | Zack Rusin <[email protected]> | 2013-12-18 19:16:07 -0500 |
---|---|---|
committer | Zack Rusin <[email protected]> | 2014-01-16 16:33:57 -0500 |
commit | 93b953d139112bea1c9c64a3de462cbb52c544fd (patch) | |
tree | ffb9b2c3867a9b396c361645aab66f3786cb5d37 /src/gallium/auxiliary/draw | |
parent | dd687fb8d090f08d09ac5e350a92f38ded837788 (diff) |
llvmpipe: do constant buffer bounds checking in shaders
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 <[email protected]>
Reviewed-by: Jose Fonseca <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Reviewed-by: Roland Scheidegger <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/draw')
-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 |
3 files changed, 56 insertions, 24 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 = |