diff options
author | Michel Dänzer <[email protected]> | 2007-11-30 20:48:03 +0100 |
---|---|---|
committer | Michel Dänzer <[email protected]> | 2007-12-06 11:18:11 +0100 |
commit | 753db0d8407147393a7b0622ae3fa28f68d0353d (patch) | |
tree | 8c11ae7b18cb34ae65e984fc7d9be50616bf99d4 | |
parent | 59356268187470c5fda9e9a1a7058607f938fb3b (diff) |
Hide texture layout details from the state tracker.
pipe->get_tex_surface() has to be used for access to texture image data.
42 files changed, 933 insertions, 886 deletions
diff --git a/src/mesa/drivers/dri/intel_winsys/intel_screen.c b/src/mesa/drivers/dri/intel_winsys/intel_screen.c index 01460e5be3c..1b520f71353 100644 --- a/src/mesa/drivers/dri/intel_winsys/intel_screen.c +++ b/src/mesa/drivers/dri/intel_winsys/intel_screen.c @@ -328,8 +328,8 @@ intelSetTexOffset(__DRIcontext *pDRICtx, int texname, if (!stObj) return; - if (stObj->mt) - st_miptree_release(intel->st->pipe, &stObj->mt); + if (stObj->pt) + st->pipe->texture_release(intel->st->pipe, &stObj->pt); stObj->imageOverride = GL_TRUE; stObj->depthOverride = depth; diff --git a/src/mesa/pipe/failover/fo_context.c b/src/mesa/pipe/failover/fo_context.c index 0cc9cab408c..a25563d4511 100644 --- a/src/mesa/pipe/failover/fo_context.c +++ b/src/mesa/pipe/failover/fo_context.c @@ -145,7 +145,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.surface_data = hw->surface_data; failover->pipe.surface_copy = hw->surface_copy; failover->pipe.surface_fill = hw->surface_fill; - failover->pipe.mipmap_tree_layout = hw->mipmap_tree_layout; + failover->pipe.texture_create = hw->texture_create; + failover->pipe.texture_release = hw->texture_release; failover->pipe.flush = hw->flush; failover->dirty = 0; diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h index 759b53ccbe4..7cf18c9ec19 100644 --- a/src/mesa/pipe/failover/fo_context.h +++ b/src/mesa/pipe/failover/fo_context.h @@ -85,7 +85,7 @@ struct failover_context { struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; uint sampler_units[PIPE_MAX_SAMPLERS]; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c index 2cd1a50b203..fd6137ba662 100644 --- a/src/mesa/pipe/failover/fo_state.c +++ b/src/mesa/pipe/failover/fo_state.c @@ -402,7 +402,7 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler) static void failover_set_texture_state(struct pipe_context *pipe, unsigned unit, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { struct failover_context *failover = failover_context(pipe); diff --git a/src/mesa/pipe/i915simple/Makefile b/src/mesa/pipe/i915simple/Makefile index 391a084915d..1223b386a3d 100644 --- a/src/mesa/pipe/i915simple/Makefile +++ b/src/mesa/pipe/i915simple/Makefile @@ -22,7 +22,7 @@ DRIVER_SOURCES = \ i915_strings.c \ i915_prim_emit.c \ i915_prim_vbuf.c \ - i915_tex_layout.c \ + i915_texture.c \ i915_fpc_emit.c \ i915_fpc_translate.c \ i915_surface.c diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c index a0ed3032b12..94649231cf3 100644 --- a/src/mesa/pipe/i915simple/i915_context.c +++ b/src/mesa/pipe/i915simple/i915_context.c @@ -29,7 +29,7 @@ #include "i915_winsys.h" #include "i915_state.h" #include "i915_batch.h" -#include "i915_tex_layout.h" +#include "i915_texture.h" #include "i915_reg.h" #include "pipe/draw/draw_context.h" @@ -357,11 +357,8 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys, i915->pci_id = pci_id; i915->flags.is_i945 = is_i945; - if (i915->flags.is_i945) - i915->pipe.mipmap_tree_layout = i945_miptree_layout; - else - i915->pipe.mipmap_tree_layout = i915_miptree_layout; - + i915->pipe.texture_create = i915_texture_create; + i915->pipe.texture_release = i915_texture_release; i915->dirty = ~0; i915->hardware_dirty = ~0; diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h index ee430ebc902..8ed3465be23 100644 --- a/src/mesa/pipe/i915simple/i915_context.h +++ b/src/mesa/pipe/i915simple/i915_context.h @@ -150,6 +150,34 @@ struct i915_alpha_test_state { unsigned LIS6; }; +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_region *region; +}; + struct i915_context { struct pipe_context pipe; @@ -174,7 +202,7 @@ struct i915_context struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; uint sampler_units[PIPE_MAX_SAMPLERS]; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c index 468d0ce91b1..038fd623ea1 100644 --- a/src/mesa/pipe/i915simple/i915_state.c +++ b/src/mesa/pipe/i915simple/i915_state.c @@ -525,11 +525,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, static void i915_set_texture_state(struct pipe_context *pipe, unsigned unit, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { struct i915_context *i915 = i915_context(pipe); - i915->texture[unit] = texture; /* ptr, not struct */ + i915->texture[unit] = (struct i915_texture*)texture; /* ptr, not struct */ i915->dirty |= I915_NEW_TEXTURE; } diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c index 0991e6ac0d1..1816d9abdb7 100644 --- a/src/mesa/pipe/i915simple/i915_state_sampler.c +++ b/src/mesa/pipe/i915simple/i915_state_sampler.c @@ -46,9 +46,11 @@ static void update_sampler(struct i915_context *i915, uint unit, const struct i915_sampler_state *sampler, - const struct pipe_mipmap_tree *mt, + const struct i915_texture *tex, unsigned state[3] ) { + const struct pipe_texture *pt = &tex->base; + /* Need to do this after updating the maps, which call the * intel_finalize_mipmap_tree and hence can update firstLevel: */ @@ -56,8 +58,8 @@ static void update_sampler(struct i915_context *i915, state[1] = sampler->state[1]; state[2] = sampler->state[2]; - if (mt->format == PIPE_FORMAT_YCBCR || - mt->format == PIPE_FORMAT_YCBCR_REV) + if (pt->format == PIPE_FORMAT_YCBCR || + pt->format == PIPE_FORMAT_YCBCR_REV) state[0] |= SS2_COLORSPACE_CONVERSION; /* 3D textures don't seem to respect the border color. @@ -75,7 +77,7 @@ static void update_sampler(struct i915_context *i915, const unsigned ws = sampler->templ->wrap_s; const unsigned wt = sampler->templ->wrap_t; const unsigned wr = sampler->templ->wrap_r; - if (mt->target == PIPE_TEXTURE_3D && + if (pt->target == PIPE_TEXTURE_3D && (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST || sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) && (ws == PIPE_TEX_WRAP_CLAMP || @@ -105,13 +107,13 @@ void i915_update_samplers( struct i915_context *i915 ) i915->current.sampler_enable_flags = 0x0; for (unit = 0; unit < I915_TEX_UNITS; unit++) { - /* determine unit enable/disable by looking for a bound mipmap tree */ + /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { update_sampler( i915, unit, i915->sampler[unit], /* sampler state */ - i915->texture[unit], /* mipmap tree */ + i915->texture[unit], /* texture */ i915->current.sampler[unit] /* the result */ ); @@ -179,18 +181,19 @@ static void i915_update_texture(struct i915_context *i915, uint unit, uint state[6]) { - const struct pipe_mipmap_tree *mt = i915->texture[unit]; + const struct i915_texture *tex = i915->texture[unit]; + const struct pipe_texture *pt = &tex->base; uint format, pitch; - const uint width = mt->width0, height = mt->height0, depth = mt->depth0; - const uint num_levels = mt->last_level - mt->first_level; + const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + const uint num_levels = pt->last_level - pt->first_level; - assert(mt); + assert(tex); assert(width); assert(height); assert(depth); - format = translate_texture_format(mt->format); - pitch = mt->pitch * mt->cpp; + format = translate_texture_format(pt->format); + pitch = tex->pitch * pt->cpp; assert(format); assert(pitch); @@ -217,7 +220,7 @@ i915_update_textures(struct i915_context *i915) uint unit; for (unit = 0; unit < I915_TEX_UNITS; unit++) { - /* determine unit enable/disable by looking for a bound mipmap tree */ + /* determine unit enable/disable by looking for a bound texture */ /* could also examine the fragment program? */ if (i915->texture[unit]) { i915_update_texture(i915, unit, i915->current.texbuffer[unit]); diff --git a/src/mesa/pipe/i915simple/i915_surface.c b/src/mesa/pipe/i915simple/i915_surface.c index e4a5de00d77..385202507db 100644 --- a/src/mesa/pipe/i915simple/i915_surface.c +++ b/src/mesa/pipe/i915simple/i915_surface.c @@ -187,34 +187,35 @@ i915_put_tile(struct pipe_context *pipe, */ static struct pipe_surface * i915_get_tex_surface(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_surface *ps; unsigned offset; /* in bytes */ - offset = mt->level[level].level_offset; + offset = tex->level_offset[level]; - if (mt->target == PIPE_TEXTURE_CUBE) { - offset += mt->level[level].image_offset[face] * mt->cpp; + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += tex->image_offset[level][face] * pt->cpp; } - else if (mt->target == PIPE_TEXTURE_3D) { - offset += mt->level[level].image_offset[zslice] * mt->cpp; + else if (pt->target == PIPE_TEXTURE_3D) { + offset += tex->image_offset[level][zslice] * pt->cpp; } else { assert(face == 0); assert(zslice == 0); } - ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format); + ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format); if (ps) { assert(ps->format); assert(ps->refcount); - pipe_region_reference(&ps->region, mt->region); - ps->cpp = mt->cpp; - ps->width = mt->level[level].width; - ps->height = mt->level[level].height; - ps->pitch = mt->pitch; + pipe_region_reference(&ps->region, tex->region); + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = tex->pitch; ps->offset = offset; } return ps; diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.h b/src/mesa/pipe/i915simple/i915_tex_layout.h deleted file mode 100644 index e0337863815..00000000000 --- a/src/mesa/pipe/i915simple/i915_tex_layout.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef I915_TEX_LAYOUT_H -#define I915_TEX_LAYOUT_H - -struct pipe_context; -struct pipe_mipmap_tree; - - -extern boolean -i915_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *); - -extern boolean -i945_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *); - - -#endif /* I915_TEX_LAYOUT_H */ diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.c b/src/mesa/pipe/i915simple/i915_texture.c index cb372a7170d..3bfa806d9ec 100644 --- a/src/mesa/pipe/i915simple/i915_tex_layout.c +++ b/src/mesa/pipe/i915simple/i915_texture.c @@ -34,8 +34,10 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" +#include "pipe/p_winsys.h" -#include "i915_tex_layout.h" +#include "i915_context.h" +#include "i915_texture.h" #include "i915_debug.h" @@ -51,94 +53,98 @@ static int align(int value, int alignment) static void -i915_miptree_set_level_info(struct pipe_mipmap_tree *mt, +i915_miptree_set_level_info(struct i915_texture *tex, unsigned level, unsigned nr_images, unsigned x, unsigned y, unsigned w, unsigned h, unsigned d) { + struct pipe_texture *pt = &tex->base; + assert(level < PIPE_MAX_TEXTURE_LEVELS); - mt->level[level].width = w; - mt->level[level].height = h; - mt->level[level].depth = d; - mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; - mt->level[level].nr_images = nr_images; + pt->width[level] = w; + pt->height[level] = h; + pt->depth[level] = d; + + tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp; + tex->nr_images[level] = nr_images; /* DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - level, w, h, d, x, y, mt->level[level].level_offset); + level, w, h, d, x, y, tex->level_offset[level]); */ /* Not sure when this would happen, but anyway: */ - if (mt->level[level].image_offset) { - FREE(mt->level[level].image_offset); - mt->level[level].image_offset = NULL; + if (tex->image_offset[level]) { + FREE(tex->image_offset[level]); + tex->image_offset[level] = NULL; } assert(nr_images); - assert(!mt->level[level].image_offset); + assert(!tex->image_offset[level]); - mt->level[level].image_offset = (unsigned *) MALLOC(nr_images * sizeof(unsigned)); - mt->level[level].image_offset[0] = 0; + tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned)); + tex->image_offset[level][0] = 0; } static void -i915_miptree_set_image_offset(struct pipe_mipmap_tree *mt, - unsigned level, unsigned img, unsigned x, unsigned y) +i915_miptree_set_image_offset(struct i915_texture *tex, + unsigned level, unsigned img, unsigned x, unsigned y) { if (img == 0 && level == 0) assert(x == 0 && y == 0); - assert(img < mt->level[level].nr_images); + assert(img < tex->nr_images[level]); - mt->level[level].image_offset[img] = (x + y * mt->pitch); + tex->image_offset[level][img] = (x + y * tex->pitch); /* DBG("%s level %d img %d pos %d,%d image_offset %x\n", - __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); + __FUNCTION__, level, img, x, y, tex->image_offset[level][img]); */ } static void -i945_miptree_layout_2d( struct pipe_mipmap_tree *mt ) +i945_miptree_layout_2d( struct i915_texture *tex ) { + struct pipe_texture *pt = &tex->base; int align_h = 2, align_w = 4; unsigned level; unsigned x = 0; unsigned y = 0; - unsigned width = mt->width0; - unsigned height = mt->height0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; - mt->pitch = mt->width0; + tex->pitch = pt->width[0]; /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (mt->first_level != mt->last_level) { - unsigned mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + if (pt->first_level != pt->last_level) { + unsigned mip1_width = align(minify(pt->width[0]), align_w) + + minify(minify(pt->width[0])); - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > pt->width[0]) + tex->pitch = mip1_width; } /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; - mt->total_height = 0; + tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp; + tex->total_height = 0; - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { unsigned img_height; - i915_miptree_set_level_info(mt, level, 1, x, y, width, height, 1); + i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1); - if (mt->compressed) + if (pt->compressed) img_height = MAX2(1, height/4); else img_height = align(height, align_h); @@ -147,11 +153,11 @@ i945_miptree_layout_2d( struct pipe_mipmap_tree *mt ) /* Because the images are packed better, the final offset * might not be the maximal one: */ - mt->total_height = MAX2(mt->total_height, y + img_height); + tex->total_height = MAX2(tex->total_height, y + img_height); /* Layout_below: step right after second mipmap. */ - if (level == mt->first_level + 1) { + if (level == pt->first_level + 1) { x += align(width, align_w); } else { @@ -183,27 +189,28 @@ static const int step_offsets[6][2] = { }; -boolean -i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) +static boolean +i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) { + struct pipe_texture *pt = &tex->base; unsigned level; - switch (mt->target) { + switch (pt->target) { case PIPE_TEXTURE_CUBE: { - const unsigned dim = mt->width0; + const unsigned dim = pt->width[0]; unsigned face; - unsigned lvlWidth = mt->width0, lvlHeight = mt->height0; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; assert(lvlWidth == lvlHeight); /* cubemap images are square */ /* double pitch for cube layouts */ - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; - mt->total_height = dim * 4; + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; + tex->total_height = dim * 4; - for (level = mt->first_level; level <= mt->last_level; level++) { - i915_miptree_set_level_info(mt, level, 6, + for (level = pt->first_level; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, 0, 0, - /*OLD: mt->pitch, mt->total_height,*/ + /*OLD: tex->pitch, tex->total_height,*/ lvlWidth, lvlHeight, 1); lvlWidth /= 2; @@ -215,8 +222,8 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) unsigned y = initial_offsets[face][1] * dim; unsigned d = dim; - for (level = mt->first_level; level <= mt->last_level; level++) { - i915_miptree_set_image_offset(mt, level, face, x, y); + for (level = pt->first_level; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; x += step_offsets[face][0] * d; y += step_offsets[face][1] * d; @@ -225,20 +232,20 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) break; } case PIPE_TEXTURE_3D:{ - unsigned width = mt->width0; - unsigned height = mt->height0; - unsigned depth = mt->depth0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; unsigned stack_height = 0; /* Calculate the size of a single slice. */ - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; /* XXX: hardware expects/requires 9 levels at minimum. */ - for (level = mt->first_level; level <= MAX2(8, mt->last_level); + for (level = pt->first_level; level <= MAX2(8, pt->last_level); level++) { - i915_miptree_set_level_info(mt, level, depth, 0, mt->total_height, + i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height, width, height, depth); @@ -251,11 +258,11 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) /* Fixup depth image_offsets: */ - depth = mt->depth0; - for (level = mt->first_level; level <= mt->last_level; level++) { + depth = pt->depth[0]; + for (level = pt->first_level; level <= pt->last_level; level++) { unsigned i; for (i = 0; i < depth; i++) - i915_miptree_set_image_offset(mt, level, i, + i915_miptree_set_image_offset(tex, level, i, 0, i * stack_height); depth = minify(depth); @@ -266,29 +273,29 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) * remarkable how wasteful of memory the i915 texture layouts * are. They are largely fixed in the i945. */ - mt->total_height = stack_height * mt->depth0; + tex->total_height = stack_height * pt->depth[0]; break; } default:{ - unsigned width = mt->width0; - unsigned height = mt->height0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; unsigned img_height; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->total_height = 0; - for (level = mt->first_level; level <= mt->last_level; level++) { - i915_miptree_set_level_info(mt, level, 1, - 0, mt->total_height, + for (level = pt->first_level; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 1, + 0, tex->total_height, width, height, 1); - if (mt->compressed) + if (pt->compressed) img_height = MAX2(1, height / 4); else img_height = (MAX2(2, height) + 1) & ~1; - mt->total_height += img_height; + tex->total_height += img_height; width = minify(width); height = minify(height); @@ -298,24 +305,25 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) } /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + tex->pitch, + tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); */ return TRUE; } -boolean -i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) +static boolean +i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex) { + struct pipe_texture *pt = &tex->base; unsigned level; - switch (mt->target) { + switch (pt->target) { case PIPE_TEXTURE_CUBE:{ - const unsigned dim = mt->width0; + const unsigned dim = pt->width[0]; unsigned face; - unsigned lvlWidth = mt->width0, lvlHeight = mt->height0; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; assert(lvlWidth == lvlHeight); /* cubemap images are square */ @@ -324,16 +332,16 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) * or the final row of 4x4, 2x2 and 1x1 faces below this. */ if (dim > 32) - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; else - mt->pitch = 14 * 8; + tex->pitch = 14 * 8; - mt->total_height = dim * 4 + 4; + tex->total_height = dim * 4 + 4; /* Set all the levels to effectively occupy the whole rectangular region. */ - for (level = mt->first_level; level <= mt->last_level; level++) { - i915_miptree_set_level_info(mt, level, 6, + for (level = pt->first_level; level <= pt->last_level; level++) { + i915_miptree_set_level_info(tex, level, 6, 0, 0, lvlWidth, lvlHeight, 1); lvlWidth /= 2; @@ -347,16 +355,16 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) unsigned d = dim; if (dim == 4 && face >= 4) { - y = mt->total_height - 4; + y = tex->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0 || mt->first_level > 0)) { - y = mt->total_height - 4; + else if (dim < 4 && (face > 0 || pt->first_level > 0)) { + y = tex->total_height - 4; x = face * 8; } - for (level = mt->first_level; level <= mt->last_level; level++) { - i915_miptree_set_image_offset(mt, level, face, x, y); + for (level = pt->first_level; level <= pt->last_level; level++) { + i915_miptree_set_image_offset(tex, level, face, x, y); d >>= 1; @@ -375,13 +383,13 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) break; case PIPE_TEX_FACE_POS_Z: case PIPE_TEX_FACE_NEG_Z: - y = mt->total_height - 4; + y = tex->total_height - 4; x = (face - 4) * 8; break; } case 2: - y = mt->total_height - 4; + y = tex->total_height - 4; x = 16 + face * 8; break; @@ -399,33 +407,33 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) break; } case PIPE_TEXTURE_3D:{ - unsigned width = mt->width0; - unsigned height = mt->height0; - unsigned depth = mt->depth0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; + tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + tex->total_height = 0; - pack_y_pitch = MAX2(mt->height0, 2); - pack_x_pitch = mt->pitch; + pack_y_pitch = MAX2(pt->height[0], 2); + pack_x_pitch = tex->pitch; pack_x_nr = 1; - for (level = mt->first_level; level <= mt->last_level; level++) { - unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6; + for (level = pt->first_level; level <= pt->last_level; level++) { + unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; unsigned q, j; - i915_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, + i915_miptree_set_level_info(tex, level, nr_images, + 0, tex->total_height, width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - i915_miptree_set_image_offset(mt, level, q, x, y); + i915_miptree_set_image_offset(tex, level, q, x, y); x += pack_x_pitch; } @@ -434,12 +442,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) } - mt->total_height += y; + tex->total_height += y; if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); + assert(pack_x_pitch * pack_x_nr <= tex->pitch); } if (pack_y_pitch > 2) { @@ -456,7 +464,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: // case PIPE_TEXTURE_RECTANGLE: - i945_miptree_layout_2d(mt); + i945_miptree_layout_2d(tex); break; default: assert(0); @@ -465,10 +473,67 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + tex->pitch, + tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp); */ return TRUE; } +void +i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct i915_texture *tex = REALLOC(*pt, sizeof(struct pipe_texture), + sizeof(struct i915_texture)); + + if (tex) { + struct i915_context *i915 = i915_context(pipe); + + memset(&tex->base + 1, 0, + sizeof(struct i915_texture) - sizeof(struct pipe_texture)); + + if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) : + i915_miptree_layout(pipe, tex)) { + tex->region = pipe->winsys->region_alloc(pipe->winsys, + tex->pitch * tex->base.cpp * + tex->total_height, + PIPE_SURFACE_FLAG_TEXTURE); + } + + if (!tex->region) { + FREE(tex); + tex = NULL; + } + } + + *pt = &tex->base; +} + +void +i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct i915_texture *tex = (struct i915_texture *)*pt; + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) tex); + */ + + pipe->winsys->region_release(pipe->winsys, &tex->region); + + for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) + if (tex->image_offset[i]) + free(tex->image_offset[i]); + + free(tex); + } + *pt = NULL; +} diff --git a/src/mesa/pipe/i915simple/i915_texture.h b/src/mesa/pipe/i915simple/i915_texture.h new file mode 100644 index 00000000000..84a0502e81a --- /dev/null +++ b/src/mesa/pipe/i915simple/i915_texture.h @@ -0,0 +1,16 @@ + +#ifndef I915_TEXTURE_H +#define I915_TEXTURE_H + +struct pipe_context; +struct pipe_texture; + + +extern void +i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt); + +extern void +i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + + +#endif /* I915_TEXTURE_H */ diff --git a/src/mesa/pipe/llvm/llvm_entry.c b/src/mesa/pipe/llvm/llvm_entry.c index 2459d14cb82..fe32e7810dc 100644 --- a/src/mesa/pipe/llvm/llvm_entry.c +++ b/src/mesa/pipe/llvm/llvm_entry.c @@ -194,7 +194,6 @@ void run_vertex_shader(float (*ainputs)[16][4], struct pipe_sampler_state; -struct pipe_mipmap_tree; struct softpipe_tile_cache; #define NUM_CHANNELS 4 /* R,G,B,A */ @@ -203,7 +202,6 @@ struct softpipe_tile_cache; struct tgsi_sampler { const struct pipe_sampler_state *state; - struct pipe_mipmap_tree *texture; /** Get samples for four fragments in a quad */ void (*get_samples)(struct tgsi_sampler *sampler, const float s[QUAD_SIZE], diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h index e145b22f2ff..5033209323f 100644 --- a/src/mesa/pipe/p_context.h +++ b/src/mesa/pipe/p_context.h @@ -155,7 +155,7 @@ struct pipe_context { void (*set_texture_state)( struct pipe_context *, unsigned unit, - struct pipe_mipmap_tree * ); + struct pipe_texture * ); void (*set_viewport_state)( struct pipe_context *, const struct pipe_viewport_state * ); @@ -180,7 +180,7 @@ struct pipe_context { /** Get a surface which is a "view" into a texture */ struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe, - struct pipe_mipmap_tree *texture, + struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice); @@ -237,8 +237,11 @@ struct pipe_context { /* * Texture functions */ - boolean (*mipmap_tree_layout)( struct pipe_context *pipe, - struct pipe_mipmap_tree *mt ); + void (*texture_create)(struct pipe_context *pipe, + struct pipe_texture **pt); + + void (*texture_release)(struct pipe_context *pipe, + struct pipe_texture **pt); /* Flush rendering: diff --git a/src/mesa/pipe/p_inlines.h b/src/mesa/pipe/p_inlines.h index 2418d016e15..c04d46dddd8 100644 --- a/src/mesa/pipe/p_inlines.h +++ b/src/mesa/pipe/p_inlines.h @@ -80,4 +80,24 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) } } + +/** + * \sa pipe_region_reference + */ +static INLINE void +pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr, + struct pipe_texture *pt) +{ + assert(ptr); + if (*ptr) { + pipe->texture_release(pipe, ptr); + assert(!*ptr); + } + if (pt) { + /* reference the new thing */ + pt->refcount++; + *ptr = pt; + } +} + #endif /* P_INLINES_H */ diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h index 642734aeb80..077a8f5a06f 100644 --- a/src/mesa/pipe/p_state.h +++ b/src/mesa/pipe/p_state.h @@ -288,27 +288,11 @@ struct pipe_surface /** - * Describes the location of each texture image within a texture region. + * Texture. Represents one or several texture images on one or several mipmap + * levels. */ -struct pipe_mipmap_level -{ - unsigned level_offset; - unsigned width; - unsigned height; - unsigned depth; - unsigned nr_images; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - unsigned *image_offset; /**< array [depth] of offsets */ -}; - -struct pipe_mipmap_tree -{ +struct pipe_texture +{ /* Effectively the key: */ unsigned target; /* XXX convert to PIPE_TEXTURE_x */ @@ -318,25 +302,13 @@ struct pipe_mipmap_tree unsigned first_level; unsigned last_level; - unsigned width0, height0, depth0; /**< Level zero image dimensions */ + unsigned width[PIPE_MAX_TEXTURE_LEVELS]; + unsigned height[PIPE_MAX_TEXTURE_LEVELS]; + unsigned depth[PIPE_MAX_TEXTURE_LEVELS]; unsigned cpp; unsigned compressed:1; - /* Derived from the above: - */ - unsigned pitch; - unsigned depth_pitch; /* per-image on i945? */ - unsigned total_height; - - /* Includes image offset tables: - */ - struct pipe_mipmap_level level[PIPE_MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct pipe_region *region; - /* These are also refcounted: */ unsigned refcount; diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile index 59628531cc8..9978884c9bd 100644 --- a/src/mesa/pipe/softpipe/Makefile +++ b/src/mesa/pipe/softpipe/Makefile @@ -34,7 +34,7 @@ DRIVER_SOURCES = \ sp_state_rasterizer.c \ sp_state_surface.c \ sp_state_vertex.c \ - sp_tex_layout.c \ + sp_texture.c \ sp_tex_sample.c \ sp_tile_cache.c \ sp_surface.c diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index d5e68c189de..7a9fccce9ae 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -40,7 +40,7 @@ #include "sp_state.h" #include "sp_surface.h" #include "sp_tile_cache.h" -#include "sp_tex_layout.h" +#include "sp_texture.h" #include "sp_winsys.h" @@ -98,9 +98,9 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp) uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_mipmap_tree *mt = sp->texture[i]; - if (mt) { - pipe->region_map(pipe, mt->region); + struct softpipe_texture *spt = sp->texture[i]; + if (spt) { + pipe->region_map(pipe, spt->region); } } } @@ -146,9 +146,9 @@ softpipe_unmap_texture_surfaces(struct softpipe_context *sp) struct pipe_context *pipe = &sp->pipe; uint i; for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_mipmap_tree *mt = sp->texture[i]; - if (mt) { - pipe->region_unmap(pipe, mt->region); + struct softpipe_texture *spt = sp->texture[i]; + if (spt) { + pipe->region_unmap(pipe, spt->region); } } } @@ -351,7 +351,8 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.get_vendor = softpipe_get_vendor; /* textures */ - softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout; + softpipe->pipe.texture_create = softpipe_texture_create; + softpipe->pipe.texture_release = softpipe_texture_release; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; /* diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 872766101d5..d4763a98c66 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -89,7 +89,7 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; + struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index 24c8a44c479..7184fcda521 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -277,7 +277,7 @@ static void shade_begin(struct quad_stage *qs) /* set TGSI sampler state that varies */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = softpipe->texture[i]; + qss->samplers[i].texture = &softpipe->texture[i]->base; } #ifdef MESA_LLVM diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 2f096a9cc97..a543735b525 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -52,6 +52,35 @@ struct sp_fragment_shader_state { #endif }; +struct softpipe_texture +{ + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_region *region; +}; + void * softpipe_create_alpha_test_state(struct pipe_context *, const struct pipe_alpha_test_state *); @@ -125,7 +154,7 @@ void softpipe_set_scissor_state( struct pipe_context *, void softpipe_set_texture_state( struct pipe_context *, unsigned unit, - struct pipe_mipmap_tree * ); + struct pipe_texture * ); void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index 912f42d5688..a360b4f02b0 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -34,6 +34,8 @@ #include "pipe/draw/draw_context.h" #include "pipe/p_shader_tokens.h" #include "pipe/llvm/gallivm.h" +#include "pipe/tgsi/util/tgsi_dump.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" void * softpipe_create_fs_state(struct pipe_context *pipe, diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 246a7d6eda7..e71b9159e3f 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -68,12 +68,12 @@ softpipe_delete_sampler_state(struct pipe_context *pipe, void softpipe_set_texture_state(struct pipe_context *pipe, unsigned unit, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { struct softpipe_context *softpipe = softpipe_context(pipe); assert(unit < PIPE_MAX_SAMPLERS); - softpipe->texture[unit] = texture; /* ptr, not struct */ + softpipe->texture[unit] = (struct softpipe_texture *)texture; /* ptr, not struct */ sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index a6ab4046037..c41bbc59b90 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -565,34 +565,35 @@ z24s8_get_tile(struct pipe_surface *ps, */ struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + struct softpipe_texture *spt = (struct softpipe_texture *)pt; struct pipe_surface *ps; unsigned offset; /* in bytes */ - offset = mt->level[level].level_offset; + offset = spt->level_offset[level]; - if (mt->target == PIPE_TEXTURE_CUBE) { - offset += mt->level[level].image_offset[face] * mt->cpp; + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += spt->image_offset[level][face] * pt->cpp; } - else if (mt->target == PIPE_TEXTURE_3D) { - offset += mt->level[level].image_offset[zslice] * mt->cpp; + else if (pt->target == PIPE_TEXTURE_3D) { + offset += spt->image_offset[level][zslice] * pt->cpp; } else { assert(face == 0); assert(zslice == 0); } - ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format); + ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format); if (ps) { assert(ps->format); assert(ps->refcount); - pipe_region_reference(&ps->region, mt->region); - ps->cpp = mt->cpp; - ps->width = mt->level[level].width; - ps->height = mt->level[level].height; - ps->pitch = mt->pitch; + pipe_region_reference(&ps->region, spt->region); + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = spt->pitch; ps->offset = offset; } return ps; diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index cf87e1a92ce..b652e7598e8 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -41,7 +41,7 @@ struct softpipe_tile_cache; extern struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice); diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.h b/src/mesa/pipe/softpipe/sp_tex_layout.h deleted file mode 100644 index ea19c13b23f..00000000000 --- a/src/mesa/pipe/softpipe/sp_tex_layout.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef SP_TEX_LAYOUT_H -#define SP_TEX_LAYOUT_H - - -struct pipe_context; -struct pipe_mipmap_tree; - - -extern boolean -softpipe_mipmap_tree_layout(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt); - - -#endif /* SP_TEX_LAYOUT_H */ - - diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 92958400fc5..9e48ed0cd2c 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -422,7 +422,7 @@ compute_lambda(struct tgsi_sampler *sampler, dsdy = FABSF(dsdy); rho = MAX2(dsdx, dsdy); if (sampler->state->normalized_coords) - rho *= sampler->texture->width0; + rho *= sampler->texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -432,7 +432,7 @@ compute_lambda(struct tgsi_sampler *sampler, dtdy = FABSF(dtdy); max = MAX2(dtdx, dtdy); if (sampler->state->normalized_coords) - max *= sampler->texture->height0; + max *= sampler->texture->height[0]; rho = MAX2(rho, max); } if (p) { @@ -443,7 +443,7 @@ compute_lambda(struct tgsi_sampler *sampler, dpdy = FABSF(dpdy); max = MAX2(dpdx, dpdy); if (sampler->state->normalized_coords) - max *= sampler->texture->depth0; + max *= sampler->texture->depth[0]; rho = MAX2(rho, max); } @@ -620,8 +620,8 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler, &level0, &level1, &levelBlend, &imgFilter); if (sampler->state->normalized_coords) { - width = sampler->texture->level[level0].width; - height = sampler->texture->level[level0].height; + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; } else { width = height = 1; @@ -757,9 +757,9 @@ sp_get_samples_3d(struct tgsi_sampler *sampler, &level0, &level1, &levelBlend, &imgFilter); if (sampler->state->normalized_coords) { - width = sampler->texture->level[level0].width; - height = sampler->texture->level[level0].height; - depth = sampler->texture->level[level0].depth; + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + depth = sampler->texture->depth[level0]; } else { width = height = depth = 1; @@ -883,7 +883,7 @@ sp_get_samples_cube(struct tgsi_sampler *sampler, /** * Called via tgsi_sampler::get_samples() * Use the sampler's state setting to get a filtered RGBA value - * from the sampler's texture (mipmap tree). + * from the sampler's texture. * * XXX we can implement many versions of this function, each * tightly coded for a specific combination of sampler state diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.c b/src/mesa/pipe/softpipe/sp_texture.c index 8156b00301f..2f9a1e9837b 100644 --- a/src/mesa/pipe/softpipe/sp_tex_layout.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -33,7 +33,11 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "sp_tex_layout.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" /* At the moment, just make softpipe use the same layout for its @@ -54,100 +58,105 @@ static int align(int value, int alignment) static void -sp_miptree_set_level_info(struct pipe_mipmap_tree *mt, - unsigned level, - unsigned nr_images, - unsigned x, unsigned y, unsigned w, unsigned h, unsigned d) +sp_miptree_set_level_info(struct softpipe_texture *spt, + unsigned level, + unsigned nr_images, + unsigned x, unsigned y, unsigned w, unsigned h, + unsigned d) { + struct pipe_texture *pt = &spt->base; + assert(level < PIPE_MAX_TEXTURE_LEVELS); - mt->level[level].width = w; - mt->level[level].height = h; - mt->level[level].depth = d; - mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; - mt->level[level].nr_images = nr_images; + pt->width[level] = w; + pt->height[level] = h; + pt->depth[level] = d; + + spt->nr_images[level] = nr_images; + spt->level_offset[level] = (x + y * spt->pitch) * pt->cpp; /* DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - level, w, h, d, x, y, mt->level[level].level_offset); + level, w, h, d, x, y, spt->level_offset[level]); */ /* Not sure when this would happen, but anyway: */ - if (mt->level[level].image_offset) { - FREE( mt->level[level].image_offset ); - mt->level[level].image_offset = NULL; + if (spt->image_offset[level]) { + FREE( spt->image_offset[level] ); + spt->image_offset[level] = NULL; } assert(nr_images); - assert(!mt->level[level].image_offset); + assert(!spt->image_offset[level]); - mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) ); - mt->level[level].image_offset[0] = 0; + spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) ); + spt->image_offset[level][0] = 0; } static void -sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt, - unsigned level, unsigned img, unsigned x, unsigned y) +sp_miptree_set_image_offset(struct softpipe_texture *spt, + unsigned level, unsigned img, unsigned x, unsigned y) { if (img == 0 && level == 0) assert(x == 0 && y == 0); - assert(img < mt->level[level].nr_images); + assert(img < spt->nr_images[level]); - mt->level[level].image_offset[img] = (x + y * mt->pitch); + spt->image_offset[level][img] = (x + y * spt->pitch); /* DBG("%s level %d img %d pos %d,%d image_offset %x\n", - __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); + __FUNCTION__, level, img, x, y, spt->image_offset[level][img]); */ } static void -sp_miptree_layout_2d( struct pipe_mipmap_tree *mt ) +sp_miptree_layout_2d( struct softpipe_texture *spt ) { + struct pipe_texture *pt = &spt->base; int align_h = 2, align_w = 4; unsigned level; unsigned x = 0; unsigned y = 0; - unsigned width = mt->width0; - unsigned height = mt->height0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; - mt->pitch = mt->width0; + spt->pitch = pt->width[0]; /* XXX FIX THIS: * we use alignment=64 bytes in sp_region_alloc(). If we change * that, change this too. */ - if (mt->pitch < 16) - mt->pitch = 16; + if (spt->pitch < 16) + spt->pitch = 16; /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (mt->first_level != mt->last_level) { - unsigned mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + if (pt->first_level != pt->last_level) { + unsigned mip1_width = align(minify(pt->width[0]), align_w) + + minify(minify(pt->width[0])); - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > pt->width[0]) + spt->pitch = mip1_width; } /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; - mt->total_height = 0; + spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp; + spt->total_height = 0; - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { unsigned img_height; - sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1); + sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1); - if (mt->compressed) + if (pt->compressed) img_height = MAX2(1, height/4); else img_height = align(height, align_h); @@ -156,11 +165,11 @@ sp_miptree_layout_2d( struct pipe_mipmap_tree *mt ) /* Because the images are packed better, the final offset * might not be the maximal one: */ - mt->total_height = MAX2(mt->total_height, y + img_height); + spt->total_height = MAX2(spt->total_height, y + img_height); /* Layout_below: step right after second mipmap. */ - if (level == mt->first_level + 1) { + if (level == pt->first_level + 1) { x += align(width, align_w); } else { @@ -193,16 +202,17 @@ static const int step_offsets[6][2] = { -boolean -softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) +static boolean +softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt) { + struct pipe_texture *pt = &spt->base; unsigned level; - switch (mt->target) { + switch (pt->target) { case PIPE_TEXTURE_CUBE:{ - const unsigned dim = mt->width0; + const unsigned dim = pt->width[0]; unsigned face; - unsigned lvlWidth = mt->width0, lvlHeight = mt->height0; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; assert(lvlWidth == lvlHeight); /* cubemap images are square */ @@ -211,16 +221,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * * or the final row of 4x4, 2x2 and 1x1 faces below this. */ if (dim > 32) - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; else - mt->pitch = 14 * 8; + spt->pitch = 14 * 8; - mt->total_height = dim * 4 + 4; + spt->total_height = dim * 4 + 4; /* Set all the levels to effectively occupy the whole rectangular region. */ - for (level = mt->first_level; level <= mt->last_level; level++) { - sp_miptree_set_level_info(mt, level, 6, + for (level = pt->first_level; level <= pt->last_level; level++) { + sp_miptree_set_level_info(spt, level, 6, 0, 0, lvlWidth, lvlHeight, 1); lvlWidth /= 2; @@ -234,16 +244,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * unsigned d = dim; if (dim == 4 && face >= 4) { - y = mt->total_height - 4; + y = spt->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0 || mt->first_level > 0)) { - y = mt->total_height - 4; + else if (dim < 4 && (face > 0 || pt->first_level > 0)) { + y = spt->total_height - 4; x = face * 8; } - for (level = mt->first_level; level <= mt->last_level; level++) { - sp_miptree_set_image_offset(mt, level, face, x, y); + for (level = pt->first_level; level <= pt->last_level; level++) { + sp_miptree_set_image_offset(spt, level, face, x, y); d >>= 1; @@ -262,13 +272,13 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * break; case PIPE_TEX_FACE_POS_Z: case PIPE_TEX_FACE_NEG_Z: - y = mt->total_height - 4; + y = spt->total_height - 4; x = (face - 4) * 8; break; } case 2: - y = mt->total_height - 4; + y = spt->total_height - 4; x = 16 + face * 8; break; @@ -286,33 +296,33 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * break; } case PIPE_TEXTURE_3D:{ - unsigned width = mt->width0; - unsigned height = mt->height0; - unsigned depth = mt->depth0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; + spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + spt->total_height = 0; - pack_y_pitch = MAX2(mt->height0, 2); - pack_x_pitch = mt->pitch; + pack_y_pitch = MAX2(pt->height[0], 2); + pack_x_pitch = spt->pitch; pack_x_nr = 1; - for (level = mt->first_level; level <= mt->last_level; level++) { - unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6; + for (level = pt->first_level; level <= pt->last_level; level++) { + unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; unsigned q, j; - sp_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, - width, height, depth); + sp_miptree_set_level_info(spt, level, nr_images, + 0, spt->total_height, + width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - sp_miptree_set_image_offset(mt, level, q, x, y); + sp_miptree_set_image_offset(spt, level, q, x, y); x += pack_x_pitch; } @@ -321,12 +331,12 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * } - mt->total_height += y; + spt->total_height += y; if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); + assert(pack_x_pitch * pack_x_nr <= spt->pitch); } if (pack_y_pitch > 2) { @@ -343,7 +353,7 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: // case PIPE_TEXTURE_RECTANGLE: - sp_miptree_layout_2d(mt); + sp_miptree_layout_2d(spt); break; default: assert(0); @@ -352,10 +362,64 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + spt->pitch, + spt->total_height, pt->cpp, spt->pitch * spt->total_height * pt->cpp); */ return TRUE; } +void +softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct softpipe_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture), + sizeof(struct softpipe_texture)); + + if (spt) { + memset(&spt->base + 1, 0, + sizeof(struct softpipe_texture) - sizeof(struct pipe_texture)); + + if (softpipe_mipmap_tree_layout(pipe, spt)) { + spt->region = pipe->winsys->region_alloc(pipe->winsys, + spt->pitch * (*pt)->cpp * + spt->total_height, + PIPE_SURFACE_FLAG_TEXTURE); + } + + if (!spt->region) { + FREE(spt); + spt = NULL; + } + } + + *pt = &spt->base; +} + +void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = (struct softpipe_texture *)*pt; + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe->winsys->region_release(pipe->winsys, &spt->region); + + for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) + if (spt->image_offset[i]) + free(spt->image_offset[i]); + + free(spt); + } + *pt = NULL; +} diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h new file mode 100644 index 00000000000..2aca57bd1d2 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_texture.h @@ -0,0 +1,18 @@ +#ifndef SP_TEXTURE_H +#define SP_TEXTURE_H + + +struct pipe_context; +struct pipe_texture; + + +extern void +softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt); + +extern void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + + +#endif /* SP_TEXTURE */ + + diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index ea0c8b8f91d..62ee6a27c93 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -51,7 +51,7 @@ struct softpipe_tile_cache { struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_mipmap_tree *texture; /**< if caching a texture */ + struct pipe_texture *texture; /**< if caching a texture */ struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; float clear_value[4]; @@ -139,7 +139,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { uint i; diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index e66fec2e208..9967aa5044a 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -71,7 +71,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc); extern void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_mipmap_tree *texture); + struct pipe_texture *texture); extern void sp_flush_tile_cache(struct softpipe_context *softpipe, diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h index 1d497e97fb0..2c62b30f150 100644 --- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h +++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h @@ -76,7 +76,7 @@ struct softpipe_tile_cache; /**< Opaque to TGSI */ struct tgsi_sampler { const struct pipe_sampler_state *state; - struct pipe_mipmap_tree *texture; + struct pipe_texture *texture; /** Get samples for four fragments in a quad */ void (*get_samples)(struct tgsi_sampler *sampler, const float s[QUAD_SIZE], diff --git a/src/mesa/sources b/src/mesa/sources index 2df60d1996c..596d3b89d5d 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -236,7 +236,7 @@ STATETRACKER_SOURCES = \ state_tracker/st_framebuffer.c \ state_tracker/st_mesa_to_tgsi.c \ state_tracker/st_program.c \ - state_tracker/st_mipmap_tree.c + state_tracker/st_texture.c SHADER_SOURCES = \ shader/arbprogparse.c \ diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index f25cfd386a3..c4e5af02d59 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -51,24 +51,24 @@ update_textures(struct st_context *st) for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) { struct gl_texture_object *texObj = st->ctx->Texture.Unit[u]._Current; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; if (texObj) { GLboolean flush, retval; - retval = st_finalize_mipmap_tree(st->ctx, st->pipe, u, &flush); + retval = st_finalize_texture(st->ctx, st->pipe, u, &flush); #if 0 - printf("finalize_mipmap_tree returned %d, flush = %d\n", + printf("finalize_texture returned %d, flush = %d\n", retval, flush); #endif - mt = st_get_texobj_mipmap_tree(texObj); + pt = st_get_texobj_texture(texObj); } else { - mt = NULL; + pt = NULL; } - st->state.texture[u] = mt; - st->pipe->set_texture_state(st->pipe, u, mt); + st->state.texture[u] = pt; + st->pipe->set_texture_state(st->pipe, u, pt); } } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 39c0cf6b327..c28ad15b294 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -33,6 +33,7 @@ #include "main/imports.h" #include "main/image.h" #include "main/macros.h" +#include "main/texformat.h" #include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" @@ -50,6 +51,7 @@ #include "st_draw.h" #include "st_format.h" #include "st_mesa_to_tgsi.h" +#include "st_texture.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_inlines.h" @@ -440,63 +442,20 @@ _mesa_base_format(GLenum format) } - -static struct pipe_mipmap_tree * -alloc_mipmap_tree(struct st_context *st, - GLsizei width, GLsizei height, uint pipeFormat) -{ - const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE; - struct pipe_mipmap_tree *mt; - GLuint cpp; - - mt = CALLOC_STRUCT(pipe_mipmap_tree); - if (!mt) - return NULL; - - cpp = st_sizeof_format(pipeFormat); - - mt->target = PIPE_TEXTURE_2D; - mt->internal_format = GL_RGBA; - mt->format = pipeFormat; - mt->first_level = 0; - mt->last_level = 0; - mt->width0 = width; - mt->height0 = height; - mt->depth0 = 1; - mt->cpp = cpp; - mt->compressed = 0; - mt->pitch = st->pipe->winsys->surface_pitch(st->pipe->winsys, cpp, width, - flags); - mt->region = st->pipe->winsys->region_alloc(st->pipe->winsys, - mt->pitch * cpp * height, flags); - mt->depth_pitch = 0; - mt->total_height = height; - mt->level[0].level_offset = 0; - mt->level[0].width = width; - mt->level[0].height = height; - mt->level[0].depth = 1; - mt->level[0].nr_images = 1; - mt->level[0].image_offset = NULL; - mt->refcount = 1; - - return mt; -} - - /** - * Make mipmap tree containing an image for glDrawPixels image. + * Make texture containing an image for glDrawPixels image. * If 'pixels' is NULL, leave the texture image data undefined. */ -static struct pipe_mipmap_tree * -make_mipmap_tree(struct st_context *st, - GLsizei width, GLsizei height, GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels) +static struct pipe_texture * +make_texture(struct st_context *st, + GLsizei width, GLsizei height, GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels) { GLcontext *ctx = st->ctx; struct pipe_context *pipe = st->pipe; const struct gl_texture_format *mformat; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; GLuint pipeFormat, cpp; GLenum baseFormat; @@ -509,29 +468,33 @@ make_mipmap_tree(struct st_context *st, assert(pipeFormat); cpp = st_sizeof_format(pipeFormat); - mt = alloc_mipmap_tree(st, width, height, pipeFormat); - if (!mt) + pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, baseFormat, 0, 0, + width, height, 1, 0); + if (!pt) return NULL; if (unpack->BufferObj && unpack->BufferObj->Name) { /* - mt->region = buffer_object_region(unpack->BufferObj); + pt->region = buffer_object_region(unpack->BufferObj); */ printf("st_DrawPixels (sourcing from PBO not implemented yet)\n"); } { + struct pipe_surface *surface; static const GLuint dstImageOffsets = 0; GLboolean success; - GLuint pitch = mt->pitch; GLubyte *dest; const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; + surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0); + /* map texture region */ - dest = pipe->region_map(pipe, mt->region); + (void) pipe->region_map(pipe, surface->region); + dest = surface->region->map + surface->offset; /* Put image into texture region. * Note that the image is actually going to be upside down in @@ -542,7 +505,7 @@ make_mipmap_tree(struct st_context *st, mformat, /* gl_texture_format */ dest, /* dest */ 0, 0, 0, /* dstX/Y/Zoffset */ - pitch * cpp, /* dstRowStride, bytes */ + surface->pitch * cpp, /* dstRowStride, bytes */ &dstImageOffsets, /* dstImageOffsets */ width, height, 1, /* size */ format, type, /* src format/type */ @@ -550,44 +513,15 @@ make_mipmap_tree(struct st_context *st, unpack); /* unmap */ - pipe->region_unmap(pipe, mt->region); + pipe->region_unmap(pipe, surface->region); + pipe_surface_reference(&surface, NULL); assert(success); /* restore */ ctx->_ImageTransferState = imageTransferStateSave; } -#if 0 - mt->target = PIPE_TEXTURE_2D; - mt->internal_format = GL_RGBA; - mt->format = pipeFormat; - mt->first_level = 0; - mt->last_level = 0; - mt->width0 = width; - mt->height0 = height; - mt->depth0 = 1; - mt->cpp = cpp; - mt->compressed = 0; - mt->pitch = mt->pitch; - mt->depth_pitch = 0; - mt->total_height = height; - mt->level[0].level_offset = 0; - mt->level[0].width = width; - mt->level[0].height = height; - mt->level[0].depth = 1; - mt->level[0].nr_images = 1; - mt->level[0].image_offset = NULL; - mt->refcount = 1; -#endif - return mt; -} - - -static void -free_mipmap_tree(struct pipe_context *pipe, struct pipe_mipmap_tree *mt) -{ - pipe->winsys->region_release(pipe->winsys, &mt->region); - free(mt); + return pt; } @@ -693,7 +627,7 @@ static void draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, GLsizei width, GLsizei height, GLfloat zoomX, GLfloat zoomY, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, struct st_vertex_program *stvp, struct st_fragment_program *stfp, const GLfloat *color, @@ -761,9 +695,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->set_viewport_state(pipe, &vp); } - /* mipmap tree state: */ + /* texture state: */ { - pipe->set_texture_state(pipe, unit, mt); + pipe->set_texture_state(pipe, unit, pt); } /* Compute window coords (y=0=bottom) with pixel zoom. @@ -1025,14 +959,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, any_pixel_transfer_ops(st) || !compatible_formats(format, type, ps->format)) { /* textured quad */ - struct pipe_mipmap_tree *mt - = make_mipmap_tree(ctx->st, width, height, format, type, - unpack, pixels); - if (mt) { + struct pipe_texture *pt + = make_texture(ctx->st, width, height, format, type, unpack, pixels); + if (pt) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - mt, stvp, stfp, color, GL_FALSE); - free_mipmap_tree(st->pipe, mt); + pt, stvp, stfp, color, GL_FALSE); + st->pipe->texture_release(st->pipe, &pt); } } else { @@ -1046,26 +979,29 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /** * Create a texture which represents a bitmap image. */ -static struct pipe_mipmap_tree * +static struct pipe_texture * make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap) { struct pipe_context *pipe = ctx->st->pipe; - const uint flags = PIPE_SURFACE_FLAG_TEXTURE; + struct pipe_surface *surface; uint format = 0, cpp, comp; + GLenum internal_format; ubyte *dest; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; int row, col; /* find a texture format we know */ if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8 )) { format = PIPE_FORMAT_U_I8; + internal_format = GL_INTENSITY8; cpp = 1; comp = 0; } else if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8_R8_G8_B8 )) { format = PIPE_FORMAT_U_A8_R8_G8_B8; + internal_format = GL_RGBA8; cpp = 4; comp = 3; /* alpha channel */ /*XXX little-endian dependency */ } @@ -1075,31 +1011,25 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, } /** - * Create a mipmap tree. + * Create a texture. */ - mt = CALLOC_STRUCT(pipe_mipmap_tree); - if (!mt) + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, internal_format, + 0, 0, width, height, 1, 0); + if (!pt) return NULL; if (unpack->BufferObj && unpack->BufferObj->Name) { /* - mt->region = buffer_object_region(unpack->BufferObj); + pt->region = buffer_object_region(unpack->BufferObj); */ printf("st_Bitmap (sourcing from PBO not implemented yet)\n"); } - - /* allocate texture region/storage */ - mt->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp, width, flags); - mt->region = pipe->winsys->region_alloc(pipe->winsys, - mt->pitch * cpp * height, flags); + surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0); /* map texture region */ - dest = pipe->region_map(pipe, mt->region); - if (!dest) { - printf("st_Bitmap region_map() failed!?!"); - return NULL; - } + (void) pipe->region_map(pipe, surface->region); + dest = surface->region->map + surface->offset; /* Put image into texture region. * Note that the image is actually going to be upside down in @@ -1109,7 +1039,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, for (row = 0; row < height; row++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); - ubyte *destRow = dest + row * mt->pitch * cpp; + ubyte *destRow = dest + row * surface->pitch * cpp; if (unpack->LsbFirst) { /* Lsb first */ @@ -1158,30 +1088,13 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, } /* row */ - /* unmap */ - pipe->region_unmap(pipe, mt->region); - - mt->target = PIPE_TEXTURE_2D; - mt->internal_format = GL_RGBA; - mt->format = format; - mt->first_level = 0; - mt->last_level = 0; - mt->width0 = width; - mt->height0 = height; - mt->depth0 = 1; - mt->cpp = cpp; - mt->compressed = 0; - mt->depth_pitch = 0; - mt->total_height = height; - mt->level[0].level_offset = 0; - mt->level[0].width = width; - mt->level[0].height = height; - mt->level[0].depth = 1; - mt->level[0].nr_images = 1; - mt->level[0].image_offset = NULL; - mt->refcount = 1; - - return mt; + /* Release surface */ + pipe->region_unmap(pipe, surface->region); + pipe_surface_reference(&surface, NULL); + + pt->format = format; + + return pt; } @@ -1193,21 +1106,21 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct st_fragment_program *stfp; struct st_vertex_program *stvp; struct st_context *st = ctx->st; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; stvp = make_vertex_shader(ctx->st, GL_TRUE); stfp = combined_bitmap_fragment_program(ctx); st_validate_state(st); - mt = make_bitmap_texture(ctx, width, height, unpack, bitmap); - if (mt) { + pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); + if (pt) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], width, height, 1.0, 1.0, - mt, stvp, stfp, + pt, stvp, stfp, ctx->Current.RasterColor, GL_FALSE); - free_mipmap_tree(st->pipe, mt); + st->pipe->texture_release(st->pipe, &pt); } } @@ -1296,7 +1209,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_fragment_program *stfp; struct pipe_surface *psRead; struct pipe_surface *psTex; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; GLfloat *color; uint format; @@ -1327,11 +1240,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, psRead = rbRead->surface; format = psRead->format; - mt = alloc_mipmap_tree(ctx->st, width, height, format); - if (!mt) + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, + rbRead->Base.InternalFormat, 0, 0, width, height, 1, 0); + if (!pt) return; - psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0); + psTex = pipe->get_tex_surface(pipe, pt, 0, 0, 0); if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { srcy = ctx->DrawBuffer->Height - srcy - height; @@ -1368,10 +1282,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, - mt, stvp, stfp, color, GL_TRUE); + pt, stvp, stfp, color, GL_TRUE); pipe_surface_reference(&psTex, NULL); - free_mipmap_tree(st->pipe, mt); + st->pipe->texture_release(st->pipe, &pt); } diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 80c92e8b7a1..43681b7f8a9 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -286,7 +286,7 @@ st_render_texture(GLcontext *ctx, struct st_renderbuffer *strb; struct gl_renderbuffer *rb; struct pipe_context *pipe = st->pipe; - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; assert(!att->Renderbuffer); @@ -302,26 +302,26 @@ st_render_texture(GLcontext *ctx, rb->AllocStorage = NULL; /* should not get called */ strb = st_renderbuffer(rb); - /* get the mipmap tree for the texture */ - mt = st_get_texobj_mipmap_tree(att->Texture); - assert(mt); - assert(mt->level[att->TextureLevel].width); + /* get the texture for the texture object */ + pt = st_get_texobj_texture(att->Texture); + assert(pt); + assert(pt->width[att->TextureLevel]); - rb->Width = mt->level[att->TextureLevel].width; - rb->Height = mt->level[att->TextureLevel].height; + rb->Width = pt->width[att->TextureLevel]; + rb->Height = pt->height[att->TextureLevel]; - /* the renderbuffer's surface is inside the mipmap_tree: */ - strb->surface = pipe->get_tex_surface(pipe, mt, + /* the renderbuffer's surface is inside the texture */ + strb->surface = pipe->get_tex_surface(pipe, pt, att->CubeMapFace, att->TextureLevel, att->Zoffset); assert(strb->surface); - init_renderbuffer_bits(strb, mt->format); + init_renderbuffer_bits(strb, pt->format); /* - printf("RENDER TO TEXTURE obj=%p mt=%p surf=%p %d x %d\n", - att->Texture, mt, strb->surface, rb->Width, rb->Height); + printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p %d x %d\n", + att->Texture, pt, strb->surface, rb->Width, rb->Height); */ /* Invalidate buffer state so that the pipe's framebuffer state diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 461705119fa..f45d7e4275b 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -40,7 +40,7 @@ #include "state_tracker/st_cb_fbo.h" #include "state_tracker/st_cb_texture.h" #include "state_tracker/st_format.h" -#include "state_tracker/st_mipmap_tree.h" +#include "state_tracker/st_texture.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -54,8 +54,7 @@ struct st_texture_object { struct gl_texture_object base; /* The "parent" object */ - /* The mipmap tree must include at least these levels once - * validated: + /* The texture must include at least these levels once validated: */ GLuint firstLevel; GLuint lastLevel; @@ -67,7 +66,7 @@ struct st_texture_object /* On validation any active images held in main memory or in other * regions will be copied to this region and the old storage freed. */ - struct pipe_mipmap_tree *mt; + struct pipe_texture *pt; GLboolean imageOverride; GLint depthOverride; @@ -76,24 +75,6 @@ struct st_texture_object -struct st_texture_image -{ - struct gl_texture_image base; - - /* These aren't stored in gl_texture_image - */ - GLuint level; - GLuint face; - - /* If stImage->mt != NULL, image data is stored here. - * Else if stImage->base.Data != NULL, image is stored there. - * Else there is no image data. - */ - struct pipe_mipmap_tree *mt; -}; - - - static INLINE struct st_texture_object * st_texture_object(struct gl_texture_object *obj) @@ -108,11 +89,11 @@ st_texture_image(struct gl_texture_image *img) } -struct pipe_mipmap_tree * -st_get_texobj_mipmap_tree(struct gl_texture_object *texObj) +struct pipe_texture * +st_get_texobj_texture(struct gl_texture_object *texObj) { struct st_texture_object *stObj = st_texture_object(texObj); - return stObj->mt; + return stObj->pt; } @@ -174,9 +155,9 @@ st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) struct st_texture_object *stObj = st_texture_object(texObj); return - stObj->mt && - stObj->mt->region && - intel_is_region_resident(intel, stObj->mt->region); + stObj->pt && + stObj->pt->region && + intel_is_region_resident(intel, stObj->pt->region); #endif return 1; } @@ -207,11 +188,10 @@ static void st_DeleteTextureObject(GLcontext *ctx, struct gl_texture_object *texObj) { - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_object *stObj = st_texture_object(texObj); - if (stObj->mt) - st_miptree_release(pipe, &stObj->mt); + if (stObj->pt) + ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); _mesa_delete_texture_object(ctx, texObj); } @@ -220,13 +200,12 @@ st_DeleteTextureObject(GLcontext *ctx, static void st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) { - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_image *stImage = st_texture_image(texImage); DBG("%s\n", __FUNCTION__); - if (stImage->mt) { - st_miptree_release(pipe, &stImage->mt); + if (stImage->pt) { + ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); } if (texImage->Data) { @@ -287,10 +266,10 @@ do_memcpy(void *dest, const void *src, size_t n) } -/* Functions to store texture images. Where possible, mipmap_tree's +/* Functions to store texture images. Where possible, textures * will be created or further instantiated with image data, otherwise * images will be stored in malloc'd memory. A validation step is - * required to pull those images into a mipmap tree, or otherwise + * required to pull those images into a texture, or otherwise * decide a fallback is required. */ @@ -313,17 +292,16 @@ logbase2(int n) /* Otherwise, store it in memory if (Border != 0) or (any dimension == * 1). * - * Otherwise, if max_level >= level >= min_level, create tree with - * space for textures from min_level down to max_level. + * Otherwise, if max_level >= level >= min_level, create texture with + * space for images from min_level down to max_level. * - * Otherwise, create tree with space for textures from (level - * 0)..(1x1). Consider pruning this tree at a validation if the - * saving is worth it. + * Otherwise, create texture with space for images from (level 0)..(1x1). + * Consider pruning this texture at a validation if the saving is worth it. */ static void -guess_and_alloc_mipmap_tree(struct pipe_context *pipe, - struct st_texture_object *stObj, - struct st_texture_image *stImage) +guess_and_alloc_texture(struct st_context *st, + struct st_texture_object *stObj, + struct st_texture_image *stImage) { GLuint firstLevel; GLuint lastLevel; @@ -382,23 +360,20 @@ guess_and_alloc_mipmap_tree(struct pipe_context *pipe, lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); } - assert(!stObj->mt); + assert(!stObj->pt); if (stImage->base.IsCompressed) comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); - stObj->mt = st_miptree_create(pipe, + stObj->pt = st_texture_create(st, gl_target_to_pipe(stObj->base.Target), - stImage->base.InternalFormat, + st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat), + stImage->base.InternalFormat, firstLevel, lastLevel, width, height, depth, - stImage->base.TexFormat->TexelBytes, comp_byte); - stObj->mt->format - = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat); - DBG("%s - success\n", __FUNCTION__); } @@ -482,11 +457,11 @@ try_pbo_upload(GLcontext *ctx, else src_stride = width; - dst_offset = st_miptree_image_offset(stImage->mt, + dst_offset = st_texture_image_offset(stImage->pt, stImage->face, stImage->level); - dst_stride = stImage->mt->pitch; + dst_stride = stImage->pt->pitch; { struct _DriBufferObject *src_buffer = @@ -495,11 +470,11 @@ try_pbo_upload(GLcontext *ctx, /* Temporary hack: cast to _DriBufferObject: */ struct _DriBufferObject *dst_buffer = - (struct _DriBufferObject *)stImage->mt->region->buffer; + (struct _DriBufferObject *)stImage->pt->region->buffer; intelEmitCopyBlit(intel, - stImage->mt->cpp, + stImage->pt->cpp, src_stride, src_buffer, src_offset, dst_stride, dst_buffer, dst_offset, 0, 0, 0, 0, width, height, @@ -540,7 +515,6 @@ st_TexImage(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage, GLsizei imageSize, int compressed) { - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); GLint postConvWidth = width; @@ -589,58 +563,58 @@ st_TexImage(GLcontext * ctx, /* Release the reference to a potentially orphaned buffer. * Release any old malloced memory. */ - if (stImage->mt) { - st_miptree_release(pipe, &stImage->mt); + if (stImage->pt) { + ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); assert(!texImage->Data); } else if (texImage->Data) { _mesa_align_free(texImage->Data); } - /* If this is the only texture image in the tree, could call + /* If this is the only texture image in the texture, could call * bmBufferData with NULL data to free the old block and avoid * waiting on any outstanding fences. */ - if (stObj->mt && - stObj->mt->first_level == level && - stObj->mt->last_level == level && - stObj->mt->target != PIPE_TEXTURE_CUBE && - !st_miptree_match_image(stObj->mt, &stImage->base, + if (stObj->pt && + stObj->pt->first_level == level && + stObj->pt->last_level == level && + stObj->pt->target != PIPE_TEXTURE_CUBE && + !st_texture_match_image(stObj->pt, &stImage->base, stImage->face, stImage->level)) { DBG("release it\n"); - st_miptree_release(pipe, &stObj->mt); - assert(!stObj->mt); + ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); + assert(!stObj->pt); } - if (!stObj->mt) { - guess_and_alloc_mipmap_tree(pipe, stObj, stImage); - if (!stObj->mt) { - DBG("guess_and_alloc_mipmap_tree: failed\n"); + if (!stObj->pt) { + guess_and_alloc_texture(ctx->st, stObj, stImage); + if (!stObj->pt) { + DBG("guess_and_alloc_texture: failed\n"); } } - assert(!stImage->mt); + assert(!stImage->pt); - if (stObj->mt && - st_miptree_match_image(stObj->mt, &stImage->base, + if (stObj->pt && + st_texture_match_image(stObj->pt, &stImage->base, stImage->face, stImage->level)) { - st_miptree_reference(&stImage->mt, stObj->mt); - assert(stImage->mt); + pipe_texture_reference(ctx->st->pipe, &stImage->pt, stObj->pt); + assert(stImage->pt); } - if (!stImage->mt) - DBG("XXX: Image did not fit into tree - storing in local memory!\n"); + if (!stImage->pt) + DBG("XXX: Image did not fit into texture - storing in local memory!\n"); #if 0 /* XXX FIX when st_buffer_objects are in place */ /* PBO fastpaths: */ if (dims <= 2 && - stImage->mt && + stImage->pt && intel_buffer_object(unpack->BufferObj) && check_pbo_format(internalFormat, format, - type, stImage->base.TexFormat)) { + type, texImage->TexFormat)) { DBG("trying pbo upload\n"); @@ -650,9 +624,9 @@ st_TexImage(GLcontext * ctx, * performance (in particular when pipe_region_cow() is * required). */ - if (stObj->mt == stImage->mt && - stObj->mt->first_level == level && - stObj->mt->last_level == level) { + if (stObj->pt == stImage->pt && + stObj->pt->first_level == level && + stObj->pt->last_level == level) { if (try_pbo_zcopy(intel, stImage, unpack, internalFormat, @@ -683,7 +657,7 @@ st_TexImage(GLcontext * ctx, /* intelCopyTexImage calls this function with pixels == NULL, with - * the expectation that the mipmap tree will be set up but nothing + * the expectation that the texture will be set up but nothing * more will be done. This is where those calls return: */ if (compressed) { @@ -698,13 +672,9 @@ st_TexImage(GLcontext * ctx, if (!pixels) return; - if (stImage->mt) { - texImage->Data = st_miptree_image_map(pipe, - stImage->mt, - stImage->face, - stImage->level, - &dstRowStride, - stImage->base.ImageOffsets); + if (stImage->pt) { + texImage->Data = st_texture_image_map(ctx->st, stImage, 0); + dstRowStride = stImage->surface->pitch * stImage->surface->cpp; } else { /* Allocate regular memory and store the image there temporarily. */ @@ -732,22 +702,36 @@ st_TexImage(GLcontext * ctx, if (compressed) { memcpy(texImage->Data, pixels, imageSize); } - else if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, unpack)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + else { + GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, + format, type); + int i; + + for (i = 0; i++ < depth;) { + if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, 1, + format, type, pixels, unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + if (stImage->pt && i < depth) { + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, i); + pixels += srcImageStride; + } + } } _mesa_unmap_teximage_pbo(ctx, unpack); - if (stImage->mt) { - st_miptree_image_unmap(pipe, stImage->mt); + if (stImage->pt) { + st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } @@ -839,49 +823,58 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, /* struct intel_context *intel = intel_context(ctx); */ - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_image *stImage = st_texture_image(texImage); + GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, + texImage->Height, format, + type); + GLuint depth; + int i; /* Map */ - if (stImage->mt) { + if (stImage->pt) { /* Image is stored in hardware format in a buffer managed by the * kernel. Need to explicitly map and unmap it. */ - stImage->base.Data = - st_miptree_image_map(pipe, - stImage->mt, - stImage->face, - stImage->level, - &stImage->base.RowStride, - stImage->base.ImageOffsets); - stImage->base.RowStride /= stImage->mt->cpp; + texImage->Data = st_texture_image_map(ctx->st, stImage, 0); + texImage->RowStride = stImage->surface->pitch; } else { /* Otherwise, the image should actually be stored in - * stImage->base.Data. This is pretty confusing for + * texImage->Data. This is pretty confusing for * everybody, I'd much prefer to separate the two functions of * texImage->Data - storage for texture images in main memory * and access (ie mappings) of images. In other words, we'd * create a new texImage->Map field and leave Data simply for * storage. */ - assert(stImage->base.Data); + assert(texImage->Data); } + depth = texImage->Depth; + texImage->Depth = 1; - if (compressed) { - _mesa_get_compressed_teximage(ctx, target, level, pixels, - texObj, texImage); - } else { - _mesa_get_teximage(ctx, target, level, format, type, pixels, - texObj, texImage); + for (i = 0; i++ < depth;) { + if (compressed) { + _mesa_get_compressed_teximage(ctx, target, level, pixels, + texObj, texImage); + } else { + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + + if (stImage->pt && i < depth) { + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, i); + pixels += dstImageStride; + } } - + + texImage->Depth = depth; /* Unmap */ - if (stImage->mt) { - st_miptree_image_unmap(pipe, stImage->mt); - stImage->base.Data = NULL; + if (stImage->pt) { + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = NULL; } } @@ -921,9 +914,11 @@ st_TexSubimage(GLcontext * ctx, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - struct pipe_context *pipe = ctx->st->pipe; struct st_texture_image *stImage = st_texture_image(texImage); GLuint dstRowStride; + GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, + format, type); + int i; DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), @@ -938,25 +933,28 @@ st_TexSubimage(GLcontext * ctx, /* Map buffer if necessary. Need to lock to prevent other contexts * from uploading the buffer under us. */ - if (stImage->mt) - texImage->Data = st_miptree_image_map(pipe, - stImage->mt, - stImage->face, - stImage->level, - &dstRowStride, - texImage->ImageOffsets); - - assert(dstRowStride); - - if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + if (stImage->pt) { + texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset); + dstRowStride = stImage->surface->pitch * stImage->surface->cpp; + } + + for (i = 0; i++ < depth;) { + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + xoffset, yoffset, 0, + dstRowStride, + texImage->ImageOffsets, + width, height, 1, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + } + + if (stImage->pt && i < depth) { + st_texture_image_unmap(ctx->st, stImage); + texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i); + pixels += srcImageStride; + } } #if 0 @@ -970,8 +968,8 @@ st_TexSubimage(GLcontext * ctx, _mesa_unmap_teximage_pbo(ctx, packing); - if (stImage->mt) { - st_miptree_image_unmap(pipe, stImage->mt); + if (stImage->pt) { + st_texture_image_unmap(ctx->st, stImage); texImage->Data = NULL; } } @@ -1074,7 +1072,7 @@ fallback_copy_texsubimage(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; const uint face = texture_face(target); - struct pipe_mipmap_tree *mt = stImage->mt; + struct pipe_texture *pt = stImage->pt; struct pipe_surface *src_surf, *dest_surf; GLfloat *data; GLint row, yStep; @@ -1090,7 +1088,7 @@ fallback_copy_texsubimage(GLcontext *ctx, src_surf = strb->surface; - dest_surf = pipe->get_tex_surface(pipe, mt, + dest_surf = pipe->get_tex_surface(pipe, pt, face, level, destZ); (void) pipe->region_map(pipe, dest_surf->region); @@ -1150,7 +1148,7 @@ do_copy_texsubimage(GLcontext *ctx, struct gl_framebuffer *fb = ctx->ReadBuffer; struct st_renderbuffer *strb; struct pipe_context *pipe = ctx->st->pipe; - struct pipe_region *src_region, *dest_region; + struct pipe_surface *dest_surface; uint dest_format, src_format; (void) texImage; @@ -1169,29 +1167,24 @@ do_copy_texsubimage(GLcontext *ctx, assert(strb); assert(strb->surface); - assert(stImage->mt); + assert(stImage->pt); if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { srcY = strb->Base.Height - srcY - height; } src_format = strb->surface->format; - dest_format = stImage->mt->format; + dest_format = stImage->pt->format; - src_region = strb->surface->region; - dest_region = stImage->mt->region; + dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face, + stImage->level, destZ); if (src_format == dest_format && ctx->_ImageTransferState == 0x0 && - src_region && - dest_region && - strb->surface->cpp == stImage->mt->cpp) { + strb->surface->region && + dest_surface->region && + strb->surface->cpp == stImage->pt->cpp) { /* do blit-style copy */ - struct pipe_surface *dest_surface = pipe->get_tex_surface(pipe, - stImage->mt, - stImage->face, - stImage->level, - destZ); /* XXX may need to invert image depending on window * vs. user-created FBO @@ -1203,12 +1196,12 @@ do_copy_texsubimage(GLcontext *ctx, * worth it: */ intelEmitCopyBlit(intel, - stImage->mt->cpp, + stImage->pt->cpp, -src->pitch, src->buffer, src->height * src->pitch * src->cpp, - stImage->mt->pitch, - stImage->mt->region->buffer, + stImage->pt->pitch, + stImage->pt->region->buffer, dest_offset, x, y + height, dstx, dsty, width, height, GL_COPY); /* ? */ @@ -1224,8 +1217,6 @@ do_copy_texsubimage(GLcontext *ctx, /* size */ width, height); #endif - - pipe_surface_reference(&dest_surface, NULL); } else { fallback_copy_texsubimage(ctx, target, level, @@ -1234,6 +1225,7 @@ do_copy_texsubimage(GLcontext *ctx, srcX, srcY, width, height); } + pipe_surface_reference(&dest_surface, NULL); #if 0 /* GL_SGIS_generate_mipmap -- this can be accelerated now. @@ -1267,7 +1259,7 @@ st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, goto fail; #endif - /* Setup or redefine the texture object, mipmap tree and texture + /* Setup or redefine the texture object, texture and texture * image. Don't populate yet. */ ctx->Driver.TexImage1D(ctx, target, level, internalFormat, @@ -1299,7 +1291,7 @@ st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, goto fail; #endif - /* Setup or redefine the texture object, mipmap tree and texture + /* Setup or redefine the texture object, texture and texture * image. Don't populate yet. */ ctx->Driver.TexImage2D(ctx, target, level, internalFormat, @@ -1407,28 +1399,28 @@ calculate_first_last_level(struct st_texture_object *stObj) static void -copy_image_data_to_tree(struct pipe_context *pipe, - struct st_texture_object *stObj, - struct st_texture_image *stImage) +copy_image_data_to_texture(struct st_context *st, + struct st_texture_object *stObj, + struct st_texture_image *stImage) { - if (stImage->mt) { + if (stImage->pt) { /* Copy potentially with the blitter: */ - st_miptree_image_copy(pipe, - stObj->mt, /* dest miptree */ + st_texture_image_copy(st->pipe, + stObj->pt, /* dest texture */ stImage->face, stImage->level, - stImage->mt /* src miptree */ + stImage->pt /* src texture */ ); - st_miptree_release(pipe, &stImage->mt); + st->pipe->texture_release(st->pipe, &stImage->pt); } else { assert(stImage->base.Data != NULL); /* More straightforward upload. */ - st_miptree_image_data(pipe, - stObj->mt, + st_texture_image_data(st->pipe, + stObj->pt, stImage->face, stImage->level, stImage->base.Data, @@ -1439,16 +1431,16 @@ copy_image_data_to_tree(struct pipe_context *pipe, stImage->base.Data = NULL; } - st_miptree_reference(&stImage->mt, stObj->mt); + pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt); } /* */ GLboolean -st_finalize_mipmap_tree(GLcontext *ctx, - struct pipe_context *pipe, GLuint unit, - GLboolean *needFlush) +st_finalize_texture(GLcontext *ctx, + struct pipe_context *pipe, GLuint unit, + GLboolean *needFlush) { struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; struct st_texture_object *stObj = st_texture_object(tObj); @@ -1465,7 +1457,7 @@ st_finalize_mipmap_tree(GLcontext *ctx, */ assert(stObj->base._Complete); - /* What levels must the tree include at a minimum? + /* What levels must the texture include at a minimum? */ calculate_first_last_level(stObj); firstImage = @@ -1474,27 +1466,27 @@ st_finalize_mipmap_tree(GLcontext *ctx, /* Fallback case: */ if (firstImage->base.Border) { - if (stObj->mt) { - st_miptree_release(pipe, &stObj->mt); + if (stObj->pt) { + ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); } return GL_FALSE; } - /* If both firstImage and stObj have a tree which can contain + /* If both firstImage and stObj point to a texture which can contain * all active images, favour firstImage. Note that because of the * completeness requirement, we know that the image dimensions * will match. */ - if (firstImage->mt && - firstImage->mt != stObj->mt && - firstImage->mt->first_level <= stObj->firstLevel && - firstImage->mt->last_level >= stObj->lastLevel) { + if (firstImage->pt && + firstImage->pt != stObj->pt && + firstImage->pt->first_level <= stObj->firstLevel && + firstImage->pt->last_level >= stObj->lastLevel) { - if (stObj->mt) - st_miptree_release(pipe, &stObj->mt); + if (stObj->pt) + ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); - st_miptree_reference(&stObj->mt, firstImage->mt); + pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt); } if (firstImage->base.IsCompressed) { @@ -1505,48 +1497,45 @@ st_finalize_mipmap_tree(GLcontext *ctx, cpp = firstImage->base.TexFormat->TexelBytes; } - /* Check tree can hold all active levels. Check tree matches + /* 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 tree isn't valid except at the + * 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 tree alone. + * leaving the texture alone. */ - if (stObj->mt && - (stObj->mt->target != gl_target_to_pipe(stObj->base.Target) || - stObj->mt->internal_format != firstImage->base.InternalFormat || - stObj->mt->first_level != stObj->firstLevel || - stObj->mt->last_level != stObj->lastLevel || - stObj->mt->width0 != firstImage->base.Width || - stObj->mt->height0 != firstImage->base.Height || - stObj->mt->depth0 != firstImage->base.Depth || - stObj->mt->cpp != cpp || - stObj->mt->compressed != firstImage->base.IsCompressed)) { - st_miptree_release(pipe, &stObj->mt); + if (stObj->pt && + (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || + stObj->pt->internal_format != firstImage->base.InternalFormat || + 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 || + stObj->pt->depth[0] != firstImage->base.Depth || + stObj->pt->cpp != cpp || + stObj->pt->compressed != firstImage->base.IsCompressed)) { + ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); } - /* May need to create a new tree: + /* May need to create a new texture: */ - if (!stObj->mt) { - stObj->mt = st_miptree_create(pipe, + if (!stObj->pt) { + stObj->pt = st_texture_create(ctx->st, gl_target_to_pipe(stObj->base.Target), - firstImage->base.InternalFormat, + st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), + firstImage->base.InternalFormat, stObj->firstLevel, stObj->lastLevel, firstImage->base.Width, firstImage->base.Height, firstImage->base.Depth, - cpp, comp_byte); - - stObj->mt->format - = st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat); } - /* Pull in any images not in the object's tree: + /* Pull in any images not in the object's texture: */ nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; for (face = 0; face < nr_faces; face++) { @@ -1554,10 +1543,10 @@ st_finalize_mipmap_tree(GLcontext *ctx, struct st_texture_image *stImage = st_texture_image(stObj->base.Image[face][i]); - /* Need to import images in main memory or held in other trees. + /* Need to import images in main memory or held in other textures. */ - if (stObj->mt != stImage->mt) { - copy_image_data_to_tree(pipe, stObj, stImage); + if (stObj->pt != stImage->pt) { + copy_image_data_to_texture(ctx->st, stObj, stImage); *needFlush = GL_TRUE; } } diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index 7a1867dc58a..7f8082b029d 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -2,14 +2,14 @@ #define ST_CB_TEXTURE_H -extern struct pipe_mipmap_tree * -st_get_texobj_mipmap_tree(struct gl_texture_object *texObj); +extern struct pipe_texture * +st_get_texobj_texture(struct gl_texture_object *texObj); extern GLboolean -st_finalize_mipmap_tree(GLcontext *ctx, - struct pipe_context *pipe, GLuint unit, - GLboolean *needFlush); +st_finalize_texture(GLcontext *ctx, + struct pipe_context *pipe, GLuint unit, + GLboolean *needFlush); extern void diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index a6045230a0f..db97014c5a7 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -36,7 +36,6 @@ struct st_context; struct st_region; struct st_texture_object; -struct st_texture_image; struct st_fragment_program; struct draw_context; struct draw_stage; @@ -61,6 +60,25 @@ struct st_tracked_state { +struct st_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If stImage->pt != NULL, image data is stored here. + * Else if stImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct pipe_texture *pt; + + struct pipe_surface *surface; +}; + + struct st_context { @@ -91,7 +109,7 @@ struct st_context struct pipe_constant_buffer constants[2]; struct pipe_feedback_state feedback; struct pipe_framebuffer_state framebuffer; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; diff --git a/src/mesa/state_tracker/st_mipmap_tree.c b/src/mesa/state_tracker/st_texture.c index 6ccf33105f1..a5582c31c0b 100644 --- a/src/mesa/state_tracker/st_mipmap_tree.c +++ b/src/mesa/state_tracker/st_texture.c @@ -25,7 +25,9 @@ * **************************************************************************/ -#include "st_mipmap_tree.h" +#include "st_context.h" +#include "st_format.h" +#include "st_texture.h" #include "enums.h" #include "pipe/p_state.h" @@ -56,19 +58,19 @@ target_to_target(GLenum target) } #endif -struct pipe_mipmap_tree * -st_miptree_create(struct pipe_context *pipe, +struct pipe_texture * +st_texture_create(struct st_context *st, unsigned target, - GLenum internal_format, - GLuint first_level, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, GLuint cpp, GLuint compress_byte) + unsigned format, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint compress_byte) { - GLboolean ok; - struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1); - GLbitfield flags = 0x0; + struct pipe_texture *pt = CALLOC_STRUCT(pipe_texture); assert(target <= PIPE_TEXTURE_CUBE); @@ -76,102 +78,64 @@ st_miptree_create(struct pipe_context *pipe, _mesa_lookup_enum_by_nr(target), _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); - mt->target = target; - mt->internal_format = internal_format; - mt->first_level = first_level; - mt->last_level = last_level; - mt->width0 = width0; - mt->height0 = height0; - mt->depth0 = depth0; - mt->cpp = compress_byte ? compress_byte : cpp; - mt->compressed = compress_byte ? 1 : 0; - mt->refcount = 1; - - ok = pipe->mipmap_tree_layout(pipe, mt); - if (ok) { - mt->region = pipe->winsys->region_alloc(pipe->winsys, - mt->pitch * mt->cpp * - mt->total_height, flags); - } - - if (!mt->region) { - free(mt); + if (!pt) return NULL; - } - - return mt; -} - - -void -st_miptree_reference(struct pipe_mipmap_tree **dst, - struct pipe_mipmap_tree *src) -{ - src->refcount++; - *dst = src; - DBG("%s %p refcount now %d\n", __FUNCTION__, (void *) src, src->refcount); -} - -void -st_miptree_release(struct pipe_context *pipe, - struct pipe_mipmap_tree **mt) -{ - if (!*mt) - return; - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *mt, (*mt)->refcount - 1); - if (--(*mt)->refcount <= 0) { - GLuint i; + assert(format); - DBG("%s deleting %p\n", __FUNCTION__, (void *) *mt); + pt->target = target; + pt->format = format; + pt->internal_format = internal_format; + pt->first_level = first_level; + pt->last_level = last_level; + pt->width[0] = width0; + pt->height[0] = height0; + pt->depth[0] = depth0; + pt->compressed = compress_byte ? 1 : 0; + pt->cpp = pt->compressed ? compress_byte : st_sizeof_format(format); + pt->refcount = 1; - pipe->winsys->region_release(pipe->winsys, &((*mt)->region)); + st->pipe->texture_create(st->pipe, &pt); - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) - if ((*mt)->level[i].image_offset) - free((*mt)->level[i].image_offset); - - free(*mt); - } - *mt = NULL; + return pt; } -/* Can the image be pulled into a unified mipmap tree. This mirrors +/* Can the image be pulled into a unified mipmap texture. This mirrors * the completeness test in a lot of ways. * * Not sure whether I want to pass gl_texture_image here. */ GLboolean -st_miptree_match_image(struct pipe_mipmap_tree *mt, +st_texture_match_image(struct pipe_texture *pt, struct gl_texture_image *image, GLuint face, GLuint level) { - /* Images with borders are never pulled into mipmap trees. + /* Images with borders are never pulled into mipmap textures. */ if (image->Border) return GL_FALSE; - if (image->InternalFormat != mt->internal_format || - image->IsCompressed != mt->compressed) + if (image->InternalFormat != pt->internal_format || + image->IsCompressed != pt->compressed) return GL_FALSE; /* Test image dimensions against the base level image adjusted for * minification. This will also catch images not present in the - * tree, changed targets, etc. + * texture, changed targets, etc. */ - if (image->Width != mt->level[level].width || - image->Height != mt->level[level].height || - image->Depth != mt->level[level].depth) + if (image->Width != pt->width[level] || + image->Height != pt->height[level] || + image->Depth != pt->depth[level]) return GL_FALSE; return GL_TRUE; } +#if 000 /* Although we use the image_offset[] array to store relative offsets * to cube faces, Mesa doesn't know anything about this and expects * each cube face to be treated as a separate image. @@ -179,14 +143,14 @@ st_miptree_match_image(struct pipe_mipmap_tree *mt, * These functions present that view to mesa: */ const GLuint * -st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level) +st_texture_depth_offsets(struct pipe_texture *pt, GLuint level) { static const GLuint zero = 0; - if (mt->target != PIPE_TEXTURE_3D || mt->level[level].nr_images == 1) + if (pt->target != PIPE_TEXTURE_3D || pt->level[level].nr_images == 1) return &zero; else - return mt->level[level].image_offset; + return pt->level[level].image_offset; } @@ -195,63 +159,47 @@ st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level) * texture memory buffer, in bytes. */ GLuint -st_miptree_image_offset(const struct pipe_mipmap_tree * mt, +st_texture_image_offset(const struct pipe_texture * pt, GLuint face, GLuint level) { - if (mt->target == PIPE_TEXTURE_CUBE) - return (mt->level[level].level_offset + - mt->level[level].image_offset[face] * mt->cpp); + if (pt->target == PIPE_TEXTURE_CUBE) + return (pt->level[level].level_offset + + pt->level[level].image_offset[face] * pt->cpp); else - return mt->level[level].level_offset; + return pt->level[level].level_offset; } - - -GLuint -st_miptree_texel_offset(const struct pipe_mipmap_tree * mt, - GLuint face, GLuint level, - GLuint col, GLuint row, GLuint img) -{ - GLuint imgOffset = st_miptree_image_offset(mt, face, level); - - return imgOffset + row * (mt->pitch + col) * mt->cpp; -} - +#endif /** - * Map a teximage in a mipmap tree. + * Map a teximage in a mipmap texture. * \param row_stride returns row stride in bytes * \param image_stride returns image stride in bytes (for 3D textures). * \return address of mapping */ GLubyte * -st_miptree_image_map(struct pipe_context *pipe, - struct pipe_mipmap_tree * mt, - GLuint face, - GLuint level, - GLuint * row_stride, GLuint * image_offsets) +st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, + GLuint zoffset) { - GLubyte *ptr; + struct pipe_texture *pt = stImage->pt; DBG("%s \n", __FUNCTION__); - if (row_stride) - *row_stride = mt->pitch * mt->cpp; + stImage->surface = st->pipe->get_tex_surface(st->pipe, pt, stImage->face, + stImage->level, zoffset); - if (image_offsets) - memcpy(image_offsets, mt->level[level].image_offset, - mt->level[level].depth * sizeof(GLuint)); + (void) st->pipe->region_map(st->pipe, stImage->surface->region); - ptr = pipe->region_map(pipe, mt->region); - - return ptr + st_miptree_image_offset(mt, face, level); + return stImage->surface->region->map + stImage->surface->offset; } void -st_miptree_image_unmap(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt) +st_texture_image_unmap(struct st_context *st, struct st_texture_image *stImage) { DBG("%s\n", __FUNCTION__); - pipe->region_unmap(pipe, mt->region); + + st->pipe->region_unmap(st->pipe, stImage->surface->region); + + pipe_surface_reference(&stImage->surface, NULL); } @@ -259,14 +207,14 @@ st_miptree_image_unmap(struct pipe_context *pipe, /* Upload data for a particular image. */ void -st_miptree_image_data(struct pipe_context *pipe, - struct pipe_mipmap_tree *dst, +st_texture_image_data(struct pipe_context *pipe, + struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_pitch, GLuint src_image_pitch) { - GLuint depth = dst->level[level].depth; + GLuint depth = dst->depth[level]; GLuint i; GLuint height = 0; const GLubyte *srcUB = src; @@ -274,7 +222,7 @@ st_miptree_image_data(struct pipe_context *pipe, DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { - height = dst->level[level].height; + height = dst->height[level]; if(dst->compressed) height /= 4; @@ -285,7 +233,7 @@ st_miptree_image_data(struct pipe_context *pipe, srcUB, src_row_pitch, 0, 0, /* source x, y */ - dst->level[level].width, height); /* width, height */ + dst->width[level], height); /* width, height */ pipe_surface_reference(&dst_surface, NULL); @@ -293,17 +241,17 @@ st_miptree_image_data(struct pipe_context *pipe, } } -/* Copy mipmap image between trees +/* Copy mipmap image between textures */ void -st_miptree_image_copy(struct pipe_context *pipe, - struct pipe_mipmap_tree *dst, +st_texture_image_copy(struct pipe_context *pipe, + struct pipe_texture *dst, GLuint face, GLuint level, - struct pipe_mipmap_tree *src) + struct pipe_texture *src) { - GLuint width = src->level[level].width; - GLuint height = src->level[level].height; - GLuint depth = src->level[level].depth; + GLuint width = src->width[level]; + GLuint height = src->height[level]; + GLuint depth = src->depth[level]; struct pipe_surface *src_surface; struct pipe_surface *dst_surface; GLuint i; diff --git a/src/mesa/state_tracker/st_mipmap_tree.h b/src/mesa/state_tracker/st_texture.h index 3e7fd7fa0ce..b25e3f3f3bd 100644 --- a/src/mesa/state_tracker/st_mipmap_tree.h +++ b/src/mesa/state_tracker/st_texture.h @@ -25,94 +25,85 @@ * **************************************************************************/ -#ifndef ST_MIPMAP_TREE_H -#define ST_MIPMAP_TREE_H +#ifndef ST_TEXTURE_H +#define ST_TEXTURE_H #include "main/mtypes.h" struct pipe_context; -struct pipe_mipmap_tree; +struct pipe_texture; struct pipe_region; -extern struct pipe_mipmap_tree * -st_miptree_create(struct pipe_context *pipe, - GLenum target, +extern struct pipe_texture * +st_texture_create(struct st_context *st, + unsigned target, + unsigned format, GLenum internal_format, GLuint first_level, GLuint last_level, GLuint width0, GLuint height0, GLuint depth0, - GLuint cpp, GLuint compress_byte); -extern void -st_miptree_reference(struct pipe_mipmap_tree **dst, - struct pipe_mipmap_tree *src); - -extern void -st_miptree_release(struct pipe_context *pipe, struct pipe_mipmap_tree **mt); - -/* Check if an image fits an existing mipmap tree layout +/* Check if an image fits an existing texture */ extern GLboolean -st_miptree_match_image(struct pipe_mipmap_tree *mt, +st_texture_match_image(struct pipe_texture *pt, struct gl_texture_image *image, GLuint face, GLuint level); -/* Return a pointer to an image within a tree. Return image stride as +/* Return a pointer to an image within a texture. Return image stride as * well. */ extern GLubyte * -st_miptree_image_map(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, - GLuint face, GLuint level, - GLuint * row_stride, GLuint * image_stride); +st_texture_image_map(struct st_context *st, + struct st_texture_image *stImage, + GLuint zoffset); extern void -st_miptree_image_unmap(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt); +st_texture_image_unmap(struct st_context *st, + struct st_texture_image *stImage); /* Return pointers to each 2d slice within an image. Indexed by depth * value. */ extern const GLuint * -st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level); +st_texture_depth_offsets(struct pipe_texture *pt, GLuint level); -/* Return the linear offset of an image relative to the start of the - * tree: +/* Return the linear offset of an image relative to the start of its region: */ extern GLuint -st_miptree_image_offset(const struct pipe_mipmap_tree *mt, +st_texture_image_offset(const struct pipe_texture *pt, GLuint face, GLuint level); extern GLuint -st_miptree_texel_offset(const struct pipe_mipmap_tree * mt, +st_texture_texel_offset(const struct pipe_texture * pt, GLuint face, GLuint level, GLuint col, GLuint row, GLuint img); -/* Upload an image into a tree +/* Upload an image into a texture */ extern void -st_miptree_image_data(struct pipe_context *pipe, - struct pipe_mipmap_tree *dst, +st_texture_image_data(struct pipe_context *pipe, + struct pipe_texture *dst, GLuint face, GLuint level, void *src, GLuint src_row_pitch, GLuint src_image_pitch); -/* Copy an image between two trees +/* Copy an image between two textures */ extern void -st_miptree_image_copy(struct pipe_context *pipe, - struct pipe_mipmap_tree *dst, +st_texture_image_copy(struct pipe_context *pipe, + struct pipe_texture *dst, GLuint face, GLuint level, - struct pipe_mipmap_tree *src); + struct pipe_texture *src); #endif |