From 09e23e077b2bc3dc9ec0ecd97e1043ee7f32f2bb Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 12 Feb 2008 14:53:25 -0700 Subject: [PATCH] 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. --- src/mesa/pipe/i915simple/i915_state.c | 7 +++ src/mesa/pipe/i915simple/i915_state_sampler.c | 2 +- src/mesa/pipe/i915simple/i915_texture.c | 30 +++++------ src/mesa/pipe/i965simple/brw_tex_layout.c | 8 +-- .../pipe/i965simple/brw_wm_surface_state.c | 2 +- src/mesa/pipe/p_state.h | 14 ++--- src/mesa/pipe/softpipe/sp_state_sampler.c | 4 ++ src/mesa/pipe/softpipe/sp_tex_sample.c | 18 ++----- src/mesa/pipe/softpipe/sp_texture.c | 4 +- src/mesa/state_tracker/st_cb_texture.c | 51 +++++++------------ src/mesa/state_tracker/st_gen_mipmap.c | 43 +++++++++------- src/mesa/state_tracker/st_texture.c | 35 +++++++++---- src/mesa/state_tracker/st_texture.h | 6 +-- 13 files changed, 115 insertions(+), 109 deletions(-) diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 950ea52d601..abd5571b885 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -250,6 +250,13 @@ i915_create_sampler_state(struct pipe_context *pipe, if (sampler->normalized_coords) cso->state[1] |= SS3_NORMALIZED_COORDS; + if (0) /* XXX not tested yet */ + { + int minlod = (int) (16.0 * sampler->min_lod); + minlod = CLAMP(minlod, 0, 16 * 11); + cso->state[1] |= (minlod << SS3_MIN_LOD_SHIFT); + } + { ubyte r = float_to_ubyte(sampler->border_color[0]); ubyte g = float_to_ubyte(sampler->border_color[1]); diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 0dbbc5241d5..9c1a5bbbd65 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -185,7 +185,7 @@ i915_update_texture(struct i915_context *i915, uint unit, const struct pipe_texture *pt = &tex->base; uint format, pitch; const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; - const uint num_levels = pt->last_level - pt->first_level; + const uint num_levels = pt->last_level; assert(tex); assert(width); diff --git a/src/mesa/pipe/i915simple/i915_texture.c b/src/mesa/pipe/i915simple/i915_texture.c index 6faeab134ab..6d37ae3d747 100644 --- a/src/mesa/pipe/i915simple/i915_texture.c +++ b/src/mesa/pipe/i915simple/i915_texture.c @@ -118,11 +118,11 @@ i945_miptree_layout_2d( struct i915_texture *tex ) tex->pitch = pt->width[0]; /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment + * the 2nd mipmap level. This occurs when the alignment * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. + * 2nd mipmap level out past the width of its parent. */ - if (pt->first_level != pt->last_level) { + if (pt->last_level > 0) { unsigned mip1_width = align_int(minify(pt->width[0]), align_w) + minify(minify(pt->width[0])); @@ -136,7 +136,7 @@ i945_miptree_layout_2d( struct i915_texture *tex ) tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp; tex->total_height = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned img_height; i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); @@ -152,9 +152,9 @@ i945_miptree_layout_2d( struct i915_texture *tex ) */ tex->total_height = MAX2(tex->total_height, y + img_height); - /* Layout_below: step right after second mipmap. + /* Layout_below: step right after second mipmap level. */ - if (level == pt->first_level + 1) { + if (level == 1) { x += align_int(width, align_w); } else { @@ -204,7 +204,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; tex->total_height = dim * 4; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, 0, 0, /*OLD: tex->pitch, tex->total_height,*/ @@ -219,7 +219,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) unsigned y = initial_offsets[face][1] * dim; unsigned d = dim; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; x += step_offsets[face][0] * d; @@ -240,7 +240,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* XXX: hardware expects/requires 9 levels at minimum. */ - for (level = pt->first_level; level <= MAX2(8, pt->last_level); + for (level = 0; level <= MAX2(8, pt->last_level); level++) { i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, width, height, depth); @@ -256,7 +256,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* Fixup depth image_offsets: */ depth = pt->depth[0]; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { unsigned i; for (i = 0; i < depth; i++) i915_miptree_set_image_offset(tex, level, i, @@ -282,7 +282,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; tex->total_height = 0; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 1, 0, tex->total_height, width, height, 1); @@ -337,7 +337,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) /* Set all the levels to effectively occupy the whole rectangular region. */ - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); @@ -355,12 +355,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) y = tex->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0 || pt->first_level > 0)) { + else if (dim < 4 && (face > 0)) { y = tex->total_height - 4; x = face * 8; } - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; @@ -418,7 +418,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) pack_x_pitch = tex->pitch; pack_x_nr = 1; - for (level = pt->first_level; level <= pt->last_level; level++) { + for (level = 0; level <= pt->last_level; level++) { unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; diff --git a/src/mesa/pipe/i965simple/brw_tex_layout.c b/src/mesa/pipe/i965simple/brw_tex_layout.c index 405fd1f7949..90561f1307d 100644 --- a/src/mesa/pipe/i965simple/brw_tex_layout.c +++ b/src/mesa/pipe/i965simple/brw_tex_layout.c @@ -146,7 +146,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (pt->first_level != pt->last_level) { + if (pt->last_level > 0) { unsigned mip1_width; if (pt->compressed) { @@ -168,7 +168,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; tex->total_height = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned img_height; intel_miptree_set_level_info(tex, level, 1, x, y, width, @@ -187,7 +187,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex) /* Layout_below: step right after second mipmap. */ - if (level == pt->first_level + 1) { + if (level == 1) { x += align(width, align_w); } else { @@ -234,7 +234,7 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture pack_x_pitch = tex->pitch; pack_x_nr = 1; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; diff --git a/src/mesa/pipe/i965simple/brw_wm_surface_state.c b/src/mesa/pipe/i965simple/brw_wm_surface_state.c index cbb4f2efd3b..d16d919bce9 100644 --- a/src/mesa/pipe/i965simple/brw_wm_surface_state.c +++ b/src/mesa/pipe/i965simple/brw_wm_surface_state.c @@ -154,7 +154,7 @@ void brw_update_texture_surface( struct brw_context *brw, /* Updated in emit_reloc */ surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer ); - surf.ss2.mip_count = tObj->base.last_level - tObj->base.first_level; + surf.ss2.mip_count = tObj->base.last_level; surf.ss2.width = tObj->base.width[0] - 1; surf.ss2.height = tObj->base.height[0] - 1; diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 83ca43f6785..4d3a6b2f413 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -234,14 +234,9 @@ struct pipe_sampler_state unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ - float shadow_ambient; /**< shadow test fail color/intensity */ - float min_lod; - float max_lod; - float lod_bias; -#if 0 /* need these? */ - int BaseLevel; /**< min mipmap level, OpenGL 1.2 */ - int MaxLevel; /**< max mipmap level, OpenGL 1.2 */ -#endif + float shadow_ambient; /**< shadow test fail color/intensity */ + float lod_bias; /**< LOD/lambda bias */ + float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; float max_anisotropy; }; @@ -277,8 +272,7 @@ struct pipe_texture enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_format format; /**< PIPE_FORMAT_x */ - unsigned first_level; - unsigned last_level; + unsigned last_level; /**< Index of last mipmap level present/defined */ unsigned width[PIPE_MAX_TEXTURE_LEVELS]; unsigned height[PIPE_MAX_TEXTURE_LEVELS]; diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 291bbc40ad0..6a5a643c89e 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -34,6 +34,8 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "pipe/draw/draw_context.h" + void * @@ -73,6 +75,8 @@ softpipe_set_sampler_texture(struct pipe_context *pipe, { struct softpipe_context *softpipe = softpipe_context(pipe); + draw_flush(softpipe->draw); + assert(unit < PIPE_MAX_SAMPLERS); softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 5e215c433ad..325bdb86da5 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -449,7 +449,6 @@ compute_lambda(struct tgsi_sampler *sampler, } lambda = LOG2(rho); - lambda += lodbias + sampler->state->lod_bias; lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); @@ -457,7 +456,6 @@ compute_lambda(struct tgsi_sampler *sampler, } - /** * Do several things here: * 1. Compute lambda from the texcoords, if needed @@ -477,7 +475,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) { /* no mipmap selection needed */ *imgFilter = sampler->state->mag_img_filter; - *level0 = *level1 = sampler->texture->first_level; + *level0 = *level1 = (int) sampler->state->min_lod; } else { float lambda; @@ -492,7 +490,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, if (lambda < 0.0) { /* XXX threshold depends on the filter */ /* magnifying */ *imgFilter = sampler->state->mag_img_filter; - *level0 = *level1 = sampler->texture->first_level; + *level0 = *level1 = 0; } else { /* minifying */ @@ -503,19 +501,13 @@ choose_mipmap_levels(struct tgsi_sampler *sampler, /* Nearest mipmap level */ const int lvl = (int) (lambda + 0.5); *level0 = - *level1 = CLAMP(lvl, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); + *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level); } else { /* Linear interpolation between mipmap levels */ const int lvl = (int) lambda; - *level0 = CLAMP(lvl, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); - *level1 = CLAMP(lvl + 1, - (int) sampler->texture->first_level, - (int) sampler->texture->last_level); + *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level); + *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level); *levelBlend = FRAC(lambda); /* blending weight between levels */ } } diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c index fd2cc3dbbb4..6de7a9b543b 100644 --- a/src/mesa/pipe/softpipe/sp_texture.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -61,7 +61,7 @@ softpipe_texture_layout(struct softpipe_texture * spt) spt->buffer_size = 0; - for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + for (level = 0; level <= pt->last_level; level++) { pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; @@ -139,6 +139,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe, struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; + assert(level <= pt->last_level); + ps = pipe->winsys->surface_alloc(pipe->winsys); if (ps) { assert(ps->refcount); 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 -- 2.30.2