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.
This commit is contained in:
Brian 2008-02-12 14:53:25 -07:00 committed by Ben Skeggs
parent 5d1af60edb
commit 09e23e077b
13 changed files with 115 additions and 109 deletions

View file

@ -250,6 +250,13 @@ i915_create_sampler_state(struct pipe_context *pipe,
if (sampler->normalized_coords) if (sampler->normalized_coords)
cso->state[1] |= SS3_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 r = float_to_ubyte(sampler->border_color[0]);
ubyte g = float_to_ubyte(sampler->border_color[1]); ubyte g = float_to_ubyte(sampler->border_color[1]);

View file

@ -185,7 +185,7 @@ i915_update_texture(struct i915_context *i915, uint unit,
const struct pipe_texture *pt = &tex->base; const struct pipe_texture *pt = &tex->base;
uint format, pitch; uint format, pitch;
const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; 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(tex);
assert(width); assert(width);

View file

@ -118,11 +118,11 @@ i945_miptree_layout_2d( struct i915_texture *tex )
tex->pitch = pt->width[0]; tex->pitch = pt->width[0];
/* May need to adjust pitch to accomodate the placement of /* 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 * 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) unsigned mip1_width = align_int(minify(pt->width[0]), align_w)
+ minify(minify(pt->width[0])); + 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->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp;
tex->total_height = 0; 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; unsigned img_height;
i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); 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); 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); x += align_int(width, align_w);
} }
else { 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->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
tex->total_height = dim * 4; 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, i915_miptree_set_level_info(tex, level, 6,
0, 0, 0, 0,
/*OLD: tex->pitch, tex->total_height,*/ /*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 y = initial_offsets[face][1] * dim;
unsigned d = 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); i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1; d >>= 1;
x += step_offsets[face][0] * d; 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. /* 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++) { level++) {
i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height,
width, height, depth); width, height, depth);
@ -256,7 +256,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
/* Fixup depth image_offsets: /* Fixup depth image_offsets:
*/ */
depth = pt->depth[0]; depth = pt->depth[0];
for (level = pt->first_level; level <= pt->last_level; level++) { for (level = 0; level <= pt->last_level; level++) {
unsigned i; unsigned i;
for (i = 0; i < depth; i++) for (i = 0; i < depth; i++)
i915_miptree_set_image_offset(tex, level, 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->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
tex->total_height = 0; 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, i915_miptree_set_level_info(tex, level, 1,
0, tex->total_height, 0, tex->total_height,
width, height, 1); 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. /* 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, i915_miptree_set_level_info(tex, level, 6,
0, 0, 0, 0,
lvlWidth, lvlHeight, 1); lvlWidth, lvlHeight, 1);
@ -355,12 +355,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
y = tex->total_height - 4; y = tex->total_height - 4;
x = (face - 4) * 8; 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; y = tex->total_height - 4;
x = face * 8; 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); i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1; d >>= 1;
@ -418,7 +418,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
pack_x_pitch = tex->pitch; pack_x_pitch = tex->pitch;
pack_x_nr = 1; 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; unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0; int x = 0;
int y = 0; int y = 0;

View file

@ -146,7 +146,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
* constraints of mipmap placement push the right edge of the * constraints of mipmap placement push the right edge of the
* 2nd mipmap out past the width of its parent. * 2nd mipmap out past the width of its parent.
*/ */
if (pt->first_level != pt->last_level) { if (pt->last_level > 0) {
unsigned mip1_width; unsigned mip1_width;
if (pt->compressed) { 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->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
tex->total_height = 0; 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; unsigned img_height;
intel_miptree_set_level_info(tex, level, 1, x, y, width, 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. /* Layout_below: step right after second mipmap.
*/ */
if (level == pt->first_level + 1) { if (level == 1) {
x += align(width, align_w); x += align(width, align_w);
} }
else { else {
@ -234,7 +234,7 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
pack_x_pitch = tex->pitch; pack_x_pitch = tex->pitch;
pack_x_nr = 1; 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; unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0; int x = 0;
int y = 0; int y = 0;

View file

@ -154,7 +154,7 @@ void brw_update_texture_surface( struct brw_context *brw,
/* Updated in emit_reloc */ /* Updated in emit_reloc */
surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer ); 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.width = tObj->base.width[0] - 1;
surf.ss2.height = tObj->base.height[0] - 1; surf.ss2.height = tObj->base.height[0] - 1;

View file

@ -234,14 +234,9 @@ struct pipe_sampler_state
unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */
unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */
unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */
float shadow_ambient; /**< shadow test fail color/intensity */ float shadow_ambient; /**< shadow test fail color/intensity */
float min_lod; float lod_bias; /**< LOD/lambda bias */
float max_lod; float min_lod, max_lod; /**< LOD clamp range, after bias */
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 border_color[4]; float border_color[4];
float max_anisotropy; float max_anisotropy;
}; };
@ -277,8 +272,7 @@ struct pipe_texture
enum pipe_texture_target target; /**< PIPE_TEXTURE_x */ enum pipe_texture_target target; /**< PIPE_TEXTURE_x */
enum pipe_format format; /**< PIPE_FORMAT_x */ enum pipe_format format; /**< PIPE_FORMAT_x */
unsigned first_level; unsigned last_level; /**< Index of last mipmap level present/defined */
unsigned last_level;
unsigned width[PIPE_MAX_TEXTURE_LEVELS]; unsigned width[PIPE_MAX_TEXTURE_LEVELS];
unsigned height[PIPE_MAX_TEXTURE_LEVELS]; unsigned height[PIPE_MAX_TEXTURE_LEVELS];

View file

@ -34,6 +34,8 @@
#include "sp_state.h" #include "sp_state.h"
#include "sp_texture.h" #include "sp_texture.h"
#include "sp_tile_cache.h" #include "sp_tile_cache.h"
#include "pipe/draw/draw_context.h"
void * void *
@ -73,6 +75,8 @@ softpipe_set_sampler_texture(struct pipe_context *pipe,
{ {
struct softpipe_context *softpipe = softpipe_context(pipe); struct softpipe_context *softpipe = softpipe_context(pipe);
draw_flush(softpipe->draw);
assert(unit < PIPE_MAX_SAMPLERS); assert(unit < PIPE_MAX_SAMPLERS);
softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */

View file

@ -449,7 +449,6 @@ compute_lambda(struct tgsi_sampler *sampler,
} }
lambda = LOG2(rho); lambda = LOG2(rho);
lambda += lodbias + sampler->state->lod_bias; lambda += lodbias + sampler->state->lod_bias;
lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod); 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: * Do several things here:
* 1. Compute lambda from the texcoords, if needed * 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) { if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
/* no mipmap selection needed */ /* no mipmap selection needed */
*imgFilter = sampler->state->mag_img_filter; *imgFilter = sampler->state->mag_img_filter;
*level0 = *level1 = sampler->texture->first_level; *level0 = *level1 = (int) sampler->state->min_lod;
} }
else { else {
float lambda; float lambda;
@ -492,7 +490,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
if (lambda < 0.0) { /* XXX threshold depends on the filter */ if (lambda < 0.0) { /* XXX threshold depends on the filter */
/* magnifying */ /* magnifying */
*imgFilter = sampler->state->mag_img_filter; *imgFilter = sampler->state->mag_img_filter;
*level0 = *level1 = sampler->texture->first_level; *level0 = *level1 = 0;
} }
else { else {
/* minifying */ /* minifying */
@ -503,19 +501,13 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
/* Nearest mipmap level */ /* Nearest mipmap level */
const int lvl = (int) (lambda + 0.5); const int lvl = (int) (lambda + 0.5);
*level0 = *level0 =
*level1 = CLAMP(lvl, *level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
(int) sampler->texture->first_level,
(int) sampler->texture->last_level);
} }
else { else {
/* Linear interpolation between mipmap levels */ /* Linear interpolation between mipmap levels */
const int lvl = (int) lambda; const int lvl = (int) lambda;
*level0 = CLAMP(lvl, *level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
(int) sampler->texture->first_level, *level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
(int) sampler->texture->last_level);
*level1 = CLAMP(lvl + 1,
(int) sampler->texture->first_level,
(int) sampler->texture->last_level);
*levelBlend = FRAC(lambda); /* blending weight between levels */ *levelBlend = FRAC(lambda); /* blending weight between levels */
} }
} }

View file

@ -61,7 +61,7 @@ softpipe_texture_layout(struct softpipe_texture * spt)
spt->buffer_size = 0; 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->width[level] = width;
pt->height[level] = height; pt->height[level] = height;
pt->depth[level] = depth; pt->depth[level] = depth;
@ -139,6 +139,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
struct softpipe_texture *spt = softpipe_texture(pt); struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps; struct pipe_surface *ps;
assert(level <= pt->last_level);
ps = pipe->winsys->surface_alloc(pipe->winsys); ps = pipe->winsys->surface_alloc(pipe->winsys);
if (ps) { if (ps) {
assert(ps->refcount); assert(ps->refcount);

View file

@ -57,15 +57,10 @@ struct st_texture_object
{ {
struct gl_texture_object base; /* The "parent" 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; GLuint lastLevel;
/* Offset for firstLevel image:
*/
GLuint textureOffset;
/* On validation any active images held in main memory or in other /* On validation any active images held in main memory or in other
* textures will be copied to this texture and the old storage freed. * 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); _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 * bmBufferData with NULL data to free the old block and avoid
* waiting on any outstanding fences. * waiting on any outstanding fences.
*/ */
if (stObj->pt && if (stObj->pt &&
stObj->pt->first_level == level && /*stObj->pt->first_level == level &&*/
stObj->pt->last_level == level && stObj->pt->last_level == level &&
stObj->pt->target != PIPE_TEXTURE_CUBE && stObj->pt->target != PIPE_TEXTURE_CUBE &&
!st_texture_match_image(stObj->pt, &stImage->base, !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; firstLevel = lastLevel = tObj->BaseLevel;
} }
else { else {
firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); firstLevel = 0;
firstLevel = MAX2(firstLevel, tObj->BaseLevel); lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2);
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 */
} }
break; break;
case GL_TEXTURE_RECTANGLE_NV: case GL_TEXTURE_RECTANGLE_NV:
@ -1380,8 +1370,6 @@ calculate_first_last_level(struct st_texture_object *stObj)
return; return;
} }
/* save these values */
stObj->firstLevel = firstLevel;
stObj->lastLevel = lastLevel; stObj->lastLevel = lastLevel;
} }
@ -1389,15 +1377,16 @@ calculate_first_last_level(struct st_texture_object *stObj)
static void static void
copy_image_data_to_texture(struct st_context *st, copy_image_data_to_texture(struct st_context *st,
struct st_texture_object *stObj, struct st_texture_object *stObj,
GLuint dstLevel,
struct st_texture_image *stImage) struct st_texture_image *stImage)
{ {
if (stImage->pt) { if (stImage->pt) {
/* Copy potentially with the blitter: /* Copy potentially with the blitter:
*/ */
st_texture_image_copy(st->pipe, st_texture_image_copy(st->pipe,
stObj->pt, /* dest texture */ stObj->pt, dstLevel, /* dest texture, level */
stImage->face, stImage->level, stImage->pt, /* src texture */
stImage->pt /* src texture */ stImage->face
); );
st->pipe->texture_release(st->pipe, &stImage->pt); 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; const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
int comp_byte = 0; int comp_byte = 0;
int cpp; int cpp;
GLuint face, i; GLuint face;
struct st_texture_image *firstImage; struct st_texture_image *firstImage;
*needFlush = GL_FALSE; *needFlush = GL_FALSE;
@ -1450,7 +1439,7 @@ st_finalize_texture(GLcontext *ctx,
/* What levels must the texture include at a minimum? /* What levels must the texture include at a minimum?
*/ */
calculate_first_last_level(stObj); 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: /* Fallback case:
*/ */
@ -1469,7 +1458,6 @@ st_finalize_texture(GLcontext *ctx,
*/ */
if (firstImage->pt && if (firstImage->pt &&
firstImage->pt != stObj->pt && firstImage->pt != stObj->pt &&
firstImage->pt->first_level <= stObj->firstLevel &&
firstImage->pt->last_level >= stObj->lastLevel) { firstImage->pt->last_level >= stObj->lastLevel) {
if (stObj->pt) if (stObj->pt)
@ -1488,18 +1476,11 @@ st_finalize_texture(GLcontext *ctx,
/* Check texture can hold all active levels. Check texture matches /* Check texture can hold all active levels. Check texture matches
* target, imageFormat, etc. * 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 && if (stObj->pt &&
(stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
stObj->pt->format != stObj->pt->format !=
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) || st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) ||
stObj->pt->first_level != stObj->firstLevel ||
stObj->pt->last_level != stObj->lastLevel || stObj->pt->last_level != stObj->lastLevel ||
stObj->pt->width[0] != firstImage->base.Width || stObj->pt->width[0] != firstImage->base.Width ||
stObj->pt->height[0] != firstImage->base.Height || stObj->pt->height[0] != firstImage->base.Height ||
@ -1516,7 +1497,7 @@ st_finalize_texture(GLcontext *ctx,
stObj->pt = st_texture_create(ctx->st, stObj->pt = st_texture_create(ctx->st,
gl_target_to_pipe(stObj->base.Target), gl_target_to_pipe(stObj->base.Target),
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
stObj->firstLevel, 0, /* first level */
stObj->lastLevel, stObj->lastLevel,
firstImage->base.Width, firstImage->base.Width,
firstImage->base.Height, firstImage->base.Height,
@ -1527,14 +1508,16 @@ st_finalize_texture(GLcontext *ctx,
/* Pull in any images not in the object's texture: /* Pull in any images not in the object's texture:
*/ */
for (face = 0; face < nr_faces; face++) { 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 = 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. /* Need to import images in main memory or held in other textures.
*/ */
if (stObj->pt != stImage->pt) { 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; *needFlush = GL_TRUE;
} }
} }

View file

@ -51,7 +51,6 @@
static void *blend_cso = NULL; static void *blend_cso = NULL;
static void *depthstencil_cso = NULL; static void *depthstencil_cso = NULL;
static void *rasterizer_cso = NULL; static void *rasterizer_cso = NULL;
static void *sampler_cso = NULL;
static struct st_fragment_program *stfp = NULL; static struct st_fragment_program *stfp = NULL;
static struct st_vertex_program *stvp = 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_context *pipe = st->pipe;
struct pipe_blend_state blend; struct pipe_blend_state blend;
struct pipe_rasterizer_state rasterizer; struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_depth_stencil_alpha_state depthstencil;
assert(!blend_cso); assert(!blend_cso);
@ -133,16 +131,6 @@ st_init_generate_mipmap(struct st_context *st)
memset(&rasterizer, 0, sizeof(rasterizer)); memset(&rasterizer, 0, sizeof(rasterizer));
rasterizer_cso = pipe->create_rasterizer_state(pipe, &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); stfp = make_tex_fragment_program(st->ctx);
stvp = st_make_passthrough_vertex_shader(st, GL_FALSE); 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_blend_state(pipe, blend_cso);
pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso); pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso);
pipe->delete_rasterizer_state(pipe, rasterizer_cso); pipe->delete_rasterizer_state(pipe, rasterizer_cso);
pipe->delete_sampler_state(pipe, sampler_cso);
/* XXX free stfp, stvp */ /* XXX free stfp, stvp */
blend_cso = NULL; blend_cso = NULL;
depthstencil_cso = NULL; depthstencil_cso = NULL;
rasterizer_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_context *pipe = st->pipe;
struct pipe_framebuffer_state fb; 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 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; uint dstLevel;
assert(target != GL_TEXTURE_3D); /* not done yet */ assert(target != GL_TEXTURE_3D); /* not done yet */
@ -263,11 +251,21 @@ st_render_mipmap(struct st_context *st,
memset(&fb, 0, sizeof(fb)); memset(&fb, 0, sizeof(fb));
fb.num_cbufs = 1; 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 */ /* bind CSOs */
pipe->bind_blend_state(pipe, blend_cso); pipe->bind_blend_state(pipe, blend_cso);
pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso); pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso);
pipe->bind_rasterizer_state(pipe, rasterizer_cso); pipe->bind_rasterizer_state(pipe, rasterizer_cso);
pipe->bind_sampler_state(pipe, 0, sampler_cso);
/* bind shaders */ /* bind shaders */
pipe->bind_fs_state(pipe, stfp->fs->data); 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); fb.cbufs[0] = pipe->get_tex_surface(pipe, pt, face, dstLevel, zslice);
pipe->set_framebuffer_state(pipe, &fb); 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]); simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
/* /*
* Setup src texture, override pt->first_level so we sample from * Setup src texture, override pt->first_level so we sample from
* the right mipmap level. * the right mipmap level.
*/ */
pt->first_level = srcLevel; /*pt->first_level = srcLevel;*/
pipe->set_sampler_texture(pipe, 0, pt); pipe->set_sampler_texture(pipe, 0, pt);
draw_quad(st->ctx); draw_quad(st->ctx);
pipe->delete_sampler_state(pipe, sampler_cso);
} }
/* restore first_level */ /* restore first_level */
pt->first_level = first_level_save; /*pt->first_level = first_level_save;*/
/* restore pipe state */ /* restore pipe state */
if (st->state.rasterizer) if (st->state.rasterizer)

View file

@ -62,6 +62,10 @@ target_to_target(GLenum target)
/** /**
* Allocate a new pipe_texture object * 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 * struct pipe_texture *
st_texture_create(struct st_context *st, st_texture_create(struct st_context *st,
@ -84,9 +88,9 @@ st_texture_create(struct st_context *st,
assert(format); assert(format);
memset(&pt, 0, sizeof(pt));
pt.target = target; pt.target = target;
pt.format = format; pt.format = format;
pt.first_level = first_level;
pt.last_level = last_level; pt.last_level = last_level;
pt.width[0] = width0; pt.width[0] = width0;
pt.height[0] = height0; pt.height[0] = height0;
@ -266,23 +270,36 @@ st_texture_image_data(struct pipe_context *pipe,
*/ */
void void
st_texture_image_copy(struct pipe_context *pipe, st_texture_image_copy(struct pipe_context *pipe,
struct pipe_texture *dst, struct pipe_texture *dst, GLuint dstLevel,
GLuint face, GLuint level, struct pipe_texture *src,
struct pipe_texture *src) GLuint face)
{ {
GLuint width = src->width[level]; GLuint width = dst->width[dstLevel];
GLuint height = src->height[level]; GLuint height = dst->height[dstLevel];
GLuint depth = src->depth[level]; GLuint depth = dst->depth[dstLevel];
struct pipe_surface *src_surface; struct pipe_surface *src_surface;
struct pipe_surface *dst_surface; struct pipe_surface *dst_surface;
GLuint i; GLuint i;
/* XXX this is a hack */
if (dst->compressed) if (dst->compressed)
height /= 4; height /= 4;
for (i = 0; i < depth; i++) { for (i = 0; i < depth; i++) {
dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i); GLuint srcLevel;
src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
/* 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, pipe->surface_copy(pipe,
dst_surface, dst_surface,

View file

@ -98,9 +98,9 @@ st_texture_image_data(struct pipe_context *pipe,
*/ */
extern void extern void
st_texture_image_copy(struct pipe_context *pipe, st_texture_image_copy(struct pipe_context *pipe,
struct pipe_texture *dst, struct pipe_texture *dst, GLuint dstLevel,
GLuint face, GLuint level, struct pipe_texture *src,
struct pipe_texture *src); GLuint face);
#endif #endif