summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2012-11-12 20:35:04 +0100
committerRoland Scheidegger <[email protected]>2012-11-12 21:02:59 +0100
commit26097c4855b97ee6e362c19df11d51fb7fd42192 (patch)
treedbc5018aa4b3a2c2fb2e1e0464be4776610cc044 /src/gallium/drivers
parent8257bb963f0b21c0c35da479707b5cacbc1c2824 (diff)
gallivm,draw,llvmpipe: use base ptr + mip offsets instead of mip pointers
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 <[email protected]> Reviewed-by: José Fonseca <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/i915/i915_state.c12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c6
6 files changed, 83 insertions, 38 deletions
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;