X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_tex_sample.c;h=e0285c70e5b8d730f9d1843ad702211aab702380;hb=8c9b9aac7d09e65195dca6681d59c10e4ef713d9;hp=5d0d35091958f7c20eb468a014c7ddf08061a1ed;hpb=1d242b688265a405dfd8077ea32ac4ea673b02a2;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 5d0d3509195..e0285c70e5b 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -78,6 +78,23 @@ struct lp_llvm_sampler_soa struct llvmpipe_sampler_dynamic_state dynamic_state; }; +struct llvmpipe_image_dynamic_state +{ + struct lp_sampler_dynamic_state base; + + const struct lp_image_static_state *static_state; +}; + +/** + * This is the bridge between our sampler and the TGSI translator. + */ +struct lp_llvm_image_soa +{ + struct lp_build_image_soa base; + + struct llvmpipe_image_dynamic_state dynamic_state; +}; + /** * Fetch the specified member of the lp_jit_texture structure. @@ -155,6 +172,8 @@ LP_LLVM_TEXTURE_MEMBER(base_ptr, LP_JIT_TEXTURE_BASE, TRUE) LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE) LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE) LP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE) +LP_LLVM_TEXTURE_MEMBER(num_samples, LP_JIT_TEXTURE_NUM_SAMPLES, TRUE) +LP_LLVM_TEXTURE_MEMBER(sample_stride, LP_JIT_TEXTURE_SAMPLE_STRIDE, TRUE) /** @@ -221,6 +240,82 @@ LP_LLVM_SAMPLER_MEMBER(lod_bias, LP_JIT_SAMPLER_LOD_BIAS, TRUE) LP_LLVM_SAMPLER_MEMBER(border_color, LP_JIT_SAMPLER_BORDER_COLOR, FALSE) +/** + * Fetch the specified member of the lp_jit_image structure. + * \param emit_load if TRUE, emit the LLVM load instruction to actually + * fetch the field's value. Otherwise, just emit the + * GEP code to address the field. + * + * @sa http://llvm.org/docs/GetElementPtr.html + */ +static LLVMValueRef +lp_llvm_image_member(const struct lp_sampler_dynamic_state *base, + struct gallivm_state *gallivm, + LLVMValueRef context_ptr, + unsigned image_unit, + unsigned member_index, + const char *member_name, + boolean emit_load) +{ + LLVMBuilderRef builder = gallivm->builder; + LLVMValueRef indices[4]; + LLVMValueRef ptr; + LLVMValueRef res; + + assert(image_unit < PIPE_MAX_SHADER_IMAGES); + + /* context[0] */ + indices[0] = lp_build_const_int32(gallivm, 0); + /* context[0].images */ + indices[1] = lp_build_const_int32(gallivm, LP_JIT_CTX_IMAGES); + /* context[0].images[unit] */ + indices[2] = lp_build_const_int32(gallivm, image_unit); + /* context[0].images[unit].member */ + indices[3] = lp_build_const_int32(gallivm, member_index); + + ptr = LLVMBuildGEP(builder, context_ptr, indices, ARRAY_SIZE(indices), ""); + + if (emit_load) + res = LLVMBuildLoad(builder, ptr, ""); + else + res = ptr; + + lp_build_name(res, "context.image%u.%s", image_unit, member_name); + + return res; +} + + +/** + * Helper macro to instantiate the functions that generate the code to + * fetch the members of lp_jit_image to fulfill the sampler code + * generator requests. + * + * This complexity is the price we have to pay to keep the image + * sampler code generator a reusable module without dependencies to + * llvmpipe internals. + */ +#define LP_LLVM_IMAGE_MEMBER(_name, _index, _emit_load) \ + static LLVMValueRef \ + lp_llvm_image_##_name( const struct lp_sampler_dynamic_state *base, \ + struct gallivm_state *gallivm, \ + LLVMValueRef context_ptr, \ + unsigned image_unit) \ + { \ + return lp_llvm_image_member(base, gallivm, context_ptr, \ + image_unit, _index, #_name, _emit_load ); \ + } + + +LP_LLVM_IMAGE_MEMBER(width, LP_JIT_IMAGE_WIDTH, TRUE) +LP_LLVM_IMAGE_MEMBER(height, LP_JIT_IMAGE_HEIGHT, TRUE) +LP_LLVM_IMAGE_MEMBER(depth, LP_JIT_IMAGE_DEPTH, TRUE) +LP_LLVM_IMAGE_MEMBER(base_ptr, LP_JIT_IMAGE_BASE, TRUE) +LP_LLVM_IMAGE_MEMBER(row_stride, LP_JIT_IMAGE_ROW_STRIDE, TRUE) +LP_LLVM_IMAGE_MEMBER(img_stride, LP_JIT_IMAGE_IMG_STRIDE, TRUE) +LP_LLVM_IMAGE_MEMBER(num_samples, LP_JIT_IMAGE_NUM_SAMPLES, TRUE) +LP_LLVM_IMAGE_MEMBER(sample_stride, LP_JIT_IMAGE_SAMPLE_STRIDE, TRUE) + #if LP_USE_TEXTURE_CACHE static LLVMValueRef lp_llvm_texture_cache_ptr(const struct lp_sampler_dynamic_state *base, @@ -310,6 +405,8 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state) sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride; sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride; sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets; + sampler->dynamic_state.base.num_samples = lp_llvm_texture_num_samples; + sampler->dynamic_state.base.sample_stride = lp_llvm_texture_sample_stride; sampler->dynamic_state.base.min_lod = lp_llvm_sampler_min_lod; sampler->dynamic_state.base.max_lod = lp_llvm_sampler_max_lod; sampler->dynamic_state.base.lod_bias = lp_llvm_sampler_lod_bias; @@ -324,3 +421,68 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state) return &sampler->base; } +static void +lp_llvm_image_soa_destroy(struct lp_build_image_soa *image) +{ + FREE(image); +} + +static void +lp_llvm_image_soa_emit_op(const struct lp_build_image_soa *base, + struct gallivm_state *gallivm, + const struct lp_img_params *params) +{ + struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base; + unsigned image_index = params->image_index; + assert(image_index < PIPE_MAX_SHADER_IMAGES); + + lp_build_img_op_soa(&image->dynamic_state.static_state[image_index].image_state, + &image->dynamic_state.base, + gallivm, params); +} + +/** + * Fetch the texture size. + */ +static void +lp_llvm_image_soa_emit_size_query(const struct lp_build_image_soa *base, + struct gallivm_state *gallivm, + const struct lp_sampler_size_query_params *params) +{ + struct lp_llvm_image_soa *image = (struct lp_llvm_image_soa *)base; + + assert(params->texture_unit < PIPE_MAX_SHADER_IMAGES); + + lp_build_size_query_soa(gallivm, + &image->dynamic_state.static_state[params->texture_unit].image_state, + &image->dynamic_state.base, + params); +} + +struct lp_build_image_soa * +lp_llvm_image_soa_create(const struct lp_image_static_state *static_state) +{ + struct lp_llvm_image_soa *image; + + image = CALLOC_STRUCT(lp_llvm_image_soa); + if (!image) + return NULL; + + image->base.destroy = lp_llvm_image_soa_destroy; + image->base.emit_op = lp_llvm_image_soa_emit_op; + image->base.emit_size_query = lp_llvm_image_soa_emit_size_query; + + image->dynamic_state.base.width = lp_llvm_image_width; + image->dynamic_state.base.height = lp_llvm_image_height; + + image->dynamic_state.base.depth = lp_llvm_image_depth; + image->dynamic_state.base.base_ptr = lp_llvm_image_base_ptr; + image->dynamic_state.base.row_stride = lp_llvm_image_row_stride; + image->dynamic_state.base.img_stride = lp_llvm_image_img_stride; + image->dynamic_state.base.num_samples = lp_llvm_image_num_samples; + image->dynamic_state.base.sample_stride = lp_llvm_image_sample_stride; + + image->dynamic_state.static_state = static_state; + + return &image->base; +}