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/drivers/llvmpipe | |
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/drivers/llvmpipe')
-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 |
4 files changed, 20 insertions, 4 deletions
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); |