summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorBrian <[email protected]>2008-02-12 14:53:25 -0700
committerBrian <[email protected]>2008-02-12 14:53:25 -0700
commit4da1cdf78fa3b954840650fa46cf72da5daf149f (patch)
tree0496f6f4364e3608f7bb7af2a549a9ba3a898252 /src/mesa/state_tracker
parentb61b1a295b13a0ff2cf98c8d07e62147d71c08b9 (diff)
gallium: clean-up, simplification of mipmapped textures
Remove pipe_texture->first_level (always implicitly zero). This means there's never any unused mipmap levels at the top. In the state tracker, we no longer re-layout mipmapped textures if the MinLod/MaxLod texture parameters change. It's up to the driver to obey the pipe_sampler->min/max_lod clamps.
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c51
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c43
-rw-r--r--src/mesa/state_tracker/st_texture.c35
-rw-r--r--src/mesa/state_tracker/st_texture.h6
4 files changed, 71 insertions, 64 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 7099ec33b97..f012b2f1a05 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -57,15 +57,10 @@ struct st_texture_object
{
struct gl_texture_object base; /* The "parent" object */
- /* The texture must include at least these levels once validated:
+ /* The texture must include at levels [0..lastLevel] once validated:
*/
- GLuint firstLevel;
GLuint lastLevel;
- /* Offset for firstLevel image:
- */
- GLuint textureOffset;
-
/* On validation any active images held in main memory or in other
* textures will be copied to this texture and the old storage freed.
*/
@@ -585,12 +580,12 @@ st_TexImage(GLcontext * ctx,
_mesa_align_free(texImage->Data);
}
- /* If this is the only texture image in the texture, could call
+ /* If this is the only mipmap level in the texture, could call
* bmBufferData with NULL data to free the old block and avoid
* waiting on any outstanding fences.
*/
if (stObj->pt &&
- stObj->pt->first_level == level &&
+ /*stObj->pt->first_level == level &&*/
stObj->pt->last_level == level &&
stObj->pt->target != PIPE_TEXTURE_CUBE &&
!st_texture_match_image(stObj->pt, &stImage->base,
@@ -1363,13 +1358,8 @@ calculate_first_last_level(struct st_texture_object *stObj)
firstLevel = lastLevel = tObj->BaseLevel;
}
else {
- firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
- firstLevel = MAX2(firstLevel, tObj->BaseLevel);
- lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
- lastLevel = MAX2(lastLevel, tObj->BaseLevel);
- lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
- lastLevel = MIN2(lastLevel, tObj->MaxLevel);
- lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ firstLevel = 0;
+ lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2);
}
break;
case GL_TEXTURE_RECTANGLE_NV:
@@ -1380,8 +1370,6 @@ calculate_first_last_level(struct st_texture_object *stObj)
return;
}
- /* save these values */
- stObj->firstLevel = firstLevel;
stObj->lastLevel = lastLevel;
}
@@ -1389,15 +1377,16 @@ calculate_first_last_level(struct st_texture_object *stObj)
static void
copy_image_data_to_texture(struct st_context *st,
struct st_texture_object *stObj,
+ GLuint dstLevel,
struct st_texture_image *stImage)
{
if (stImage->pt) {
/* Copy potentially with the blitter:
*/
st_texture_image_copy(st->pipe,
- stObj->pt, /* dest texture */
- stImage->face, stImage->level,
- stImage->pt /* src texture */
+ stObj->pt, dstLevel, /* dest texture, level */
+ stImage->pt, /* src texture */
+ stImage->face
);
st->pipe->texture_release(st->pipe, &stImage->pt);
@@ -1438,7 +1427,7 @@ st_finalize_texture(GLcontext *ctx,
const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
int comp_byte = 0;
int cpp;
- GLuint face, i;
+ GLuint face;
struct st_texture_image *firstImage;
*needFlush = GL_FALSE;
@@ -1450,7 +1439,7 @@ st_finalize_texture(GLcontext *ctx,
/* What levels must the texture include at a minimum?
*/
calculate_first_last_level(stObj);
- firstImage = st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
+ firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
/* Fallback case:
*/
@@ -1469,7 +1458,6 @@ st_finalize_texture(GLcontext *ctx,
*/
if (firstImage->pt &&
firstImage->pt != stObj->pt &&
- firstImage->pt->first_level <= stObj->firstLevel &&
firstImage->pt->last_level >= stObj->lastLevel) {
if (stObj->pt)
@@ -1488,18 +1476,11 @@ st_finalize_texture(GLcontext *ctx,
/* Check texture can hold all active levels. Check texture matches
* target, imageFormat, etc.
- *
- * XXX: For some layouts (eg i945?), the test might have to be
- * first_level == firstLevel, as the texture isn't valid except at the
- * original start level. Hope to get around this by
- * programming minLod, maxLod, baseLevel into the hardware and
- * leaving the texture alone.
*/
if (stObj->pt &&
(stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
stObj->pt->format !=
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) ||
- stObj->pt->first_level != stObj->firstLevel ||
stObj->pt->last_level != stObj->lastLevel ||
stObj->pt->width[0] != firstImage->base.Width ||
stObj->pt->height[0] != firstImage->base.Height ||
@@ -1516,7 +1497,7 @@ st_finalize_texture(GLcontext *ctx,
stObj->pt = st_texture_create(ctx->st,
gl_target_to_pipe(stObj->base.Target),
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
- stObj->firstLevel,
+ 0, /* first level */
stObj->lastLevel,
firstImage->base.Width,
firstImage->base.Height,
@@ -1527,14 +1508,16 @@ st_finalize_texture(GLcontext *ctx,
/* Pull in any images not in the object's texture:
*/
for (face = 0; face < nr_faces; face++) {
- for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
+ GLuint level;
+ for (level = 0; level <= stObj->lastLevel; level++) {
struct st_texture_image *stImage =
- st_texture_image(stObj->base.Image[face][i]);
+ //st_texture_image(stObj->base.Image[face][level]);
+ st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
/* Need to import images in main memory or held in other textures.
*/
if (stObj->pt != stImage->pt) {
- copy_image_data_to_texture(ctx->st, stObj, stImage);
+ copy_image_data_to_texture(ctx->st, stObj, level, stImage);
*needFlush = GL_TRUE;
}
}
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index c152c599056..fd7d8cefea9 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -51,7 +51,6 @@
static void *blend_cso = NULL;
static void *depthstencil_cso = NULL;
static void *rasterizer_cso = NULL;
-static void *sampler_cso = NULL;
static struct st_fragment_program *stfp = NULL;
static struct st_vertex_program *stvp = NULL;
@@ -118,7 +117,6 @@ st_init_generate_mipmap(struct st_context *st)
struct pipe_context *pipe = st->pipe;
struct pipe_blend_state blend;
struct pipe_rasterizer_state rasterizer;
- struct pipe_sampler_state sampler;
struct pipe_depth_stencil_alpha_state depthstencil;
assert(!blend_cso);
@@ -133,16 +131,6 @@ st_init_generate_mipmap(struct st_context *st)
memset(&rasterizer, 0, sizeof(rasterizer));
rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer);
- memset(&sampler, 0, sizeof(sampler));
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
- sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
- sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
- sampler.normalized_coords = 1;
- sampler_cso = pipe->create_sampler_state(pipe, &sampler);
-
stfp = make_tex_fragment_program(st->ctx);
stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
}
@@ -156,14 +144,12 @@ st_destroy_generate_mipmpap(struct st_context *st)
pipe->delete_blend_state(pipe, blend_cso);
pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso);
pipe->delete_rasterizer_state(pipe, rasterizer_cso);
- pipe->delete_sampler_state(pipe, sampler_cso);
/* XXX free stfp, stvp */
blend_cso = NULL;
depthstencil_cso = NULL;
rasterizer_cso = NULL;
- sampler_cso = NULL;
}
@@ -248,8 +234,10 @@ st_render_mipmap(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
struct pipe_framebuffer_state fb;
+ struct pipe_sampler_state sampler;
+ void *sampler_cso;
const uint face = _mesa_tex_target_to_face(target), zslice = 0;
- const uint first_level_save = pt->first_level;
+ /*const uint first_level_save = pt->first_level;*/
uint dstLevel;
assert(target != GL_TEXTURE_3D); /* not done yet */
@@ -263,11 +251,21 @@ st_render_mipmap(struct st_context *st,
memset(&fb, 0, sizeof(fb));
fb.num_cbufs = 1;
+ /* sampler state */
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.normalized_coords = 1;
+
+
/* bind CSOs */
pipe->bind_blend_state(pipe, blend_cso);
pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso);
pipe->bind_rasterizer_state(pipe, rasterizer_cso);
- pipe->bind_sampler_state(pipe, 0, sampler_cso);
/* bind shaders */
pipe->bind_fs_state(pipe, stfp->fs->data);
@@ -286,20 +284,29 @@ st_render_mipmap(struct st_context *st,
fb.cbufs[0] = pipe->get_tex_surface(pipe, pt, face, dstLevel, zslice);
pipe->set_framebuffer_state(pipe, &fb);
+ /*
+ * Setup sampler state
+ */
+ sampler.min_lod = sampler.max_lod = srcLevel;
+ sampler_cso = pipe->create_sampler_state(pipe, &sampler);
+ pipe->bind_sampler_state(pipe, 0, sampler_cso);
+
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
/*
* Setup src texture, override pt->first_level so we sample from
* the right mipmap level.
*/
- pt->first_level = srcLevel;
+ /*pt->first_level = srcLevel;*/
pipe->set_sampler_texture(pipe, 0, pt);
draw_quad(st->ctx);
+
+ pipe->delete_sampler_state(pipe, sampler_cso);
}
/* restore first_level */
- pt->first_level = first_level_save;
+ /*pt->first_level = first_level_save;*/
/* restore pipe state */
if (st->state.rasterizer)
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 844a9f80d85..ff33da6f9e4 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -62,6 +62,10 @@ target_to_target(GLenum target)
/**
* Allocate a new pipe_texture object
+ * width0, height0, depth0 are the dimensions of the level 0 image
+ * (the highest resolution). last_level indicates how many mipmap levels
+ * to allocate storage for. For non-mipmapped textures, this will be zero.
+ * XXX first_level obsolete
*/
struct pipe_texture *
st_texture_create(struct st_context *st,
@@ -84,9 +88,9 @@ st_texture_create(struct st_context *st,
assert(format);
+ memset(&pt, 0, sizeof(pt));
pt.target = target;
pt.format = format;
- pt.first_level = first_level;
pt.last_level = last_level;
pt.width[0] = width0;
pt.height[0] = height0;
@@ -266,23 +270,36 @@ st_texture_image_data(struct pipe_context *pipe,
*/
void
st_texture_image_copy(struct pipe_context *pipe,
- struct pipe_texture *dst,
- GLuint face, GLuint level,
- struct pipe_texture *src)
+ struct pipe_texture *dst, GLuint dstLevel,
+ struct pipe_texture *src,
+ GLuint face)
{
- GLuint width = src->width[level];
- GLuint height = src->height[level];
- GLuint depth = src->depth[level];
+ GLuint width = dst->width[dstLevel];
+ GLuint height = dst->height[dstLevel];
+ GLuint depth = dst->depth[dstLevel];
struct pipe_surface *src_surface;
struct pipe_surface *dst_surface;
GLuint i;
+ /* XXX this is a hack */
if (dst->compressed)
height /= 4;
for (i = 0; i < depth; i++) {
- dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
- src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
+ GLuint srcLevel;
+
+ /* find src texture level of needed size */
+ for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
+ if (src->width[srcLevel] == width &&
+ src->height[srcLevel] == height) {
+ break;
+ }
+ }
+ assert(src->width[srcLevel] == width);
+ assert(src->height[srcLevel] == height);
+
+ dst_surface = pipe->get_tex_surface(pipe, dst, face, dstLevel, i);
+ src_surface = pipe->get_tex_surface(pipe, src, face, srcLevel, i);
pipe->surface_copy(pipe,
dst_surface,
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 0b87a494c38..6c5f0930fa5 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -98,9 +98,9 @@ st_texture_image_data(struct pipe_context *pipe,
*/
extern void
st_texture_image_copy(struct pipe_context *pipe,
- struct pipe_texture *dst,
- GLuint face, GLuint level,
- struct pipe_texture *src);
+ struct pipe_texture *dst, GLuint dstLevel,
+ struct pipe_texture *src,
+ GLuint face);
#endif