pipe->get_tex_surface() has to be used for access to texture image data.
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;
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;
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];
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);
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
#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"
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;
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;
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];
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;
}
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:
*/
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.
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 ||
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 */
);
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);
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]);
*/
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;
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Michel Dänzer <michel@tungstengraphics.com>
- */
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-
-#include "i915_tex_layout.h"
-#include "i915_debug.h"
-
-
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
-static int align(int value, int alignment)
-{
- return (value + alignment - 1) & ~(alignment - 1);
-}
-
-
-static void
-i915_miptree_set_level_info(struct pipe_mipmap_tree *mt,
- unsigned level,
- unsigned nr_images,
- unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
-{
- 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;
-
- /*
- 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);
- */
-
- /* 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;
- }
-
- assert(nr_images);
- assert(!mt->level[level].image_offset);
-
- mt->level[level].image_offset = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
- mt->level[level].image_offset[0] = 0;
-}
-
-
-static void
-i915_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
- 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);
-
- mt->level[level].image_offset[img] = (x + y * mt->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]);
- */
-}
-
-
-static void
-i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
-{
- int align_h = 2, align_w = 4;
- unsigned level;
- unsigned x = 0;
- unsigned y = 0;
- unsigned width = mt->width0;
- unsigned height = mt->height0;
-
- mt->pitch = mt->width0;
-
- /* 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 (mip1_width > mt->width0)
- mt->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;
-
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
- unsigned img_height;
-
- i915_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
-
- if (mt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = align(height, align_h);
-
-
- /* 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);
-
- /* Layout_below: step right after second mipmap.
- */
- if (level == mt->first_level + 1) {
- x += align(width, align_w);
- }
- else {
- y += img_height;
- }
-
- width = minify(width);
- height = minify(height);
- }
-}
-
-
-static const int initial_offsets[6][2] = {
- {0, 0},
- {0, 2},
- {1, 0},
- {1, 2},
- {1, 1},
- {1, 3}
-};
-
-static const int step_offsets[6][2] = {
- {0, 2},
- {0, 2},
- {-1, 2},
- {-1, 2},
- {-1, 1},
- {-1, 1}
-};
-
-
-boolean
-i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
- unsigned level;
-
- switch (mt->target) {
- case PIPE_TEXTURE_CUBE: {
- const unsigned dim = mt->width0;
- unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
- 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;
-
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_level_info(mt, level, 6,
- 0, 0,
- /*OLD: mt->pitch, mt->total_height,*/
- lvlWidth, lvlHeight,
- 1);
- lvlWidth /= 2;
- lvlHeight /= 2;
- }
-
- for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- 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);
- d >>= 1;
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- }
- }
- break;
- }
- case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
- unsigned stack_height = 0;
-
- /* Calculate the size of a single slice.
- */
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
-
- /* XXX: hardware expects/requires 9 levels at minimum.
- */
- for (level = mt->first_level; level <= MAX2(8, mt->last_level);
- level++) {
- i915_miptree_set_level_info(mt, level, depth, 0, mt->total_height,
- width, height, depth);
-
-
- stack_height += MAX2(2, height);
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- }
-
- /* Fixup depth image_offsets:
- */
- depth = mt->depth0;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- unsigned i;
- for (i = 0; i < depth; i++)
- i915_miptree_set_image_offset(mt, level, i,
- 0, i * stack_height);
-
- depth = minify(depth);
- }
-
-
- /* Multiply slice size by texture depth for total size. It's
- * remarkable how wasteful of memory the i915 texture layouts
- * are. They are largely fixed in the i945.
- */
- mt->total_height = stack_height * mt->depth0;
- break;
- }
-
- default:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned img_height;
-
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->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,
- width, height, 1);
-
- if (mt->compressed)
- img_height = MAX2(1, height / 4);
- else
- img_height = (MAX2(2, height) + 1) & ~1;
-
- mt->total_height += img_height;
-
- width = minify(width);
- height = minify(height);
- }
- break;
- }
- }
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
- */
-
- return TRUE;
-}
-
-
-boolean
-i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
- unsigned level;
-
- switch (mt->target) {
- case PIPE_TEXTURE_CUBE:{
- const unsigned dim = mt->width0;
- unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
- assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
- /* Depending on the size of the largest images, pitch can be
- * determined either by the old-style packing of cubemap faces,
- * 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;
- else
- mt->pitch = 14 * 8;
-
- mt->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,
- 0, 0,
- lvlWidth, lvlHeight, 1);
- lvlWidth /= 2;
- lvlHeight /= 2;
- }
-
-
- for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- unsigned y = initial_offsets[face][1] * dim;
- unsigned d = dim;
-
- if (dim == 4 && face >= 4) {
- y = mt->total_height - 4;
- x = (face - 4) * 8;
- }
- else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
- y = mt->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);
-
- d >>= 1;
-
- switch (d) {
- case 4:
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- case PIPE_TEX_FACE_NEG_X:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- case PIPE_TEX_FACE_POS_Y:
- case PIPE_TEX_FACE_NEG_Y:
- y += 12;
- x -= 8;
- break;
- case PIPE_TEX_FACE_POS_Z:
- case PIPE_TEX_FACE_NEG_Z:
- y = mt->total_height - 4;
- x = (face - 4) * 8;
- break;
- }
-
- case 2:
- y = mt->total_height - 4;
- x = 16 + face * 8;
- break;
-
- case 1:
- x += 48;
- break;
-
- default:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- }
- }
- }
- break;
- }
- case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
- 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;
-
- pack_y_pitch = MAX2(mt->height0, 2);
- pack_x_pitch = mt->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;
- int x = 0;
- int y = 0;
- unsigned q, j;
-
- i915_miptree_set_level_info(mt, level, nr_images,
- 0, mt->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);
- x += pack_x_pitch;
- }
-
- x = 0;
- y += pack_y_pitch;
- }
-
-
- mt->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);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- }
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- }
- break;
- }
-
- case PIPE_TEXTURE_1D:
- case PIPE_TEXTURE_2D:
-// case PIPE_TEXTURE_RECTANGLE:
- i945_miptree_layout_2d(mt);
- break;
- default:
- assert(0);
- return FALSE;
- }
-
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
- */
-
- return TRUE;
-}
-
+++ /dev/null
-
-#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 */
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+
+#include "i915_context.h"
+#include "i915_texture.h"
+#include "i915_debug.h"
+
+
+static unsigned minify( unsigned d )
+{
+ return MAX2(1, d>>1);
+}
+
+static int align(int value, int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+
+static void
+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);
+
+ 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, tex->level_offset[level]);
+ */
+
+ /* Not sure when this would happen, but anyway:
+ */
+ if (tex->image_offset[level]) {
+ FREE(tex->image_offset[level]);
+ tex->image_offset[level] = NULL;
+ }
+
+ assert(nr_images);
+ assert(!tex->image_offset[level]);
+
+ tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
+ tex->image_offset[level][0] = 0;
+}
+
+
+static void
+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 < tex->nr_images[level]);
+
+ 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, tex->image_offset[level][img]);
+ */
+}
+
+
+static void
+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 = pt->width[0];
+ unsigned height = pt->height[0];
+
+ 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 (pt->first_level != pt->last_level) {
+ unsigned mip1_width = align(minify(pt->width[0]), align_w)
+ + minify(minify(pt->width[0]));
+
+ 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.
+ */
+ tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
+ tex->total_height = 0;
+
+ for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
+ unsigned img_height;
+
+ i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1);
+
+ if (pt->compressed)
+ img_height = MAX2(1, height/4);
+ else
+ img_height = align(height, align_h);
+
+
+ /* Because the images are packed better, the final offset
+ * might not be the maximal one:
+ */
+ tex->total_height = MAX2(tex->total_height, y + img_height);
+
+ /* Layout_below: step right after second mipmap.
+ */
+ if (level == pt->first_level + 1) {
+ x += align(width, align_w);
+ }
+ else {
+ y += img_height;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ }
+}
+
+
+static const int initial_offsets[6][2] = {
+ {0, 0},
+ {0, 2},
+ {1, 0},
+ {1, 2},
+ {1, 1},
+ {1, 3}
+};
+
+static const int step_offsets[6][2] = {
+ {0, 2},
+ {0, 2},
+ {-1, 2},
+ {-1, 2},
+ {-1, 1},
+ {-1, 1}
+};
+
+
+static boolean
+i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned level;
+
+ switch (pt->target) {
+ case PIPE_TEXTURE_CUBE: {
+ const unsigned dim = pt->width[0];
+ unsigned face;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+ assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+ /* double pitch for cube layouts */
+ tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+ tex->total_height = dim * 4;
+
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 6,
+ 0, 0,
+ /*OLD: tex->pitch, tex->total_height,*/
+ lvlWidth, lvlHeight,
+ 1);
+ lvlWidth /= 2;
+ lvlHeight /= 2;
+ }
+
+ for (face = 0; face < 6; face++) {
+ unsigned x = initial_offsets[face][0] * dim;
+ unsigned y = initial_offsets[face][1] * dim;
+ unsigned d = dim;
+
+ 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;
+ }
+ }
+ break;
+ }
+ case PIPE_TEXTURE_3D:{
+ 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.
+ */
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+
+ /* XXX: hardware expects/requires 9 levels at minimum.
+ */
+ for (level = pt->first_level; level <= MAX2(8, pt->last_level);
+ level++) {
+ i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height,
+ width, height, depth);
+
+
+ stack_height += MAX2(2, height);
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ }
+
+ /* Fixup depth image_offsets:
+ */
+ 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(tex, level, i,
+ 0, i * stack_height);
+
+ depth = minify(depth);
+ }
+
+
+ /* Multiply slice size by texture depth for total size. It's
+ * remarkable how wasteful of memory the i915 texture layouts
+ * are. They are largely fixed in the i945.
+ */
+ tex->total_height = stack_height * pt->depth[0];
+ break;
+ }
+
+ default:{
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned img_height;
+
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ tex->total_height = 0;
+
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 1,
+ 0, tex->total_height,
+ width, height, 1);
+
+ if (pt->compressed)
+ img_height = MAX2(1, height / 4);
+ else
+ img_height = (MAX2(2, height) + 1) & ~1;
+
+ tex->total_height += img_height;
+
+ width = minify(width);
+ height = minify(height);
+ }
+ break;
+ }
+ }
+ /*
+ DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+ tex->pitch,
+ tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
+ */
+
+ return TRUE;
+}
+
+
+static boolean
+i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned level;
+
+ switch (pt->target) {
+ case PIPE_TEXTURE_CUBE:{
+ const unsigned dim = pt->width[0];
+ unsigned face;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+ assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+ /* Depending on the size of the largest images, pitch can be
+ * determined either by the old-style packing of cubemap faces,
+ * or the final row of 4x4, 2x2 and 1x1 faces below this.
+ */
+ if (dim > 32)
+ tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+ else
+ tex->pitch = 14 * 8;
+
+ tex->total_height = dim * 4 + 4;
+
+ /* Set all the levels to effectively occupy the whole rectangular region.
+ */
+ 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;
+ lvlHeight /= 2;
+ }
+
+
+ for (face = 0; face < 6; face++) {
+ unsigned x = initial_offsets[face][0] * dim;
+ unsigned y = initial_offsets[face][1] * dim;
+ unsigned d = dim;
+
+ if (dim == 4 && face >= 4) {
+ y = tex->total_height - 4;
+ x = (face - 4) * 8;
+ }
+ else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+ y = tex->total_height - 4;
+ x = face * 8;
+ }
+
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_image_offset(tex, level, face, x, y);
+
+ d >>= 1;
+
+ switch (d) {
+ case 4:
+ switch (face) {
+ case PIPE_TEX_FACE_POS_X:
+ case PIPE_TEX_FACE_NEG_X:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ case PIPE_TEX_FACE_POS_Y:
+ case PIPE_TEX_FACE_NEG_Y:
+ y += 12;
+ x -= 8;
+ break;
+ case PIPE_TEX_FACE_POS_Z:
+ case PIPE_TEX_FACE_NEG_Z:
+ y = tex->total_height - 4;
+ x = (face - 4) * 8;
+ break;
+ }
+
+ case 2:
+ y = tex->total_height - 4;
+ x = 16 + face * 8;
+ break;
+
+ case 1:
+ x += 48;
+ break;
+
+ default:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case PIPE_TEXTURE_3D:{
+ 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;
+
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ tex->total_height = 0;
+
+ pack_y_pitch = MAX2(pt->height[0], 2);
+ pack_x_pitch = tex->pitch;
+ pack_x_nr = 1;
+
+ 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(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(tex, level, q, x, y);
+ x += pack_x_pitch;
+ }
+
+ x = 0;
+ y += pack_y_pitch;
+ }
+
+
+ tex->total_height += y;
+
+ if (pack_x_pitch > 4) {
+ pack_x_pitch >>= 1;
+ pack_x_nr <<= 1;
+ assert(pack_x_pitch * pack_x_nr <= tex->pitch);
+ }
+
+ if (pack_y_pitch > 2) {
+ pack_y_pitch >>= 1;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ }
+ break;
+ }
+
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+// case PIPE_TEXTURE_RECTANGLE:
+ i945_miptree_layout_2d(tex);
+ break;
+ default:
+ assert(0);
+ return FALSE;
+ }
+
+ /*
+ DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+ 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;
+}
--- /dev/null
+
+#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 */
struct pipe_sampler_state;
-struct pipe_mipmap_tree;
struct softpipe_tile_cache;
#define NUM_CHANNELS 4 /* R,G,B,A */
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],
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 * );
/** 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);
/*
* 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:
}
}
+
+/**
+ * \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 */
/**
- * 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 */
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;
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
#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"
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);
}
}
}
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);
}
}
}
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;
/*
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];
/* 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
#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 *);
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 * );
#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,
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);
*/
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;
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);
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Michel Dänzer <michel@tungstengraphics.com>
- */
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "sp_tex_layout.h"
-
-
-/* At the moment, just make softpipe use the same layout for its
- * textures as the i945. Softpipe needs some sort of texture layout,
- * this one was handy. May be worthwhile to simplify this code a
- * little.
- */
-
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
-static int align(int value, int alignment)
-{
- return (value + alignment - 1) & ~(alignment - 1);
-}
-
-
-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)
-{
- 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;
-
- /*
- 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);
- */
-
- /* 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;
- }
-
- assert(nr_images);
- assert(!mt->level[level].image_offset);
-
- mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
- mt->level[level].image_offset[0] = 0;
-}
-
-
-static void
-sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
- 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);
-
- mt->level[level].image_offset[img] = (x + y * mt->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]);
- */
-}
-
-
-static void
-sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
-{
- int align_h = 2, align_w = 4;
- unsigned level;
- unsigned x = 0;
- unsigned y = 0;
- unsigned width = mt->width0;
- unsigned height = mt->height0;
-
- mt->pitch = mt->width0;
- /* 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;
-
- /* 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 (mip1_width > mt->width0)
- mt->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;
-
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
- unsigned img_height;
-
- sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
-
- if (mt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = align(height, align_h);
-
-
- /* 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);
-
- /* Layout_below: step right after second mipmap.
- */
- if (level == mt->first_level + 1) {
- x += align(width, align_w);
- }
- else {
- y += img_height;
- }
-
- width = minify(width);
- height = minify(height);
- }
-}
-
-
-static const int initial_offsets[6][2] = {
- {0, 0},
- {0, 2},
- {1, 0},
- {1, 2},
- {1, 1},
- {1, 3}
-};
-
-static const int step_offsets[6][2] = {
- {0, 2},
- {0, 2},
- {-1, 2},
- {-1, 2},
- {-1, 1},
- {-1, 1}
-};
-
-
-
-boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
-{
- unsigned level;
-
- switch (mt->target) {
- case PIPE_TEXTURE_CUBE:{
- const unsigned dim = mt->width0;
- unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
-
- assert(lvlWidth == lvlHeight); /* cubemap images are square */
-
- /* Depending on the size of the largest images, pitch can be
- * determined either by the old-style packing of cubemap faces,
- * 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;
- else
- mt->pitch = 14 * 8;
-
- mt->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,
- 0, 0,
- lvlWidth, lvlHeight, 1);
- lvlWidth /= 2;
- lvlHeight /= 2;
- }
-
-
- for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- unsigned y = initial_offsets[face][1] * dim;
- unsigned d = dim;
-
- if (dim == 4 && face >= 4) {
- y = mt->total_height - 4;
- x = (face - 4) * 8;
- }
- else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
- y = mt->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);
-
- d >>= 1;
-
- switch (d) {
- case 4:
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- case PIPE_TEX_FACE_NEG_X:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- case PIPE_TEX_FACE_POS_Y:
- case PIPE_TEX_FACE_NEG_Y:
- y += 12;
- x -= 8;
- break;
- case PIPE_TEX_FACE_POS_Z:
- case PIPE_TEX_FACE_NEG_Z:
- y = mt->total_height - 4;
- x = (face - 4) * 8;
- break;
- }
-
- case 2:
- y = mt->total_height - 4;
- x = 16 + face * 8;
- break;
-
- case 1:
- x += 48;
- break;
-
- default:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- }
- }
- }
- break;
- }
- case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
- 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;
-
- pack_y_pitch = MAX2(mt->height0, 2);
- pack_x_pitch = mt->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;
- 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);
-
- 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);
- x += pack_x_pitch;
- }
-
- x = 0;
- y += pack_y_pitch;
- }
-
-
- mt->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);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- }
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- }
- break;
- }
-
- case PIPE_TEXTURE_1D:
- case PIPE_TEXTURE_2D:
-// case PIPE_TEXTURE_RECTANGLE:
- sp_miptree_layout_2d(mt);
- break;
- default:
- assert(0);
- break;
- }
-
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
- */
-
- return TRUE;
-}
-
+++ /dev/null
-#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 */
-
-
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];
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) {
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);
}
&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;
&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;
/**
* 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
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.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
+ * textures as the i945. Softpipe needs some sort of texture layout,
+ * this one was handy. May be worthwhile to simplify this code a
+ * little.
+ */
+
+static unsigned minify( unsigned d )
+{
+ return MAX2(1, d>>1);
+}
+
+static int align(int value, int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+
+static void
+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);
+
+ 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, spt->level_offset[level]);
+ */
+
+ /* Not sure when this would happen, but anyway:
+ */
+ if (spt->image_offset[level]) {
+ FREE( spt->image_offset[level] );
+ spt->image_offset[level] = NULL;
+ }
+
+ assert(nr_images);
+ assert(!spt->image_offset[level]);
+
+ spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
+ spt->image_offset[level][0] = 0;
+}
+
+
+static void
+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 < spt->nr_images[level]);
+
+ 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, spt->image_offset[level][img]);
+ */
+}
+
+
+static void
+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 = pt->width[0];
+ unsigned height = pt->height[0];
+
+ 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 (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 (pt->first_level != pt->last_level) {
+ unsigned mip1_width = align(minify(pt->width[0]), align_w)
+ + minify(minify(pt->width[0]));
+
+ 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.
+ */
+ spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp;
+ spt->total_height = 0;
+
+ for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
+ unsigned img_height;
+
+ sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1);
+
+ if (pt->compressed)
+ img_height = MAX2(1, height/4);
+ else
+ img_height = align(height, align_h);
+
+
+ /* Because the images are packed better, the final offset
+ * might not be the maximal one:
+ */
+ spt->total_height = MAX2(spt->total_height, y + img_height);
+
+ /* Layout_below: step right after second mipmap.
+ */
+ if (level == pt->first_level + 1) {
+ x += align(width, align_w);
+ }
+ else {
+ y += img_height;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ }
+}
+
+
+static const int initial_offsets[6][2] = {
+ {0, 0},
+ {0, 2},
+ {1, 0},
+ {1, 2},
+ {1, 1},
+ {1, 3}
+};
+
+static const int step_offsets[6][2] = {
+ {0, 2},
+ {0, 2},
+ {-1, 2},
+ {-1, 2},
+ {-1, 1},
+ {-1, 1}
+};
+
+
+
+static boolean
+softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt)
+{
+ struct pipe_texture *pt = &spt->base;
+ unsigned level;
+
+ switch (pt->target) {
+ case PIPE_TEXTURE_CUBE:{
+ const unsigned dim = pt->width[0];
+ unsigned face;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+
+ assert(lvlWidth == lvlHeight); /* cubemap images are square */
+
+ /* Depending on the size of the largest images, pitch can be
+ * determined either by the old-style packing of cubemap faces,
+ * or the final row of 4x4, 2x2 and 1x1 faces below this.
+ */
+ if (dim > 32)
+ spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+ else
+ spt->pitch = 14 * 8;
+
+ spt->total_height = dim * 4 + 4;
+
+ /* Set all the levels to effectively occupy the whole rectangular region.
+ */
+ 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;
+ lvlHeight /= 2;
+ }
+
+
+ for (face = 0; face < 6; face++) {
+ unsigned x = initial_offsets[face][0] * dim;
+ unsigned y = initial_offsets[face][1] * dim;
+ unsigned d = dim;
+
+ if (dim == 4 && face >= 4) {
+ y = spt->total_height - 4;
+ x = (face - 4) * 8;
+ }
+ else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+ y = spt->total_height - 4;
+ x = face * 8;
+ }
+
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ sp_miptree_set_image_offset(spt, level, face, x, y);
+
+ d >>= 1;
+
+ switch (d) {
+ case 4:
+ switch (face) {
+ case PIPE_TEX_FACE_POS_X:
+ case PIPE_TEX_FACE_NEG_X:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ case PIPE_TEX_FACE_POS_Y:
+ case PIPE_TEX_FACE_NEG_Y:
+ y += 12;
+ x -= 8;
+ break;
+ case PIPE_TEX_FACE_POS_Z:
+ case PIPE_TEX_FACE_NEG_Z:
+ y = spt->total_height - 4;
+ x = (face - 4) * 8;
+ break;
+ }
+
+ case 2:
+ y = spt->total_height - 4;
+ x = 16 + face * 8;
+ break;
+
+ case 1:
+ x += 48;
+ break;
+
+ default:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case PIPE_TEXTURE_3D:{
+ 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;
+
+ spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ spt->total_height = 0;
+
+ pack_y_pitch = MAX2(pt->height[0], 2);
+ pack_x_pitch = spt->pitch;
+ pack_x_nr = 1;
+
+ 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(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(spt, level, q, x, y);
+ x += pack_x_pitch;
+ }
+
+ x = 0;
+ y += pack_y_pitch;
+ }
+
+
+ spt->total_height += y;
+
+ if (pack_x_pitch > 4) {
+ pack_x_pitch >>= 1;
+ pack_x_nr <<= 1;
+ assert(pack_x_pitch * pack_x_nr <= spt->pitch);
+ }
+
+ if (pack_y_pitch > 2) {
+ pack_y_pitch >>= 1;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ }
+ break;
+ }
+
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+// case PIPE_TEXTURE_RECTANGLE:
+ sp_miptree_layout_2d(spt);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ /*
+ DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
+ 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;
+}
--- /dev/null
+#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 */
+
+
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];
void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
uint i;
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,
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],
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 \
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);
}
}
#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"
#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"
}
-
-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;
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
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 */
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;
}
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,
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.
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 {
/**
* 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 */
}
}
/**
- * 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
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 */
} /* 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;
}
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);
}
}
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;
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;
/* 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);
}
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);
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
#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"
{
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;
/* 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;
-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)
}
-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;
}
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;
}
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);
}
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) {
}
-/* 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.
*/
/* 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;
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__);
}
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 =
/* 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,
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;
/* 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");
* 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,
/* 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) {
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. */
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;
}
/*
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;
}
}
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),
/* 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
_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;
}
}
{
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;
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);
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;
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
* 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); /* ? */
/* size */
width, height);
#endif
-
- pipe_surface_reference(&dest_surface, NULL);
}
else {
fallback_copy_texsubimage(ctx, target, level,
srcX, srcY, width, height);
}
+ pipe_surface_reference(&dest_surface, NULL);
#if 0
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
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,
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,
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,
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);
*/
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 =
/* 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) {
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++) {
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;
}
}
#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
struct st_context;
struct st_region;
struct st_texture_object;
-struct st_texture_image;
struct st_fragment_program;
struct draw_context;
struct draw_stage;
+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
{
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;
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "st_mipmap_tree.h"
-#include "enums.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_winsys.h"
-
-
-#define DBG if(0) printf
-
-#if 0
-static GLenum
-target_to_target(GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
- return GL_TEXTURE_CUBE_MAP_ARB;
- default:
- return target;
- }
-}
-#endif
-
-struct pipe_mipmap_tree *
-st_miptree_create(struct pipe_context *pipe,
- unsigned target,
- GLenum internal_format,
- GLuint first_level,
- GLuint last_level,
- GLuint width0,
- GLuint height0,
- GLuint depth0, GLuint cpp, GLuint compress_byte)
-{
- GLboolean ok;
- struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1);
- GLbitfield flags = 0x0;
-
- assert(target <= PIPE_TEXTURE_CUBE);
-
- DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
- _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);
- 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;
-
- DBG("%s deleting %p\n", __FUNCTION__, (void *) *mt);
-
- pipe->winsys->region_release(pipe->winsys, &((*mt)->region));
-
- for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
- if ((*mt)->level[i].image_offset)
- free((*mt)->level[i].image_offset);
-
- free(*mt);
- }
- *mt = NULL;
-}
-
-
-
-
-/* Can the image be pulled into a unified mipmap tree. 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,
- struct gl_texture_image *image,
- GLuint face, GLuint level)
-{
- /* Images with borders are never pulled into mipmap trees.
- */
- if (image->Border)
- return GL_FALSE;
-
- if (image->InternalFormat != mt->internal_format ||
- image->IsCompressed != mt->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.
- */
- if (image->Width != mt->level[level].width ||
- image->Height != mt->level[level].height ||
- image->Depth != mt->level[level].depth)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-
-/* 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.
- *
- * These functions present that view to mesa:
- */
-const GLuint *
-st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
-{
- static const GLuint zero = 0;
-
- if (mt->target != PIPE_TEXTURE_3D || mt->level[level].nr_images == 1)
- return &zero;
- else
- return mt->level[level].image_offset;
-}
-
-
-/**
- * Return the offset to the given mipmap texture image within the
- * texture memory buffer, in bytes.
- */
-GLuint
-st_miptree_image_offset(const struct pipe_mipmap_tree * mt,
- GLuint face, GLuint level)
-{
- if (mt->target == PIPE_TEXTURE_CUBE)
- return (mt->level[level].level_offset +
- mt->level[level].image_offset[face] * mt->cpp);
- else
- return mt->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;
-}
-
-
-
-/**
- * Map a teximage in a mipmap tree.
- * \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)
-{
- GLubyte *ptr;
- DBG("%s \n", __FUNCTION__);
-
- if (row_stride)
- *row_stride = mt->pitch * mt->cpp;
-
- if (image_offsets)
- memcpy(image_offsets, mt->level[level].image_offset,
- mt->level[level].depth * sizeof(GLuint));
-
- ptr = pipe->region_map(pipe, mt->region);
-
- return ptr + st_miptree_image_offset(mt, face, level);
-}
-
-void
-st_miptree_image_unmap(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt)
-{
- DBG("%s\n", __FUNCTION__);
- pipe->region_unmap(pipe, mt->region);
-}
-
-
-
-/* Upload data for a particular image.
- */
-void
-st_miptree_image_data(struct pipe_context *pipe,
- struct pipe_mipmap_tree *dst,
- GLuint face,
- GLuint level,
- void *src,
- GLuint src_row_pitch, GLuint src_image_pitch)
-{
- GLuint depth = dst->level[level].depth;
- GLuint i;
- GLuint height = 0;
- const GLubyte *srcUB = src;
- struct pipe_surface *dst_surface;
-
- DBG("%s\n", __FUNCTION__);
- for (i = 0; i < depth; i++) {
- height = dst->level[level].height;
- if(dst->compressed)
- height /= 4;
-
- dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
-
- pipe->surface_data(pipe, dst_surface,
- 0, 0, /* dstx, dsty */
- srcUB,
- src_row_pitch,
- 0, 0, /* source x, y */
- dst->level[level].width, height); /* width, height */
-
- pipe_surface_reference(&dst_surface, NULL);
-
- srcUB += src_image_pitch * dst->cpp;
- }
-}
-
-/* Copy mipmap image between trees
- */
-void
-st_miptree_image_copy(struct pipe_context *pipe,
- struct pipe_mipmap_tree *dst,
- GLuint face, GLuint level,
- struct pipe_mipmap_tree *src)
-{
- GLuint width = src->level[level].width;
- GLuint height = src->level[level].height;
- GLuint depth = src->level[level].depth;
- struct pipe_surface *src_surface;
- struct pipe_surface *dst_surface;
- GLuint i;
-
- if (dst->compressed)
- height /= 4;
- for (i = 0; i < depth; i++) {
- dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
- src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
-
- pipe->surface_copy(pipe,
- dst_surface,
- 0, 0, /* destX, Y */
- src_surface,
- 0, 0, /* srcX, Y */
- width, height);
-
- pipe_surface_reference(&dst_surface, NULL);
- pipe_surface_reference(&src_surface, NULL);
- }
-
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#ifndef ST_MIPMAP_TREE_H
-#define ST_MIPMAP_TREE_H
-
-
-#include "main/mtypes.h"
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-struct pipe_region;
-
-
-extern struct pipe_mipmap_tree *
-st_miptree_create(struct pipe_context *pipe,
- GLenum target,
- 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
- */
-extern GLboolean
-st_miptree_match_image(struct pipe_mipmap_tree *mt,
- struct gl_texture_image *image,
- GLuint face, GLuint level);
-
-/* Return a pointer to an image within a tree. 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);
-
-extern void
-st_miptree_image_unmap(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt);
-
-
-/* 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);
-
-
-/* Return the linear offset of an image relative to the start of the
- * tree:
- */
-extern GLuint
-st_miptree_image_offset(const struct pipe_mipmap_tree *mt,
- GLuint face, GLuint level);
-
-extern GLuint
-st_miptree_texel_offset(const struct pipe_mipmap_tree * mt,
- GLuint face, GLuint level,
- GLuint col, GLuint row, GLuint img);
-
-
-/* Upload an image into a tree
- */
-extern void
-st_miptree_image_data(struct pipe_context *pipe,
- struct pipe_mipmap_tree *dst,
- GLuint face, GLuint level, void *src,
- GLuint src_row_pitch, GLuint src_image_pitch);
-
-
-/* Copy an image between two trees
- */
-extern void
-st_miptree_image_copy(struct pipe_context *pipe,
- struct pipe_mipmap_tree *dst,
- GLuint face, GLuint level,
- struct pipe_mipmap_tree *src);
-
-
-#endif
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "st_context.h"
+#include "st_format.h"
+#include "st_texture.h"
+#include "enums.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_winsys.h"
+
+
+#define DBG if(0) printf
+
+#if 0
+static GLenum
+target_to_target(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ return GL_TEXTURE_CUBE_MAP_ARB;
+ default:
+ return target;
+ }
+}
+#endif
+
+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 compress_byte)
+{
+ struct pipe_texture *pt = CALLOC_STRUCT(pipe_texture);
+
+ assert(target <= PIPE_TEXTURE_CUBE);
+
+ DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(internal_format), first_level, last_level);
+
+ if (!pt)
+ return NULL;
+
+ assert(format);
+
+ 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;
+
+ st->pipe->texture_create(st->pipe, &pt);
+
+ return pt;
+}
+
+
+
+
+/* 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_texture_match_image(struct pipe_texture *pt,
+ struct gl_texture_image *image,
+ GLuint face, GLuint level)
+{
+ /* Images with borders are never pulled into mipmap textures.
+ */
+ if (image->Border)
+ return GL_FALSE;
+
+ 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
+ * texture, changed targets, etc.
+ */
+ 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.
+ *
+ * These functions present that view to mesa:
+ */
+const GLuint *
+st_texture_depth_offsets(struct pipe_texture *pt, GLuint level)
+{
+ static const GLuint zero = 0;
+
+ if (pt->target != PIPE_TEXTURE_3D || pt->level[level].nr_images == 1)
+ return &zero;
+ else
+ return pt->level[level].image_offset;
+}
+
+
+/**
+ * Return the offset to the given mipmap texture image within the
+ * texture memory buffer, in bytes.
+ */
+GLuint
+st_texture_image_offset(const struct pipe_texture * pt,
+ GLuint face, GLuint level)
+{
+ if (pt->target == PIPE_TEXTURE_CUBE)
+ return (pt->level[level].level_offset +
+ pt->level[level].image_offset[face] * pt->cpp);
+ else
+ return pt->level[level].level_offset;
+}
+#endif
+
+
+/**
+ * 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_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
+ GLuint zoffset)
+{
+ struct pipe_texture *pt = stImage->pt;
+ DBG("%s \n", __FUNCTION__);
+
+ stImage->surface = st->pipe->get_tex_surface(st->pipe, pt, stImage->face,
+ stImage->level, zoffset);
+
+ (void) st->pipe->region_map(st->pipe, stImage->surface->region);
+
+ return stImage->surface->region->map + stImage->surface->offset;
+}
+
+void
+st_texture_image_unmap(struct st_context *st, struct st_texture_image *stImage)
+{
+ DBG("%s\n", __FUNCTION__);
+
+ st->pipe->region_unmap(st->pipe, stImage->surface->region);
+
+ pipe_surface_reference(&stImage->surface, NULL);
+}
+
+
+
+/* Upload data for a particular image.
+ */
+void
+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->depth[level];
+ GLuint i;
+ GLuint height = 0;
+ const GLubyte *srcUB = src;
+ struct pipe_surface *dst_surface;
+
+ DBG("%s\n", __FUNCTION__);
+ for (i = 0; i < depth; i++) {
+ height = dst->height[level];
+ if(dst->compressed)
+ height /= 4;
+
+ dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+
+ pipe->surface_data(pipe, dst_surface,
+ 0, 0, /* dstx, dsty */
+ srcUB,
+ src_row_pitch,
+ 0, 0, /* source x, y */
+ dst->width[level], height); /* width, height */
+
+ pipe_surface_reference(&dst_surface, NULL);
+
+ srcUB += src_image_pitch * dst->cpp;
+ }
+}
+
+/* Copy mipmap image between textures
+ */
+void
+st_texture_image_copy(struct pipe_context *pipe,
+ struct pipe_texture *dst,
+ GLuint face, GLuint level,
+ struct pipe_texture *src)
+{
+ 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;
+
+ if (dst->compressed)
+ height /= 4;
+ for (i = 0; i < depth; i++) {
+ dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
+ src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
+
+ pipe->surface_copy(pipe,
+ dst_surface,
+ 0, 0, /* destX, Y */
+ src_surface,
+ 0, 0, /* srcX, Y */
+ width, height);
+
+ pipe_surface_reference(&dst_surface, NULL);
+ pipe_surface_reference(&src_surface, NULL);
+ }
+
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef ST_TEXTURE_H
+#define ST_TEXTURE_H
+
+
+#include "main/mtypes.h"
+
+struct pipe_context;
+struct pipe_texture;
+struct pipe_region;
+
+
+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 compress_byte);
+
+
+/* Check if an image fits an existing texture
+ */
+extern GLboolean
+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 texture. Return image stride as
+ * well.
+ */
+extern GLubyte *
+st_texture_image_map(struct st_context *st,
+ struct st_texture_image *stImage,
+ GLuint zoffset);
+
+extern void
+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_texture_depth_offsets(struct pipe_texture *pt, GLuint level);
+
+
+/* Return the linear offset of an image relative to the start of its region:
+ */
+extern GLuint
+st_texture_image_offset(const struct pipe_texture *pt,
+ GLuint face, GLuint level);
+
+extern GLuint
+st_texture_texel_offset(const struct pipe_texture * pt,
+ GLuint face, GLuint level,
+ GLuint col, GLuint row, GLuint img);
+
+
+/* Upload an image into a texture
+ */
+extern void
+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 textures
+ */
+extern void
+st_texture_image_copy(struct pipe_context *pipe,
+ struct pipe_texture *dst,
+ GLuint face, GLuint level,
+ struct pipe_texture *src);
+
+
+#endif