summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2007-11-30 20:48:03 +0100
committerMichel Dänzer <[email protected]>2007-12-06 11:18:11 +0100
commit753db0d8407147393a7b0622ae3fa28f68d0353d (patch)
tree8c11ae7b18cb34ae65e984fc7d9be50616bf99d4 /src/mesa/pipe
parent59356268187470c5fda9e9a1a7058607f938fb3b (diff)
Hide texture layout details from the state tracker.
pipe->get_tex_surface() has to be used for access to texture image data.
Diffstat (limited to 'src/mesa/pipe')
-rw-r--r--src/mesa/pipe/failover/fo_context.c3
-rw-r--r--src/mesa/pipe/failover/fo_context.h2
-rw-r--r--src/mesa/pipe/failover/fo_state.c2
-rw-r--r--src/mesa/pipe/i915simple/Makefile2
-rw-r--r--src/mesa/pipe/i915simple/i915_context.c9
-rw-r--r--src/mesa/pipe/i915simple/i915_context.h30
-rw-r--r--src/mesa/pipe/i915simple/i915_state.c4
-rw-r--r--src/mesa/pipe/i915simple/i915_state_sampler.c29
-rw-r--r--src/mesa/pipe/i915simple/i915_surface.c25
-rw-r--r--src/mesa/pipe/i915simple/i915_tex_layout.h16
-rw-r--r--src/mesa/pipe/i915simple/i915_texture.c (renamed from src/mesa/pipe/i915simple/i915_tex_layout.c)269
-rw-r--r--src/mesa/pipe/i915simple/i915_texture.h16
-rw-r--r--src/mesa/pipe/llvm/llvm_entry.c2
-rw-r--r--src/mesa/pipe/p_context.h11
-rw-r--r--src/mesa/pipe/p_inlines.h20
-rw-r--r--src/mesa/pipe/p_state.h42
-rw-r--r--src/mesa/pipe/softpipe/Makefile2
-rw-r--r--src/mesa/pipe/softpipe/sp_context.c17
-rw-r--r--src/mesa/pipe/softpipe/sp_context.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_quad_fs.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_state.h31
-rw-r--r--src/mesa/pipe/softpipe/sp_state_fs.c2
-rw-r--r--src/mesa/pipe/softpipe/sp_state_sampler.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.c25
-rw-r--r--src/mesa/pipe/softpipe/sp_surface.h2
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_layout.h16
-rw-r--r--src/mesa/pipe/softpipe/sp_tex_sample.c18
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.c (renamed from src/mesa/pipe/softpipe/sp_tex_layout.c)214
-rw-r--r--src/mesa/pipe/softpipe/sp_texture.h18
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.c4
-rw-r--r--src/mesa/pipe/softpipe/sp_tile_cache.h2
-rw-r--r--src/mesa/pipe/tgsi/exec/tgsi_exec.h2
32 files changed, 515 insertions, 328 deletions
diff --git a/src/mesa/pipe/failover/fo_context.c b/src/mesa/pipe/failover/fo_context.c
index 0cc9cab408c..a25563d4511 100644
--- a/src/mesa/pipe/failover/fo_context.c
+++ b/src/mesa/pipe/failover/fo_context.c
@@ -145,7 +145,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
failover->pipe.surface_data = hw->surface_data;
failover->pipe.surface_copy = hw->surface_copy;
failover->pipe.surface_fill = hw->surface_fill;
- failover->pipe.mipmap_tree_layout = hw->mipmap_tree_layout;
+ failover->pipe.texture_create = hw->texture_create;
+ failover->pipe.texture_release = hw->texture_release;
failover->pipe.flush = hw->flush;
failover->dirty = 0;
diff --git a/src/mesa/pipe/failover/fo_context.h b/src/mesa/pipe/failover/fo_context.h
index 759b53ccbe4..7cf18c9ec19 100644
--- a/src/mesa/pipe/failover/fo_context.h
+++ b/src/mesa/pipe/failover/fo_context.h
@@ -85,7 +85,7 @@ struct failover_context {
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
uint sampler_units[PIPE_MAX_SAMPLERS];
- struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
diff --git a/src/mesa/pipe/failover/fo_state.c b/src/mesa/pipe/failover/fo_state.c
index 2cd1a50b203..fd6137ba662 100644
--- a/src/mesa/pipe/failover/fo_state.c
+++ b/src/mesa/pipe/failover/fo_state.c
@@ -402,7 +402,7 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
static void
failover_set_texture_state(struct pipe_context *pipe,
unsigned unit,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
struct failover_context *failover = failover_context(pipe);
diff --git a/src/mesa/pipe/i915simple/Makefile b/src/mesa/pipe/i915simple/Makefile
index 391a084915d..1223b386a3d 100644
--- a/src/mesa/pipe/i915simple/Makefile
+++ b/src/mesa/pipe/i915simple/Makefile
@@ -22,7 +22,7 @@ DRIVER_SOURCES = \
i915_strings.c \
i915_prim_emit.c \
i915_prim_vbuf.c \
- i915_tex_layout.c \
+ i915_texture.c \
i915_fpc_emit.c \
i915_fpc_translate.c \
i915_surface.c
diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c
index a0ed3032b12..94649231cf3 100644
--- a/src/mesa/pipe/i915simple/i915_context.c
+++ b/src/mesa/pipe/i915simple/i915_context.c
@@ -29,7 +29,7 @@
#include "i915_winsys.h"
#include "i915_state.h"
#include "i915_batch.h"
-#include "i915_tex_layout.h"
+#include "i915_texture.h"
#include "i915_reg.h"
#include "pipe/draw/draw_context.h"
@@ -357,11 +357,8 @@ struct pipe_context *i915_create( struct pipe_winsys *pipe_winsys,
i915->pci_id = pci_id;
i915->flags.is_i945 = is_i945;
- if (i915->flags.is_i945)
- i915->pipe.mipmap_tree_layout = i945_miptree_layout;
- else
- i915->pipe.mipmap_tree_layout = i915_miptree_layout;
-
+ i915->pipe.texture_create = i915_texture_create;
+ i915->pipe.texture_release = i915_texture_release;
i915->dirty = ~0;
i915->hardware_dirty = ~0;
diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h
index ee430ebc902..8ed3465be23 100644
--- a/src/mesa/pipe/i915simple/i915_context.h
+++ b/src/mesa/pipe/i915simple/i915_context.h
@@ -150,6 +150,34 @@ struct i915_alpha_test_state {
unsigned LIS6;
};
+struct i915_texture {
+ struct pipe_texture base;
+
+ /* Derived from the above:
+ */
+ unsigned pitch;
+ unsigned depth_pitch; /* per-image on i945? */
+ unsigned total_height;
+
+ unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* Explicitly store the offset of each image for each cube face or
+ * depth value. Pretty much have to accept that hardware formats
+ * are going to be so diverse that there is no unified way to
+ * compute the offsets of depth/cube images within a mipmap level,
+ * so have to store them as a lookup table:
+ */
+ unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+
+ /* Includes image offset tables:
+ */
+ unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* The data is held here:
+ */
+ struct pipe_region *region;
+};
+
struct i915_context
{
struct pipe_context pipe;
@@ -174,7 +202,7 @@ struct i915_context
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
uint sampler_units[PIPE_MAX_SAMPLERS];
- struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+ struct i915_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
diff --git a/src/mesa/pipe/i915simple/i915_state.c b/src/mesa/pipe/i915simple/i915_state.c
index 468d0ce91b1..038fd623ea1 100644
--- a/src/mesa/pipe/i915simple/i915_state.c
+++ b/src/mesa/pipe/i915simple/i915_state.c
@@ -525,11 +525,11 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
static void i915_set_texture_state(struct pipe_context *pipe,
unsigned unit,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
struct i915_context *i915 = i915_context(pipe);
- i915->texture[unit] = texture; /* ptr, not struct */
+ i915->texture[unit] = (struct i915_texture*)texture; /* ptr, not struct */
i915->dirty |= I915_NEW_TEXTURE;
}
diff --git a/src/mesa/pipe/i915simple/i915_state_sampler.c b/src/mesa/pipe/i915simple/i915_state_sampler.c
index 0991e6ac0d1..1816d9abdb7 100644
--- a/src/mesa/pipe/i915simple/i915_state_sampler.c
+++ b/src/mesa/pipe/i915simple/i915_state_sampler.c
@@ -46,9 +46,11 @@
static void update_sampler(struct i915_context *i915,
uint unit,
const struct i915_sampler_state *sampler,
- const struct pipe_mipmap_tree *mt,
+ const struct i915_texture *tex,
unsigned state[3] )
{
+ const struct pipe_texture *pt = &tex->base;
+
/* Need to do this after updating the maps, which call the
* intel_finalize_mipmap_tree and hence can update firstLevel:
*/
@@ -56,8 +58,8 @@ static void update_sampler(struct i915_context *i915,
state[1] = sampler->state[1];
state[2] = sampler->state[2];
- if (mt->format == PIPE_FORMAT_YCBCR ||
- mt->format == PIPE_FORMAT_YCBCR_REV)
+ if (pt->format == PIPE_FORMAT_YCBCR ||
+ pt->format == PIPE_FORMAT_YCBCR_REV)
state[0] |= SS2_COLORSPACE_CONVERSION;
/* 3D textures don't seem to respect the border color.
@@ -75,7 +77,7 @@ static void update_sampler(struct i915_context *i915,
const unsigned ws = sampler->templ->wrap_s;
const unsigned wt = sampler->templ->wrap_t;
const unsigned wr = sampler->templ->wrap_r;
- if (mt->target == PIPE_TEXTURE_3D &&
+ if (pt->target == PIPE_TEXTURE_3D &&
(sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
(ws == PIPE_TEX_WRAP_CLAMP ||
@@ -105,13 +107,13 @@ void i915_update_samplers( struct i915_context *i915 )
i915->current.sampler_enable_flags = 0x0;
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
- /* determine unit enable/disable by looking for a bound mipmap tree */
+ /* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
if (i915->texture[unit]) {
update_sampler( i915,
unit,
i915->sampler[unit], /* sampler state */
- i915->texture[unit], /* mipmap tree */
+ i915->texture[unit], /* texture */
i915->current.sampler[unit] /* the result */
);
@@ -179,18 +181,19 @@ static void
i915_update_texture(struct i915_context *i915, uint unit,
uint state[6])
{
- const struct pipe_mipmap_tree *mt = i915->texture[unit];
+ const struct i915_texture *tex = i915->texture[unit];
+ const struct pipe_texture *pt = &tex->base;
uint format, pitch;
- const uint width = mt->width0, height = mt->height0, depth = mt->depth0;
- const uint num_levels = mt->last_level - mt->first_level;
+ const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
+ const uint num_levels = pt->last_level - pt->first_level;
- assert(mt);
+ assert(tex);
assert(width);
assert(height);
assert(depth);
- format = translate_texture_format(mt->format);
- pitch = mt->pitch * mt->cpp;
+ format = translate_texture_format(pt->format);
+ pitch = tex->pitch * pt->cpp;
assert(format);
assert(pitch);
@@ -217,7 +220,7 @@ i915_update_textures(struct i915_context *i915)
uint unit;
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
- /* determine unit enable/disable by looking for a bound mipmap tree */
+ /* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
if (i915->texture[unit]) {
i915_update_texture(i915, unit, i915->current.texbuffer[unit]);
diff --git a/src/mesa/pipe/i915simple/i915_surface.c b/src/mesa/pipe/i915simple/i915_surface.c
index e4a5de00d77..385202507db 100644
--- a/src/mesa/pipe/i915simple/i915_surface.c
+++ b/src/mesa/pipe/i915simple/i915_surface.c
@@ -187,34 +187,35 @@ i915_put_tile(struct pipe_context *pipe,
*/
static struct pipe_surface *
i915_get_tex_surface(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt,
+ struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
+ struct i915_texture *tex = (struct i915_texture *)pt;
struct pipe_surface *ps;
unsigned offset; /* in bytes */
- offset = mt->level[level].level_offset;
+ offset = tex->level_offset[level];
- if (mt->target == PIPE_TEXTURE_CUBE) {
- offset += mt->level[level].image_offset[face] * mt->cpp;
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ offset += tex->image_offset[level][face] * pt->cpp;
}
- else if (mt->target == PIPE_TEXTURE_3D) {
- offset += mt->level[level].image_offset[zslice] * mt->cpp;
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ offset += tex->image_offset[level][zslice] * pt->cpp;
}
else {
assert(face == 0);
assert(zslice == 0);
}
- ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format);
+ ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
if (ps) {
assert(ps->format);
assert(ps->refcount);
- pipe_region_reference(&ps->region, mt->region);
- ps->cpp = mt->cpp;
- ps->width = mt->level[level].width;
- ps->height = mt->level[level].height;
- ps->pitch = mt->pitch;
+ pipe_region_reference(&ps->region, tex->region);
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = tex->pitch;
ps->offset = offset;
}
return ps;
diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.h b/src/mesa/pipe/i915simple/i915_tex_layout.h
deleted file mode 100644
index e0337863815..00000000000
--- a/src/mesa/pipe/i915simple/i915_tex_layout.h
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#ifndef I915_TEX_LAYOUT_H
-#define I915_TEX_LAYOUT_H
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-
-
-extern boolean
-i915_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
-
-extern boolean
-i945_miptree_layout(struct pipe_context *, struct pipe_mipmap_tree *);
-
-
-#endif /* I915_TEX_LAYOUT_H */
diff --git a/src/mesa/pipe/i915simple/i915_tex_layout.c b/src/mesa/pipe/i915simple/i915_texture.c
index cb372a7170d..3bfa806d9ec 100644
--- a/src/mesa/pipe/i915simple/i915_tex_layout.c
+++ b/src/mesa/pipe/i915simple/i915_texture.c
@@ -34,8 +34,10 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
-#include "i915_tex_layout.h"
+#include "i915_context.h"
+#include "i915_texture.h"
#include "i915_debug.h"
@@ -51,94 +53,98 @@ static int align(int value, int alignment)
static void
-i915_miptree_set_level_info(struct pipe_mipmap_tree *mt,
+i915_miptree_set_level_info(struct i915_texture *tex,
unsigned level,
unsigned nr_images,
unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
{
+ struct pipe_texture *pt = &tex->base;
+
assert(level < PIPE_MAX_TEXTURE_LEVELS);
- mt->level[level].width = w;
- mt->level[level].height = h;
- mt->level[level].depth = d;
- mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
- mt->level[level].nr_images = nr_images;
+ pt->width[level] = w;
+ pt->height[level] = h;
+ pt->depth[level] = d;
+
+ tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp;
+ tex->nr_images[level] = nr_images;
/*
DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
- level, w, h, d, x, y, mt->level[level].level_offset);
+ level, w, h, d, x, y, tex->level_offset[level]);
*/
/* Not sure when this would happen, but anyway:
*/
- if (mt->level[level].image_offset) {
- FREE(mt->level[level].image_offset);
- mt->level[level].image_offset = NULL;
+ if (tex->image_offset[level]) {
+ FREE(tex->image_offset[level]);
+ tex->image_offset[level] = NULL;
}
assert(nr_images);
- assert(!mt->level[level].image_offset);
+ assert(!tex->image_offset[level]);
- mt->level[level].image_offset = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
- mt->level[level].image_offset[0] = 0;
+ tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
+ tex->image_offset[level][0] = 0;
}
static void
-i915_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
- unsigned level, unsigned img, unsigned x, unsigned y)
+i915_miptree_set_image_offset(struct i915_texture *tex,
+ unsigned level, unsigned img, unsigned x, unsigned y)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
- assert(img < mt->level[level].nr_images);
+ assert(img < tex->nr_images[level]);
- mt->level[level].image_offset[img] = (x + y * mt->pitch);
+ tex->image_offset[level][img] = (x + y * tex->pitch);
/*
DBG("%s level %d img %d pos %d,%d image_offset %x\n",
- __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
+ __FUNCTION__, level, img, x, y, tex->image_offset[level][img]);
*/
}
static void
-i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
+i945_miptree_layout_2d( struct i915_texture *tex )
{
+ struct pipe_texture *pt = &tex->base;
int align_h = 2, align_w = 4;
unsigned level;
unsigned x = 0;
unsigned y = 0;
- unsigned width = mt->width0;
- unsigned height = mt->height0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
- mt->pitch = mt->width0;
+ tex->pitch = pt->width[0];
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap. This occurs when the alignment
* constraints of mipmap placement push the right edge of the
* 2nd mipmap out past the width of its parent.
*/
- if (mt->first_level != mt->last_level) {
- unsigned mip1_width = align(minify(mt->width0), align_w)
- + minify(minify(mt->width0));
+ if (pt->first_level != pt->last_level) {
+ unsigned mip1_width = align(minify(pt->width[0]), align_w)
+ + minify(minify(pt->width[0]));
- if (mip1_width > mt->width0)
- mt->pitch = mip1_width;
+ if (mip1_width > pt->width[0])
+ tex->pitch = mip1_width;
}
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
- mt->total_height = 0;
+ tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
+ tex->total_height = 0;
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+ for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
unsigned img_height;
- i915_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
+ i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1);
- if (mt->compressed)
+ if (pt->compressed)
img_height = MAX2(1, height/4);
else
img_height = align(height, align_h);
@@ -147,11 +153,11 @@ i945_miptree_layout_2d( struct pipe_mipmap_tree *mt )
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
- mt->total_height = MAX2(mt->total_height, y + img_height);
+ tex->total_height = MAX2(tex->total_height, y + img_height);
/* Layout_below: step right after second mipmap.
*/
- if (level == mt->first_level + 1) {
+ if (level == pt->first_level + 1) {
x += align(width, align_w);
}
else {
@@ -183,27 +189,28 @@ static const int step_offsets[6][2] = {
};
-boolean
-i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+static boolean
+i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
{
+ struct pipe_texture *pt = &tex->base;
unsigned level;
- switch (mt->target) {
+ switch (pt->target) {
case PIPE_TEXTURE_CUBE: {
- const unsigned dim = mt->width0;
+ const unsigned dim = pt->width[0];
unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
assert(lvlWidth == lvlHeight); /* cubemap images are square */
/* double pitch for cube layouts */
- mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
- mt->total_height = dim * 4;
+ tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+ tex->total_height = dim * 4;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_level_info(mt, level, 6,
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 6,
0, 0,
- /*OLD: mt->pitch, mt->total_height,*/
+ /*OLD: tex->pitch, tex->total_height,*/
lvlWidth, lvlHeight,
1);
lvlWidth /= 2;
@@ -215,8 +222,8 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
unsigned y = initial_offsets[face][1] * dim;
unsigned d = dim;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_image_offset(mt, level, face, x, y);
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1;
x += step_offsets[face][0] * d;
y += step_offsets[face][1] * d;
@@ -225,20 +232,20 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
break;
}
case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
unsigned stack_height = 0;
/* Calculate the size of a single slice.
*/
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
/* XXX: hardware expects/requires 9 levels at minimum.
*/
- for (level = mt->first_level; level <= MAX2(8, mt->last_level);
+ for (level = pt->first_level; level <= MAX2(8, pt->last_level);
level++) {
- i915_miptree_set_level_info(mt, level, depth, 0, mt->total_height,
+ i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height,
width, height, depth);
@@ -251,11 +258,11 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
/* Fixup depth image_offsets:
*/
- depth = mt->depth0;
- for (level = mt->first_level; level <= mt->last_level; level++) {
+ depth = pt->depth[0];
+ for (level = pt->first_level; level <= pt->last_level; level++) {
unsigned i;
for (i = 0; i < depth; i++)
- i915_miptree_set_image_offset(mt, level, i,
+ i915_miptree_set_image_offset(tex, level, i,
0, i * stack_height);
depth = minify(depth);
@@ -266,29 +273,29 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
- mt->total_height = stack_height * mt->depth0;
+ tex->total_height = stack_height * pt->depth[0];
break;
}
default:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
unsigned img_height;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ tex->total_height = 0;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_level_info(mt, level, 1,
- 0, mt->total_height,
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 1,
+ 0, tex->total_height,
width, height, 1);
- if (mt->compressed)
+ if (pt->compressed)
img_height = MAX2(1, height / 4);
else
img_height = (MAX2(2, height) + 1) & ~1;
- mt->total_height += img_height;
+ tex->total_height += img_height;
width = minify(width);
height = minify(height);
@@ -298,24 +305,25 @@ i915_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
}
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
+ tex->pitch,
+ tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
*/
return TRUE;
}
-boolean
-i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+static boolean
+i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
{
+ struct pipe_texture *pt = &tex->base;
unsigned level;
- switch (mt->target) {
+ switch (pt->target) {
case PIPE_TEXTURE_CUBE:{
- const unsigned dim = mt->width0;
+ const unsigned dim = pt->width[0];
unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
assert(lvlWidth == lvlHeight); /* cubemap images are square */
@@ -324,16 +332,16 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32)
- mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
+ tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
else
- mt->pitch = 14 * 8;
+ tex->pitch = 14 * 8;
- mt->total_height = dim * 4 + 4;
+ tex->total_height = dim * 4 + 4;
/* Set all the levels to effectively occupy the whole rectangular region.
*/
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_level_info(mt, level, 6,
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 6,
0, 0,
lvlWidth, lvlHeight, 1);
lvlWidth /= 2;
@@ -347,16 +355,16 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
unsigned d = dim;
if (dim == 4 && face >= 4) {
- y = mt->total_height - 4;
+ y = tex->total_height - 4;
x = (face - 4) * 8;
}
- else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
- y = mt->total_height - 4;
+ else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+ y = tex->total_height - 4;
x = face * 8;
}
- for (level = mt->first_level; level <= mt->last_level; level++) {
- i915_miptree_set_image_offset(mt, level, face, x, y);
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ i915_miptree_set_image_offset(tex, level, face, x, y);
d >>= 1;
@@ -375,13 +383,13 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
break;
case PIPE_TEX_FACE_POS_Z:
case PIPE_TEX_FACE_NEG_Z:
- y = mt->total_height - 4;
+ y = tex->total_height - 4;
x = (face - 4) * 8;
break;
}
case 2:
- y = mt->total_height - 4;
+ y = tex->total_height - 4;
x = 16 + face * 8;
break;
@@ -399,33 +407,33 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
break;
}
case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
+ tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ tex->total_height = 0;
- pack_y_pitch = MAX2(mt->height0, 2);
- pack_x_pitch = mt->pitch;
+ pack_y_pitch = MAX2(pt->height[0], 2);
+ pack_x_pitch = tex->pitch;
pack_x_nr = 1;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6;
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0;
int y = 0;
unsigned q, j;
- i915_miptree_set_level_info(mt, level, nr_images,
- 0, mt->total_height,
+ i915_miptree_set_level_info(tex, level, nr_images,
+ 0, tex->total_height,
width, height, depth);
for (q = 0; q < nr_images;) {
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
- i915_miptree_set_image_offset(mt, level, q, x, y);
+ i915_miptree_set_image_offset(tex, level, q, x, y);
x += pack_x_pitch;
}
@@ -434,12 +442,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
}
- mt->total_height += y;
+ tex->total_height += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->pitch);
+ assert(pack_x_pitch * pack_x_nr <= tex->pitch);
}
if (pack_y_pitch > 2) {
@@ -456,7 +464,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
// case PIPE_TEXTURE_RECTANGLE:
- i945_miptree_layout_2d(mt);
+ i945_miptree_layout_2d(tex);
break;
default:
assert(0);
@@ -465,10 +473,67 @@ i945_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
+ tex->pitch,
+ tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
*/
return TRUE;
}
+void
+i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ struct i915_texture *tex = REALLOC(*pt, sizeof(struct pipe_texture),
+ sizeof(struct i915_texture));
+
+ if (tex) {
+ struct i915_context *i915 = i915_context(pipe);
+
+ memset(&tex->base + 1, 0,
+ sizeof(struct i915_texture) - sizeof(struct pipe_texture));
+
+ if (i915->flags.is_i945 ? i945_miptree_layout(pipe, tex) :
+ i915_miptree_layout(pipe, tex)) {
+ tex->region = pipe->winsys->region_alloc(pipe->winsys,
+ tex->pitch * tex->base.cpp *
+ tex->total_height,
+ PIPE_SURFACE_FLAG_TEXTURE);
+ }
+
+ if (!tex->region) {
+ FREE(tex);
+ tex = NULL;
+ }
+ }
+
+ *pt = &tex->base;
+}
+
+void
+i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ if (!*pt)
+ return;
+
+ /*
+ DBG("%s %p refcount will be %d\n",
+ __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
+ */
+ if (--(*pt)->refcount <= 0) {
+ struct i915_texture *tex = (struct i915_texture *)*pt;
+ uint i;
+
+ /*
+ DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
+ */
+
+ pipe->winsys->region_release(pipe->winsys, &tex->region);
+
+ for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ if (tex->image_offset[i])
+ free(tex->image_offset[i]);
+
+ free(tex);
+ }
+ *pt = NULL;
+}
diff --git a/src/mesa/pipe/i915simple/i915_texture.h b/src/mesa/pipe/i915simple/i915_texture.h
new file mode 100644
index 00000000000..84a0502e81a
--- /dev/null
+++ b/src/mesa/pipe/i915simple/i915_texture.h
@@ -0,0 +1,16 @@
+
+#ifndef I915_TEXTURE_H
+#define I915_TEXTURE_H
+
+struct pipe_context;
+struct pipe_texture;
+
+
+extern void
+i915_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
+
+extern void
+i915_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+
+
+#endif /* I915_TEXTURE_H */
diff --git a/src/mesa/pipe/llvm/llvm_entry.c b/src/mesa/pipe/llvm/llvm_entry.c
index 2459d14cb82..fe32e7810dc 100644
--- a/src/mesa/pipe/llvm/llvm_entry.c
+++ b/src/mesa/pipe/llvm/llvm_entry.c
@@ -194,7 +194,6 @@ void run_vertex_shader(float (*ainputs)[16][4],
struct pipe_sampler_state;
-struct pipe_mipmap_tree;
struct softpipe_tile_cache;
#define NUM_CHANNELS 4 /* R,G,B,A */
@@ -203,7 +202,6 @@ struct softpipe_tile_cache;
struct tgsi_sampler
{
const struct pipe_sampler_state *state;
- struct pipe_mipmap_tree *texture;
/** Get samples for four fragments in a quad */
void (*get_samples)(struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
index e145b22f2ff..5033209323f 100644
--- a/src/mesa/pipe/p_context.h
+++ b/src/mesa/pipe/p_context.h
@@ -155,7 +155,7 @@ struct pipe_context {
void (*set_texture_state)( struct pipe_context *,
unsigned unit,
- struct pipe_mipmap_tree * );
+ struct pipe_texture * );
void (*set_viewport_state)( struct pipe_context *,
const struct pipe_viewport_state * );
@@ -180,7 +180,7 @@ struct pipe_context {
/** Get a surface which is a "view" into a texture */
struct pipe_surface *(*get_tex_surface)(struct pipe_context *pipe,
- struct pipe_mipmap_tree *texture,
+ struct pipe_texture *texture,
unsigned face, unsigned level,
unsigned zslice);
@@ -237,8 +237,11 @@ struct pipe_context {
/*
* Texture functions
*/
- boolean (*mipmap_tree_layout)( struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt );
+ void (*texture_create)(struct pipe_context *pipe,
+ struct pipe_texture **pt);
+
+ void (*texture_release)(struct pipe_context *pipe,
+ struct pipe_texture **pt);
/* Flush rendering:
diff --git a/src/mesa/pipe/p_inlines.h b/src/mesa/pipe/p_inlines.h
index 2418d016e15..c04d46dddd8 100644
--- a/src/mesa/pipe/p_inlines.h
+++ b/src/mesa/pipe/p_inlines.h
@@ -80,4 +80,24 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
}
}
+
+/**
+ * \sa pipe_region_reference
+ */
+static INLINE void
+pipe_texture_reference(struct pipe_context *pipe, struct pipe_texture **ptr,
+ struct pipe_texture *pt)
+{
+ assert(ptr);
+ if (*ptr) {
+ pipe->texture_release(pipe, ptr);
+ assert(!*ptr);
+ }
+ if (pt) {
+ /* reference the new thing */
+ pt->refcount++;
+ *ptr = pt;
+ }
+}
+
#endif /* P_INLINES_H */
diff --git a/src/mesa/pipe/p_state.h b/src/mesa/pipe/p_state.h
index 642734aeb80..077a8f5a06f 100644
--- a/src/mesa/pipe/p_state.h
+++ b/src/mesa/pipe/p_state.h
@@ -288,27 +288,11 @@ struct pipe_surface
/**
- * Describes the location of each texture image within a texture region.
+ * Texture. Represents one or several texture images on one or several mipmap
+ * levels.
*/
-struct pipe_mipmap_level
-{
- unsigned level_offset;
- unsigned width;
- unsigned height;
- unsigned depth;
- unsigned nr_images;
-
- /* Explicitly store the offset of each image for each cube face or
- * depth value. Pretty much have to accept that hardware formats
- * are going to be so diverse that there is no unified way to
- * compute the offsets of depth/cube images within a mipmap level,
- * so have to store them as a lookup table:
- */
- unsigned *image_offset; /**< array [depth] of offsets */
-};
-
-struct pipe_mipmap_tree
-{
+struct pipe_texture
+{
/* Effectively the key:
*/
unsigned target; /* XXX convert to PIPE_TEXTURE_x */
@@ -318,25 +302,13 @@ struct pipe_mipmap_tree
unsigned first_level;
unsigned last_level;
- unsigned width0, height0, depth0; /**< Level zero image dimensions */
+ unsigned width[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned height[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned depth[PIPE_MAX_TEXTURE_LEVELS];
unsigned cpp;
unsigned compressed:1;
- /* Derived from the above:
- */
- unsigned pitch;
- unsigned depth_pitch; /* per-image on i945? */
- unsigned total_height;
-
- /* Includes image offset tables:
- */
- struct pipe_mipmap_level level[PIPE_MAX_TEXTURE_LEVELS];
-
- /* The data is held here:
- */
- struct pipe_region *region;
-
/* These are also refcounted:
*/
unsigned refcount;
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile
index 59628531cc8..9978884c9bd 100644
--- a/src/mesa/pipe/softpipe/Makefile
+++ b/src/mesa/pipe/softpipe/Makefile
@@ -34,7 +34,7 @@ DRIVER_SOURCES = \
sp_state_rasterizer.c \
sp_state_surface.c \
sp_state_vertex.c \
- sp_tex_layout.c \
+ sp_texture.c \
sp_tex_sample.c \
sp_tile_cache.c \
sp_surface.c
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index d5e68c189de..7a9fccce9ae 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -40,7 +40,7 @@
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
-#include "sp_tex_layout.h"
+#include "sp_texture.h"
#include "sp_winsys.h"
@@ -98,9 +98,9 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp)
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_mipmap_tree *mt = sp->texture[i];
- if (mt) {
- pipe->region_map(pipe, mt->region);
+ struct softpipe_texture *spt = sp->texture[i];
+ if (spt) {
+ pipe->region_map(pipe, spt->region);
}
}
}
@@ -146,9 +146,9 @@ softpipe_unmap_texture_surfaces(struct softpipe_context *sp)
struct pipe_context *pipe = &sp->pipe;
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_mipmap_tree *mt = sp->texture[i];
- if (mt) {
- pipe->region_unmap(pipe, mt->region);
+ struct softpipe_texture *spt = sp->texture[i];
+ if (spt) {
+ pipe->region_unmap(pipe, spt->region);
}
}
}
@@ -351,7 +351,8 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
softpipe->pipe.get_vendor = softpipe_get_vendor;
/* textures */
- softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout;
+ softpipe->pipe.texture_create = softpipe_texture_create;
+ softpipe->pipe.texture_release = softpipe_texture_release;
softpipe->pipe.get_tex_surface = softpipe_get_tex_surface;
/*
diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h
index 872766101d5..d4763a98c66 100644
--- a/src/mesa/pipe/softpipe/sp_context.h
+++ b/src/mesa/pipe/softpipe/sp_context.h
@@ -89,7 +89,7 @@ struct softpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
+ struct softpipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c
index 24c8a44c479..7184fcda521 100644
--- a/src/mesa/pipe/softpipe/sp_quad_fs.c
+++ b/src/mesa/pipe/softpipe/sp_quad_fs.c
@@ -277,7 +277,7 @@ static void shade_begin(struct quad_stage *qs)
/* set TGSI sampler state that varies */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
qss->samplers[i].state = softpipe->sampler[i];
- qss->samplers[i].texture = softpipe->texture[i];
+ qss->samplers[i].texture = &softpipe->texture[i]->base;
}
#ifdef MESA_LLVM
diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h
index 2f096a9cc97..a543735b525 100644
--- a/src/mesa/pipe/softpipe/sp_state.h
+++ b/src/mesa/pipe/softpipe/sp_state.h
@@ -52,6 +52,35 @@ struct sp_fragment_shader_state {
#endif
};
+struct softpipe_texture
+{
+ struct pipe_texture base;
+
+ /* Derived from the above:
+ */
+ unsigned pitch;
+ unsigned depth_pitch; /* per-image on i945? */
+ unsigned total_height;
+
+ unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* Explicitly store the offset of each image for each cube face or
+ * depth value. Pretty much have to accept that hardware formats
+ * are going to be so diverse that there is no unified way to
+ * compute the offsets of depth/cube images within a mipmap level,
+ * so have to store them as a lookup table:
+ */
+ unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+
+ /* Includes image offset tables:
+ */
+ unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+
+ /* The data is held here:
+ */
+ struct pipe_region *region;
+};
+
void *
softpipe_create_alpha_test_state(struct pipe_context *,
const struct pipe_alpha_test_state *);
@@ -125,7 +154,7 @@ void softpipe_set_scissor_state( struct pipe_context *,
void softpipe_set_texture_state( struct pipe_context *,
unsigned unit,
- struct pipe_mipmap_tree * );
+ struct pipe_texture * );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c
index 912f42d5688..a360b4f02b0 100644
--- a/src/mesa/pipe/softpipe/sp_state_fs.c
+++ b/src/mesa/pipe/softpipe/sp_state_fs.c
@@ -34,6 +34,8 @@
#include "pipe/draw/draw_context.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/llvm/gallivm.h"
+#include "pipe/tgsi/util/tgsi_dump.h"
+#include "pipe/tgsi/exec/tgsi_sse2.h"
void * softpipe_create_fs_state(struct pipe_context *pipe,
diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c
index 246a7d6eda7..e71b9159e3f 100644
--- a/src/mesa/pipe/softpipe/sp_state_sampler.c
+++ b/src/mesa/pipe/softpipe/sp_state_sampler.c
@@ -68,12 +68,12 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
void
softpipe_set_texture_state(struct pipe_context *pipe,
unsigned unit,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
assert(unit < PIPE_MAX_SAMPLERS);
- softpipe->texture[unit] = texture; /* ptr, not struct */
+ softpipe->texture[unit] = (struct softpipe_texture *)texture; /* ptr, not struct */
sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture);
diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c
index a6ab4046037..c41bbc59b90 100644
--- a/src/mesa/pipe/softpipe/sp_surface.c
+++ b/src/mesa/pipe/softpipe/sp_surface.c
@@ -565,34 +565,35 @@ z24s8_get_tile(struct pipe_surface *ps,
*/
struct pipe_surface *
softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt,
+ struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
+ struct softpipe_texture *spt = (struct softpipe_texture *)pt;
struct pipe_surface *ps;
unsigned offset; /* in bytes */
- offset = mt->level[level].level_offset;
+ offset = spt->level_offset[level];
- if (mt->target == PIPE_TEXTURE_CUBE) {
- offset += mt->level[level].image_offset[face] * mt->cpp;
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ offset += spt->image_offset[level][face] * pt->cpp;
}
- else if (mt->target == PIPE_TEXTURE_3D) {
- offset += mt->level[level].image_offset[zslice] * mt->cpp;
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ offset += spt->image_offset[level][zslice] * pt->cpp;
}
else {
assert(face == 0);
assert(zslice == 0);
}
- ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format);
+ ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format);
if (ps) {
assert(ps->format);
assert(ps->refcount);
- pipe_region_reference(&ps->region, mt->region);
- ps->cpp = mt->cpp;
- ps->width = mt->level[level].width;
- ps->height = mt->level[level].height;
- ps->pitch = mt->pitch;
+ pipe_region_reference(&ps->region, spt->region);
+ ps->cpp = pt->cpp;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->pitch = spt->pitch;
ps->offset = offset;
}
return ps;
diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h
index cf87e1a92ce..b652e7598e8 100644
--- a/src/mesa/pipe/softpipe/sp_surface.h
+++ b/src/mesa/pipe/softpipe/sp_surface.h
@@ -41,7 +41,7 @@ struct softpipe_tile_cache;
extern struct pipe_surface *
softpipe_get_tex_surface(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt,
+ struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice);
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.h b/src/mesa/pipe/softpipe/sp_tex_layout.h
deleted file mode 100644
index ea19c13b23f..00000000000
--- a/src/mesa/pipe/softpipe/sp_tex_layout.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef SP_TEX_LAYOUT_H
-#define SP_TEX_LAYOUT_H
-
-
-struct pipe_context;
-struct pipe_mipmap_tree;
-
-
-extern boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe,
- struct pipe_mipmap_tree *mt);
-
-
-#endif /* SP_TEX_LAYOUT_H */
-
-
diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c
index 92958400fc5..9e48ed0cd2c 100644
--- a/src/mesa/pipe/softpipe/sp_tex_sample.c
+++ b/src/mesa/pipe/softpipe/sp_tex_sample.c
@@ -422,7 +422,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dsdy = FABSF(dsdy);
rho = MAX2(dsdx, dsdy);
if (sampler->state->normalized_coords)
- rho *= sampler->texture->width0;
+ rho *= sampler->texture->width[0];
}
if (t) {
float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
@@ -432,7 +432,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dtdy = FABSF(dtdy);
max = MAX2(dtdx, dtdy);
if (sampler->state->normalized_coords)
- max *= sampler->texture->height0;
+ max *= sampler->texture->height[0];
rho = MAX2(rho, max);
}
if (p) {
@@ -443,7 +443,7 @@ compute_lambda(struct tgsi_sampler *sampler,
dpdy = FABSF(dpdy);
max = MAX2(dpdx, dpdy);
if (sampler->state->normalized_coords)
- max *= sampler->texture->depth0;
+ max *= sampler->texture->depth[0];
rho = MAX2(rho, max);
}
@@ -620,8 +620,8 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler,
&level0, &level1, &levelBlend, &imgFilter);
if (sampler->state->normalized_coords) {
- width = sampler->texture->level[level0].width;
- height = sampler->texture->level[level0].height;
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
}
else {
width = height = 1;
@@ -757,9 +757,9 @@ sp_get_samples_3d(struct tgsi_sampler *sampler,
&level0, &level1, &levelBlend, &imgFilter);
if (sampler->state->normalized_coords) {
- width = sampler->texture->level[level0].width;
- height = sampler->texture->level[level0].height;
- depth = sampler->texture->level[level0].depth;
+ width = sampler->texture->width[level0];
+ height = sampler->texture->height[level0];
+ depth = sampler->texture->depth[level0];
}
else {
width = height = depth = 1;
@@ -883,7 +883,7 @@ sp_get_samples_cube(struct tgsi_sampler *sampler,
/**
* Called via tgsi_sampler::get_samples()
* Use the sampler's state setting to get a filtered RGBA value
- * from the sampler's texture (mipmap tree).
+ * from the sampler's texture.
*
* XXX we can implement many versions of this function, each
* tightly coded for a specific combination of sampler state
diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.c b/src/mesa/pipe/softpipe/sp_texture.c
index 8156b00301f..2f9a1e9837b 100644
--- a/src/mesa/pipe/softpipe/sp_tex_layout.c
+++ b/src/mesa/pipe/softpipe/sp_texture.c
@@ -33,7 +33,11 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
-#include "sp_tex_layout.h"
+#include "pipe/p_winsys.h"
+
+#include "sp_context.h"
+#include "sp_state.h"
+#include "sp_texture.h"
/* At the moment, just make softpipe use the same layout for its
@@ -54,100 +58,105 @@ static int align(int value, int alignment)
static void
-sp_miptree_set_level_info(struct pipe_mipmap_tree *mt,
- unsigned level,
- unsigned nr_images,
- unsigned x, unsigned y, unsigned w, unsigned h, unsigned d)
+sp_miptree_set_level_info(struct softpipe_texture *spt,
+ unsigned level,
+ unsigned nr_images,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ unsigned d)
{
+ struct pipe_texture *pt = &spt->base;
+
assert(level < PIPE_MAX_TEXTURE_LEVELS);
- mt->level[level].width = w;
- mt->level[level].height = h;
- mt->level[level].depth = d;
- mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp;
- mt->level[level].nr_images = nr_images;
+ pt->width[level] = w;
+ pt->height[level] = h;
+ pt->depth[level] = d;
+
+ spt->nr_images[level] = nr_images;
+ spt->level_offset[level] = (x + y * spt->pitch) * pt->cpp;
/*
DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
- level, w, h, d, x, y, mt->level[level].level_offset);
+ level, w, h, d, x, y, spt->level_offset[level]);
*/
/* Not sure when this would happen, but anyway:
*/
- if (mt->level[level].image_offset) {
- FREE( mt->level[level].image_offset );
- mt->level[level].image_offset = NULL;
+ if (spt->image_offset[level]) {
+ FREE( spt->image_offset[level] );
+ spt->image_offset[level] = NULL;
}
assert(nr_images);
- assert(!mt->level[level].image_offset);
+ assert(!spt->image_offset[level]);
- mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
- mt->level[level].image_offset[0] = 0;
+ spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) );
+ spt->image_offset[level][0] = 0;
}
static void
-sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt,
- unsigned level, unsigned img, unsigned x, unsigned y)
+sp_miptree_set_image_offset(struct softpipe_texture *spt,
+ unsigned level, unsigned img, unsigned x, unsigned y)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
- assert(img < mt->level[level].nr_images);
+ assert(img < spt->nr_images[level]);
- mt->level[level].image_offset[img] = (x + y * mt->pitch);
+ spt->image_offset[level][img] = (x + y * spt->pitch);
/*
DBG("%s level %d img %d pos %d,%d image_offset %x\n",
- __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
+ __FUNCTION__, level, img, x, y, spt->image_offset[level][img]);
*/
}
static void
-sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
+sp_miptree_layout_2d( struct softpipe_texture *spt )
{
+ struct pipe_texture *pt = &spt->base;
int align_h = 2, align_w = 4;
unsigned level;
unsigned x = 0;
unsigned y = 0;
- unsigned width = mt->width0;
- unsigned height = mt->height0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
- mt->pitch = mt->width0;
+ spt->pitch = pt->width[0];
/* XXX FIX THIS:
* we use alignment=64 bytes in sp_region_alloc(). If we change
* that, change this too.
*/
- if (mt->pitch < 16)
- mt->pitch = 16;
+ if (spt->pitch < 16)
+ spt->pitch = 16;
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap. This occurs when the alignment
* constraints of mipmap placement push the right edge of the
* 2nd mipmap out past the width of its parent.
*/
- if (mt->first_level != mt->last_level) {
- unsigned mip1_width = align(minify(mt->width0), align_w)
- + minify(minify(mt->width0));
+ if (pt->first_level != pt->last_level) {
+ unsigned mip1_width = align(minify(pt->width[0]), align_w)
+ + minify(minify(pt->width[0]));
- if (mip1_width > mt->width0)
- mt->pitch = mip1_width;
+ if (mip1_width > pt->width[0])
+ spt->pitch = mip1_width;
}
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
- mt->total_height = 0;
+ spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp;
+ spt->total_height = 0;
- for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+ for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
unsigned img_height;
- sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1);
+ sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1);
- if (mt->compressed)
+ if (pt->compressed)
img_height = MAX2(1, height/4);
else
img_height = align(height, align_h);
@@ -156,11 +165,11 @@ sp_miptree_layout_2d( struct pipe_mipmap_tree *mt )
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
- mt->total_height = MAX2(mt->total_height, y + img_height);
+ spt->total_height = MAX2(spt->total_height, y + img_height);
/* Layout_below: step right after second mipmap.
*/
- if (level == mt->first_level + 1) {
+ if (level == pt->first_level + 1) {
x += align(width, align_w);
}
else {
@@ -193,16 +202,17 @@ static const int step_offsets[6][2] = {
-boolean
-softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt)
+static boolean
+softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt)
{
+ struct pipe_texture *pt = &spt->base;
unsigned level;
- switch (mt->target) {
+ switch (pt->target) {
case PIPE_TEXTURE_CUBE:{
- const unsigned dim = mt->width0;
+ const unsigned dim = pt->width[0];
unsigned face;
- unsigned lvlWidth = mt->width0, lvlHeight = mt->height0;
+ unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
assert(lvlWidth == lvlHeight); /* cubemap images are square */
@@ -211,16 +221,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (dim > 32)
- mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
+ spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
else
- mt->pitch = 14 * 8;
+ spt->pitch = 14 * 8;
- mt->total_height = dim * 4 + 4;
+ spt->total_height = dim * 4 + 4;
/* Set all the levels to effectively occupy the whole rectangular region.
*/
- for (level = mt->first_level; level <= mt->last_level; level++) {
- sp_miptree_set_level_info(mt, level, 6,
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ sp_miptree_set_level_info(spt, level, 6,
0, 0,
lvlWidth, lvlHeight, 1);
lvlWidth /= 2;
@@ -234,16 +244,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
unsigned d = dim;
if (dim == 4 && face >= 4) {
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = (face - 4) * 8;
}
- else if (dim < 4 && (face > 0 || mt->first_level > 0)) {
- y = mt->total_height - 4;
+ else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
+ y = spt->total_height - 4;
x = face * 8;
}
- for (level = mt->first_level; level <= mt->last_level; level++) {
- sp_miptree_set_image_offset(mt, level, face, x, y);
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ sp_miptree_set_image_offset(spt, level, face, x, y);
d >>= 1;
@@ -262,13 +272,13 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
break;
case PIPE_TEX_FACE_POS_Z:
case PIPE_TEX_FACE_NEG_Z:
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = (face - 4) * 8;
break;
}
case 2:
- y = mt->total_height - 4;
+ y = spt->total_height - 4;
x = 16 + face * 8;
break;
@@ -286,33 +296,33 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
break;
}
case PIPE_TEXTURE_3D:{
- unsigned width = mt->width0;
- unsigned height = mt->height0;
- unsigned depth = mt->depth0;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
- mt->total_height = 0;
+ spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ spt->total_height = 0;
- pack_y_pitch = MAX2(mt->height0, 2);
- pack_x_pitch = mt->pitch;
+ pack_y_pitch = MAX2(pt->height[0], 2);
+ pack_x_pitch = spt->pitch;
pack_x_nr = 1;
- for (level = mt->first_level; level <= mt->last_level; level++) {
- unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6;
+ for (level = pt->first_level; level <= pt->last_level; level++) {
+ unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
int x = 0;
int y = 0;
unsigned q, j;
- sp_miptree_set_level_info(mt, level, nr_images,
- 0, mt->total_height,
- width, height, depth);
+ sp_miptree_set_level_info(spt, level, nr_images,
+ 0, spt->total_height,
+ width, height, depth);
for (q = 0; q < nr_images;) {
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
- sp_miptree_set_image_offset(mt, level, q, x, y);
+ sp_miptree_set_image_offset(spt, level, q, x, y);
x += pack_x_pitch;
}
@@ -321,12 +331,12 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
}
- mt->total_height += y;
+ spt->total_height += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= mt->pitch);
+ assert(pack_x_pitch * pack_x_nr <= spt->pitch);
}
if (pack_y_pitch > 2) {
@@ -343,7 +353,7 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
// case PIPE_TEXTURE_RECTANGLE:
- sp_miptree_layout_2d(mt);
+ sp_miptree_layout_2d(spt);
break;
default:
assert(0);
@@ -352,10 +362,64 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- mt->pitch,
- mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp);
+ spt->pitch,
+ spt->total_height, pt->cpp, spt->pitch * spt->total_height * pt->cpp);
*/
return TRUE;
}
+void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ struct softpipe_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture),
+ sizeof(struct softpipe_texture));
+
+ if (spt) {
+ memset(&spt->base + 1, 0,
+ sizeof(struct softpipe_texture) - sizeof(struct pipe_texture));
+
+ if (softpipe_mipmap_tree_layout(pipe, spt)) {
+ spt->region = pipe->winsys->region_alloc(pipe->winsys,
+ spt->pitch * (*pt)->cpp *
+ spt->total_height,
+ PIPE_SURFACE_FLAG_TEXTURE);
+ }
+
+ if (!spt->region) {
+ FREE(spt);
+ spt = NULL;
+ }
+ }
+
+ *pt = &spt->base;
+}
+
+void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt)
+{
+ if (!*pt)
+ return;
+
+ /*
+ DBG("%s %p refcount will be %d\n",
+ __FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
+ */
+ if (--(*pt)->refcount <= 0) {
+ struct softpipe_texture *spt = (struct softpipe_texture *)*pt;
+ uint i;
+
+ /*
+ DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
+ */
+
+ pipe->winsys->region_release(pipe->winsys, &spt->region);
+
+ for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ if (spt->image_offset[i])
+ free(spt->image_offset[i]);
+
+ free(spt);
+ }
+ *pt = NULL;
+}
diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h
new file mode 100644
index 00000000000..2aca57bd1d2
--- /dev/null
+++ b/src/mesa/pipe/softpipe/sp_texture.h
@@ -0,0 +1,18 @@
+#ifndef SP_TEXTURE_H
+#define SP_TEXTURE_H
+
+
+struct pipe_context;
+struct pipe_texture;
+
+
+extern void
+softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt);
+
+extern void
+softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt);
+
+
+#endif /* SP_TEXTURE */
+
+
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c
index ea0c8b8f91d..62ee6a27c93 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.c
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.c
@@ -51,7 +51,7 @@
struct softpipe_tile_cache
{
struct pipe_surface *surface; /**< the surface we're caching */
- struct pipe_mipmap_tree *texture; /**< if caching a texture */
+ struct pipe_texture *texture; /**< if caching a texture */
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
float clear_value[4];
@@ -139,7 +139,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
- struct pipe_mipmap_tree *texture)
+ struct pipe_texture *texture)
{
uint i;
diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h
index e66fec2e208..9967aa5044a 100644
--- a/src/mesa/pipe/softpipe/sp_tile_cache.h
+++ b/src/mesa/pipe/softpipe/sp_tile_cache.h
@@ -71,7 +71,7 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
extern void
sp_tile_cache_set_texture(struct softpipe_tile_cache *tc,
- struct pipe_mipmap_tree *texture);
+ struct pipe_texture *texture);
extern void
sp_flush_tile_cache(struct softpipe_context *softpipe,
diff --git a/src/mesa/pipe/tgsi/exec/tgsi_exec.h b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
index 1d497e97fb0..2c62b30f150 100644
--- a/src/mesa/pipe/tgsi/exec/tgsi_exec.h
+++ b/src/mesa/pipe/tgsi/exec/tgsi_exec.h
@@ -76,7 +76,7 @@ struct softpipe_tile_cache; /**< Opaque to TGSI */
struct tgsi_sampler
{
const struct pipe_sampler_state *state;
- struct pipe_mipmap_tree *texture;
+ struct pipe_texture *texture;
/** Get samples for four fragments in a quad */
void (*get_samples)(struct tgsi_sampler *sampler,
const float s[QUAD_SIZE],