From 26097c4855b97ee6e362c19df11d51fb7fd42192 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 12 Nov 2012 20:35:04 +0100 Subject: [PATCH] gallivm,draw,llvmpipe: use base ptr + mip offsets instead of mip pointers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This might have a slight overhead but handling mip offsets more like the width (and image) strides should make some things easier (mip level being just part of the offset calculation) later. Reviewed-by: Brian Paul Reviewed-by: José Fonseca --- src/gallium/auxiliary/draw/draw_context.c | 8 +-- src/gallium/auxiliary/draw/draw_context.h | 3 +- src/gallium/auxiliary/draw/draw_llvm.c | 19 ++++--- src/gallium/auxiliary/draw/draw_llvm.h | 9 ++-- src/gallium/auxiliary/draw/draw_llvm_sample.c | 6 ++- src/gallium/auxiliary/gallivm/lp_bld_sample.c | 7 +-- src/gallium/auxiliary/gallivm/lp_bld_sample.h | 13 +++-- .../auxiliary/gallivm/lp_bld_sample_soa.c | 8 +-- src/gallium/drivers/i915/i915_state.c | 12 ++--- src/gallium/drivers/llvmpipe/lp_jit.c | 14 ++--- src/gallium/drivers/llvmpipe/lp_jit.h | 6 ++- src/gallium/drivers/llvmpipe/lp_setup.c | 53 +++++++++++++------ .../drivers/llvmpipe/lp_state_sampler.c | 30 ++++++++--- src/gallium/drivers/llvmpipe/lp_tex_sample.c | 6 ++- 14 files changed, 131 insertions(+), 63 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 91dd2e1a20a..6980631b365 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -802,17 +802,19 @@ draw_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, uint32_t first_level, uint32_t last_level, + const void *base_ptr, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], - const void *data[PIPE_MAX_TEXTURE_LEVELS]) + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]) { if (shader_stage == PIPE_SHADER_VERTEX) { #ifdef HAVE_LLVM if (draw->llvm) draw_llvm_set_mapped_texture(draw, sampler_idx, - width, height, depth, first_level, last_level, - row_stride, img_stride, data); + width, height, depth, first_level, + last_level, base_ptr, + row_stride, img_stride, mip_offsets); #endif } } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 30633233fb0..a4937b6165f 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -154,9 +154,10 @@ draw_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, uint32_t first_level, uint32_t last_level, + const void *base, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], - const void *data[PIPE_MAX_TEXTURE_LEVELS]); + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]); /* diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index ebfe437261c..6f0e1de7481 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -79,12 +79,12 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name) elem_types[DRAW_JIT_TEXTURE_DEPTH] = elem_types[DRAW_JIT_TEXTURE_FIRST_LEVEL] = elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = int32_type; + elem_types[DRAW_JIT_TEXTURE_BASE] = + LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] = elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] = + elem_types[DRAW_JIT_TEXTURE_MIP_OFFSETS] = LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS); - elem_types[DRAW_JIT_TEXTURE_DATA] = - LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0), - PIPE_MAX_TEXTURE_LEVELS); elem_types[DRAW_JIT_TEXTURE_MIN_LOD] = elem_types[DRAW_JIT_TEXTURE_MAX_LOD] = elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(gallivm->context); @@ -118,15 +118,18 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name) LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level, target, texture_type, DRAW_JIT_TEXTURE_LAST_LEVEL); + LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, base, + target, texture_type, + DRAW_JIT_TEXTURE_BASE); LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride, target, texture_type, DRAW_JIT_TEXTURE_ROW_STRIDE); LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride, target, texture_type, DRAW_JIT_TEXTURE_IMG_STRIDE); - LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data, + LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, mip_offsets, target, texture_type, - DRAW_JIT_TEXTURE_DATA); + DRAW_JIT_TEXTURE_MIP_OFFSETS); LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod, target, texture_type, DRAW_JIT_TEXTURE_MIN_LOD); @@ -1364,9 +1367,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, uint32_t first_level, uint32_t last_level, + const void *base_ptr, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], - const void *data[PIPE_MAX_TEXTURE_LEVELS]) + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]) { unsigned j; struct draw_jit_texture *jit_tex; @@ -1380,9 +1384,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw, jit_tex->depth = depth; jit_tex->first_level = first_level; jit_tex->last_level = last_level; + jit_tex->base = base_ptr; for (j = first_level; j <= last_level; j++) { - jit_tex->data[j] = data[j]; + jit_tex->mip_offsets[j] = mip_offsets[j]; jit_tex->row_stride[j] = row_stride[j]; jit_tex->img_stride[j] = img_stride[j]; } diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 9a291a47627..d7a630eb015 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -47,9 +47,10 @@ struct draw_jit_texture uint32_t depth; uint32_t first_level; uint32_t last_level; + const void *base; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; - const void *data[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; float min_lod; float max_lod; float lod_bias; @@ -62,9 +63,10 @@ enum { DRAW_JIT_TEXTURE_DEPTH, DRAW_JIT_TEXTURE_FIRST_LEVEL, DRAW_JIT_TEXTURE_LAST_LEVEL, + DRAW_JIT_TEXTURE_BASE, DRAW_JIT_TEXTURE_ROW_STRIDE, DRAW_JIT_TEXTURE_IMG_STRIDE, - DRAW_JIT_TEXTURE_DATA, + DRAW_JIT_TEXTURE_MIP_OFFSETS, DRAW_JIT_TEXTURE_MIN_LOD, DRAW_JIT_TEXTURE_MAX_LOD, DRAW_JIT_TEXTURE_LOD_BIAS, @@ -293,8 +295,9 @@ draw_llvm_set_mapped_texture(struct draw_context *draw, unsigned sampler_idx, uint32_t width, uint32_t height, uint32_t depth, uint32_t first_level, uint32_t last_level, + const void *base_ptr, uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS], uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS], - const void *data[PIPE_MAX_TEXTURE_LEVELS]); + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]); #endif diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c index 53317165557..0892d16bd6d 100644 --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c @@ -146,9 +146,10 @@ DRAW_LLVM_TEXTURE_MEMBER(height, DRAW_JIT_TEXTURE_HEIGHT, TRUE) DRAW_LLVM_TEXTURE_MEMBER(depth, DRAW_JIT_TEXTURE_DEPTH, TRUE) DRAW_LLVM_TEXTURE_MEMBER(first_level,DRAW_JIT_TEXTURE_FIRST_LEVEL, TRUE) DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE) +DRAW_LLVM_TEXTURE_MEMBER(base_ptr, DRAW_JIT_TEXTURE_BASE, TRUE) DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE) DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE) -DRAW_LLVM_TEXTURE_MEMBER(data_ptr, DRAW_JIT_TEXTURE_DATA, FALSE) +DRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE) DRAW_LLVM_TEXTURE_MEMBER(min_lod, DRAW_JIT_TEXTURE_MIN_LOD, TRUE) DRAW_LLVM_TEXTURE_MEMBER(max_lod, DRAW_JIT_TEXTURE_MAX_LOD, TRUE) DRAW_LLVM_TEXTURE_MEMBER(lod_bias, DRAW_JIT_TEXTURE_LOD_BIAS, TRUE) @@ -238,7 +239,8 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level; sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride; sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride; - sampler->dynamic_state.base.data_ptr = draw_llvm_texture_data_ptr; + sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr; + sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets; sampler->dynamic_state.base.min_lod = draw_llvm_texture_min_lod; sampler->dynamic_state.base.max_lod = draw_llvm_texture_max_lod; sampler->dynamic_state.base.lod_bias = draw_llvm_texture_lod_bias; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 63cf610ecad..0727fd2b91a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -733,12 +733,13 @@ lp_build_get_mipmap_level(struct lp_build_sample_context *bld, LLVMValueRef level) { LLVMBuilderRef builder = bld->gallivm->builder; - LLVMValueRef indexes[2], data_ptr; + LLVMValueRef indexes[2], data_ptr, mip_offset; indexes[0] = lp_build_const_int32(bld->gallivm, 0); indexes[1] = level; - data_ptr = LLVMBuildGEP(builder, bld->data_array, indexes, 2, ""); - data_ptr = LLVMBuildLoad(builder, data_ptr, ""); + mip_offset = LLVMBuildGEP(builder, bld->mip_offsets, indexes, 2, ""); + mip_offset = LLVMBuildLoad(builder, mip_offset, ""); + data_ptr = LLVMBuildGEP(builder, bld->base_ptr, &mip_offset, 1, ""); return data_ptr; } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index 0f3d8ae6cb5..d8a068d5497 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -157,12 +157,18 @@ struct lp_sampler_dynamic_state struct gallivm_state *gallivm, unsigned unit); - /** Obtain pointer to array of pointers to mimpap levels */ + /** Obtain pointer to base of texture */ LLVMValueRef - (*data_ptr)( const struct lp_sampler_dynamic_state *state, + (*base_ptr)( const struct lp_sampler_dynamic_state *state, struct gallivm_state *gallivm, unsigned unit); + /** Obtain pointer to array of mipmap offsets */ + LLVMValueRef + (*mip_offsets)( const struct lp_sampler_dynamic_state *state, + struct gallivm_state *gallivm, + unsigned unit); + /** Obtain texture min lod (returns float) */ LLVMValueRef (*min_lod)(const struct lp_sampler_dynamic_state *state, @@ -246,7 +252,8 @@ struct lp_build_sample_context /* Common dynamic state values */ LLVMValueRef row_stride_array; LLVMValueRef img_stride_array; - LLVMValueRef data_array; + LLVMValueRef base_ptr; + LLVMValueRef mip_offsets; /** Integer vector with texture width, height, depth */ LLVMValueRef int_size; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index aaef7970635..00a5b187bcb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -1298,8 +1298,9 @@ lp_build_sample_soa(struct gallivm_state *gallivm, tex_depth = dynamic_state->depth(dynamic_state, gallivm, unit); bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, unit); bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, unit); - bld.data_array = dynamic_state->data_ptr(dynamic_state, gallivm, unit); - /* Note that data_array is an array[level] of pointers to texture images */ + bld.base_ptr = dynamic_state->base_ptr(dynamic_state, gallivm, unit); + bld.mip_offsets = dynamic_state->mip_offsets(dynamic_state, gallivm, unit); + /* Note that mip_offsets is an array[level] of offsets to texture images */ s = coords[0]; t = coords[1]; @@ -1439,7 +1440,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm, bld4.dims = bld.dims; bld4.row_stride_array = bld.row_stride_array; bld4.img_stride_array = bld.img_stride_array; - bld4.data_array = bld.data_array; + bld4.base_ptr = bld.base_ptr; + bld4.mip_offsets = bld.mip_offsets; bld4.int_size = bld.int_size; bld4.vector_width = lp_type_width(type4); diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 7fa648fc4d9..37ad1ed61c8 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -360,7 +360,7 @@ i915_prepare_vertex_sampling(struct i915_context *i915) unsigned i,j; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; - const void* data[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; unsigned num = i915->num_vertex_sampler_views; struct pipe_sampler_view **views = i915->vertex_sampler_views; @@ -381,16 +381,15 @@ i915_prepare_vertex_sampling(struct i915_context *i915) */ pipe_resource_reference(&i915->mapped_vs_tex[i], tex); - i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; + i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; addr = iws->buffer_map(iws, i915_tex->buffer, FALSE /* read only */); /* Setup array of mipmap level pointers */ - /* FIXME: handle 3D textures? */ + /* FIXME: handle 3D textures? */ for (j = view->u.tex.first_level; j <= tex->last_level; j++) { - unsigned offset = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); - data[j] = addr + offset; + mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); row_stride[j] = i915_tex->stride; img_stride[j] = 0; /* FIXME */; } @@ -400,7 +399,8 @@ i915_prepare_vertex_sampling(struct i915_context *i915) i, tex->width0, tex->height0, tex->depth0, view->u.tex.first_level, tex->last_level, - row_stride, img_stride, data); + addr, + row_stride, img_stride, mip_offsets); } else i915->mapped_vs_tex[i] = NULL; } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 7a85eab41a0..20c53cbcf7f 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -55,13 +55,12 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp) elem_types[LP_JIT_TEXTURE_HEIGHT] = elem_types[LP_JIT_TEXTURE_DEPTH] = elem_types[LP_JIT_TEXTURE_FIRST_LEVEL] = - elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32TypeInContext(lc); + elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32TypeInContext(lc); + elem_types[LP_JIT_TEXTURE_BASE] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0); elem_types[LP_JIT_TEXTURE_ROW_STRIDE] = elem_types[LP_JIT_TEXTURE_IMG_STRIDE] = + elem_types[LP_JIT_TEXTURE_MIP_OFFSETS] = LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS); - elem_types[LP_JIT_TEXTURE_DATA] = - LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(lc), 0), - LP_MAX_TEXTURE_LEVELS); elem_types[LP_JIT_TEXTURE_MIN_LOD] = elem_types[LP_JIT_TEXTURE_MAX_LOD] = elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(lc); @@ -91,15 +90,18 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp) LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level, gallivm->target, texture_type, LP_JIT_TEXTURE_LAST_LEVEL); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, base, + gallivm->target, texture_type, + LP_JIT_TEXTURE_BASE); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride, gallivm->target, texture_type, LP_JIT_TEXTURE_ROW_STRIDE); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride, gallivm->target, texture_type, LP_JIT_TEXTURE_IMG_STRIDE); - LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data, + LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, mip_offsets, gallivm->target, texture_type, - LP_JIT_TEXTURE_DATA); + LP_JIT_TEXTURE_MIP_OFFSETS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod, gallivm->target, texture_type, LP_JIT_TEXTURE_MIN_LOD); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 584d2c8fd81..94a2bb5ff36 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -53,9 +53,10 @@ struct lp_jit_texture uint32_t depth; uint32_t first_level; uint32_t last_level; + const void *base; uint32_t row_stride[LP_MAX_TEXTURE_LEVELS]; uint32_t img_stride[LP_MAX_TEXTURE_LEVELS]; - const void *data[LP_MAX_TEXTURE_LEVELS]; + uint32_t mip_offsets[LP_MAX_TEXTURE_LEVELS]; /* sampler state, actually */ float min_lod; float max_lod; @@ -70,9 +71,10 @@ enum { LP_JIT_TEXTURE_DEPTH, LP_JIT_TEXTURE_FIRST_LEVEL, LP_JIT_TEXTURE_LAST_LEVEL, + LP_JIT_TEXTURE_BASE, LP_JIT_TEXTURE_ROW_STRIDE, LP_JIT_TEXTURE_IMG_STRIDE, - LP_JIT_TEXTURE_DATA, + LP_JIT_TEXTURE_MIP_OFFSETS, LP_JIT_TEXTURE_MIN_LOD, LP_JIT_TEXTURE_MAX_LOD, LP_JIT_TEXTURE_LOD_BIAS, diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index e5c84bbacdc..60144c34bac 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -663,24 +663,46 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, pipe_resource_reference(&setup->fs.current_tex[i], tex); if (!lp_tex->dt) { - /* regular texture - setup array of mipmap level pointers */ + /* regular texture - setup array of mipmap level offsets */ + void *mip_ptr; int j; + /* + * XXX this is messed up we don't want to accidentally trigger + * tiled->linear conversion for levels we don't need. + * So ask for first_level data (which will allocate all levels) + * then if successful get base ptr. + */ + mip_ptr = llvmpipe_get_texture_image_all(lp_tex, view->u.tex.first_level, + LP_TEX_USAGE_READ, + LP_TEX_LAYOUT_LINEAR); + if ((LP_PERF & PERF_TEX_MEM) || !mip_ptr) { + /* out of memory - use dummy tile memory */ + jit_tex->base = lp_dummy_tile; + jit_tex->width = TILE_SIZE/8; + jit_tex->height = TILE_SIZE/8; + jit_tex->depth = 1; + jit_tex->first_level = 0; + jit_tex->last_level = 0; + } + else { + jit_tex->base = lp_tex->linear_img.data; + } for (j = view->u.tex.first_level; j <= tex->last_level; j++) { - jit_tex->data[j] = - llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ, - LP_TEX_LAYOUT_LINEAR); + mip_ptr = llvmpipe_get_texture_image_all(lp_tex, j, + LP_TEX_USAGE_READ, + LP_TEX_LAYOUT_LINEAR); + jit_tex->mip_offsets[j] = (uint8_t *)mip_ptr - (uint8_t *)jit_tex->base; + /* + * could get mip offset directly but need call above to + * invoke tiled->linear conversion. + */ + assert(lp_tex->linear_mip_offsets[j] == jit_tex->mip_offsets[j]); jit_tex->row_stride[j] = lp_tex->row_stride[j]; jit_tex->img_stride[j] = lp_tex->img_stride[j]; - if ((LP_PERF & PERF_TEX_MEM) || - !jit_tex->data[j]) { + if (jit_tex->base == lp_dummy_tile) { /* out of memory - use dummy tile memory */ - jit_tex->data[j] = lp_dummy_tile; - jit_tex->width = TILE_SIZE/8; - jit_tex->height = TILE_SIZE/8; - jit_tex->depth = 1; - jit_tex->first_level = 0; - jit_tex->last_level = 0; + jit_tex->mip_offsets[j] = 0; jit_tex->row_stride[j] = 0; jit_tex->img_stride[j] = 0; } @@ -693,11 +715,12 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, */ struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; - jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, - PIPE_TRANSFER_READ); + jit_tex->base = winsys->displaytarget_map(winsys, lp_tex->dt, + PIPE_TRANSFER_READ); jit_tex->row_stride[0] = lp_tex->row_stride[0]; jit_tex->img_stride[0] = lp_tex->img_stride[0]; - assert(jit_tex->data[0]); + jit_tex->mip_offsets[0] = 0; + assert(jit_tex->base); } } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 0be900ed299..58fac3f54d4 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -255,7 +255,8 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, unsigned i; uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; - const void *data[PIPE_MAX_TEXTURE_LEVELS]; + uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; + const void *addr; assert(num <= PIPE_MAX_SAMPLERS); if (!num) @@ -275,11 +276,24 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ + /* XXX this may fail due to OOM ? */ int j; + void *mip_ptr; + /* must trigger allocation first before we can get base ptr */ + mip_ptr = llvmpipe_get_texture_image_all(lp_tex, view->u.tex.first_level, + LP_TEX_USAGE_READ, + LP_TEX_LAYOUT_LINEAR); + addr = lp_tex->linear_img.data; for (j = view->u.tex.first_level; j <= tex->last_level; j++) { - data[j] = - llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ, - LP_TEX_LAYOUT_LINEAR); + mip_ptr = llvmpipe_get_texture_image_all(lp_tex, j, + LP_TEX_USAGE_READ, + LP_TEX_LAYOUT_LINEAR); + mip_offsets[j] = (uint8_t *)mip_ptr - (uint8_t *)addr; + /* + * could get mip offset directly but need call above to + * invoke tiled->linear conversion. + */ + assert(lp_tex->linear_mip_offsets[j] == mip_offsets[j]); row_stride[j] = lp_tex->row_stride[j]; img_stride[j] = lp_tex->img_stride[j]; } @@ -291,18 +305,20 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp, */ struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; - data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, + addr = winsys->displaytarget_map(winsys, lp_tex->dt, PIPE_TRANSFER_READ); row_stride[0] = lp_tex->row_stride[0]; img_stride[0] = lp_tex->img_stride[0]; - assert(data[0]); + mip_offsets[0] = 0; + assert(addr); } draw_set_mapped_texture(lp->draw, PIPE_SHADER_VERTEX, i, tex->width0, tex->height0, tex->depth0, view->u.tex.first_level, tex->last_level, - row_stride, img_stride, data); + addr, + row_stride, img_stride, mip_offsets); } } } diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 9151e427ba7..1c5c009b556 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -151,9 +151,10 @@ LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE) LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE) LP_LLVM_TEXTURE_MEMBER(first_level, LP_JIT_TEXTURE_FIRST_LEVEL, TRUE) LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE) +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(data_ptr, LP_JIT_TEXTURE_DATA, FALSE) +LP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE) LP_LLVM_TEXTURE_MEMBER(min_lod, LP_JIT_TEXTURE_MIN_LOD, TRUE) LP_LLVM_TEXTURE_MEMBER(max_lod, LP_JIT_TEXTURE_MAX_LOD, TRUE) LP_LLVM_TEXTURE_MEMBER(lod_bias, LP_JIT_TEXTURE_LOD_BIAS, TRUE) @@ -246,9 +247,10 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state, sampler->dynamic_state.base.depth = lp_llvm_texture_depth; sampler->dynamic_state.base.first_level = lp_llvm_texture_first_level; sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level; + sampler->dynamic_state.base.base_ptr = lp_llvm_texture_base_ptr; 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.data_ptr = lp_llvm_texture_data_ptr; + sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets; sampler->dynamic_state.base.min_lod = lp_llvm_texture_min_lod; sampler->dynamic_state.base.max_lod = lp_llvm_texture_max_lod; sampler->dynamic_state.base.lod_bias = lp_llvm_texture_lod_bias; -- 2.30.2