mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
Hide texture layout details from the state tracker.
pipe->get_tex_surface() has to be used for access to texture image data.
This commit is contained in:
parent
5935626818
commit
753db0d840
42 changed files with 929 additions and 882 deletions
|
|
@ -328,8 +328,8 @@ intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
|
|||
if (!stObj)
|
||||
return;
|
||||
|
||||
if (stObj->mt)
|
||||
st_miptree_release(intel->st->pipe, &stObj->mt);
|
||||
if (stObj->pt)
|
||||
st->pipe->texture_release(intel->st->pipe, &stObj->pt);
|
||||
|
||||
stObj->imageOverride = GL_TRUE;
|
||||
stObj->depthOverride = depth;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
}
|
||||
16
src/mesa/pipe/i915simple/i915_texture.h
Normal file
16
src/mesa/pipe/i915simple/i915_texture.h
Normal file
|
|
@ -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 */
|
||||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 * );
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
18
src/mesa/pipe/softpipe/sp_texture.h
Normal file
18
src/mesa/pipe/softpipe/sp_texture.h
Normal file
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ STATETRACKER_SOURCES = \
|
|||
state_tracker/st_framebuffer.c \
|
||||
state_tracker/st_mesa_to_tgsi.c \
|
||||
state_tracker/st_program.c \
|
||||
state_tracker/st_mipmap_tree.c
|
||||
state_tracker/st_texture.c
|
||||
|
||||
SHADER_SOURCES = \
|
||||
shader/arbprogparse.c \
|
||||
|
|
|
|||
|
|
@ -51,24 +51,24 @@ update_textures(struct st_context *st)
|
|||
for (u = 0; u < st->ctx->Const.MaxTextureImageUnits; u++) {
|
||||
struct gl_texture_object *texObj
|
||||
= st->ctx->Texture.Unit[u]._Current;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
if (texObj) {
|
||||
GLboolean flush, retval;
|
||||
|
||||
retval = st_finalize_mipmap_tree(st->ctx, st->pipe, u, &flush);
|
||||
retval = st_finalize_texture(st->ctx, st->pipe, u, &flush);
|
||||
#if 0
|
||||
printf("finalize_mipmap_tree returned %d, flush = %d\n",
|
||||
printf("finalize_texture returned %d, flush = %d\n",
|
||||
retval, flush);
|
||||
#endif
|
||||
|
||||
mt = st_get_texobj_mipmap_tree(texObj);
|
||||
pt = st_get_texobj_texture(texObj);
|
||||
}
|
||||
else {
|
||||
mt = NULL;
|
||||
pt = NULL;
|
||||
}
|
||||
|
||||
st->state.texture[u] = mt;
|
||||
st->pipe->set_texture_state(st->pipe, u, mt);
|
||||
st->state.texture[u] = pt;
|
||||
st->pipe->set_texture_state(st->pipe, u, pt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "main/imports.h"
|
||||
#include "main/image.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/texformat.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
|
@ -50,6 +51,7 @@
|
|||
#include "st_draw.h"
|
||||
#include "st_format.h"
|
||||
#include "st_mesa_to_tgsi.h"
|
||||
#include "st_texture.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
|
|
@ -440,63 +442,20 @@ _mesa_base_format(GLenum format)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static struct pipe_mipmap_tree *
|
||||
alloc_mipmap_tree(struct st_context *st,
|
||||
GLsizei width, GLsizei height, uint pipeFormat)
|
||||
{
|
||||
const GLbitfield flags = PIPE_SURFACE_FLAG_TEXTURE;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
GLuint cpp;
|
||||
|
||||
mt = CALLOC_STRUCT(pipe_mipmap_tree);
|
||||
if (!mt)
|
||||
return NULL;
|
||||
|
||||
cpp = st_sizeof_format(pipeFormat);
|
||||
|
||||
mt->target = PIPE_TEXTURE_2D;
|
||||
mt->internal_format = GL_RGBA;
|
||||
mt->format = pipeFormat;
|
||||
mt->first_level = 0;
|
||||
mt->last_level = 0;
|
||||
mt->width0 = width;
|
||||
mt->height0 = height;
|
||||
mt->depth0 = 1;
|
||||
mt->cpp = cpp;
|
||||
mt->compressed = 0;
|
||||
mt->pitch = st->pipe->winsys->surface_pitch(st->pipe->winsys, cpp, width,
|
||||
flags);
|
||||
mt->region = st->pipe->winsys->region_alloc(st->pipe->winsys,
|
||||
mt->pitch * cpp * height, flags);
|
||||
mt->depth_pitch = 0;
|
||||
mt->total_height = height;
|
||||
mt->level[0].level_offset = 0;
|
||||
mt->level[0].width = width;
|
||||
mt->level[0].height = height;
|
||||
mt->level[0].depth = 1;
|
||||
mt->level[0].nr_images = 1;
|
||||
mt->level[0].image_offset = NULL;
|
||||
mt->refcount = 1;
|
||||
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make mipmap tree containing an image for glDrawPixels image.
|
||||
* Make texture containing an image for glDrawPixels image.
|
||||
* If 'pixels' is NULL, leave the texture image data undefined.
|
||||
*/
|
||||
static struct pipe_mipmap_tree *
|
||||
make_mipmap_tree(struct st_context *st,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels)
|
||||
static struct pipe_texture *
|
||||
make_texture(struct st_context *st,
|
||||
GLsizei width, GLsizei height, GLenum format, GLenum type,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLvoid *pixels)
|
||||
{
|
||||
GLcontext *ctx = st->ctx;
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
const struct gl_texture_format *mformat;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
GLuint pipeFormat, cpp;
|
||||
GLenum baseFormat;
|
||||
|
||||
|
|
@ -509,29 +468,33 @@ make_mipmap_tree(struct st_context *st,
|
|||
assert(pipeFormat);
|
||||
cpp = st_sizeof_format(pipeFormat);
|
||||
|
||||
mt = alloc_mipmap_tree(st, width, height, pipeFormat);
|
||||
if (!mt)
|
||||
pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, baseFormat, 0, 0,
|
||||
width, height, 1, 0);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
|
||||
if (unpack->BufferObj && unpack->BufferObj->Name) {
|
||||
/*
|
||||
mt->region = buffer_object_region(unpack->BufferObj);
|
||||
pt->region = buffer_object_region(unpack->BufferObj);
|
||||
*/
|
||||
printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
|
||||
}
|
||||
|
||||
{
|
||||
struct pipe_surface *surface;
|
||||
static const GLuint dstImageOffsets = 0;
|
||||
GLboolean success;
|
||||
GLuint pitch = mt->pitch;
|
||||
GLubyte *dest;
|
||||
const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
|
||||
|
||||
/* we'll do pixel transfer in a fragment shader */
|
||||
ctx->_ImageTransferState = 0x0;
|
||||
|
||||
surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
|
||||
|
||||
/* map texture region */
|
||||
dest = pipe->region_map(pipe, mt->region);
|
||||
(void) pipe->region_map(pipe, surface->region);
|
||||
dest = surface->region->map + surface->offset;
|
||||
|
||||
/* Put image into texture region.
|
||||
* Note that the image is actually going to be upside down in
|
||||
|
|
@ -542,7 +505,7 @@ make_mipmap_tree(struct st_context *st,
|
|||
mformat, /* gl_texture_format */
|
||||
dest, /* dest */
|
||||
0, 0, 0, /* dstX/Y/Zoffset */
|
||||
pitch * cpp, /* dstRowStride, bytes */
|
||||
surface->pitch * cpp, /* dstRowStride, bytes */
|
||||
&dstImageOffsets, /* dstImageOffsets */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
|
|
@ -550,44 +513,15 @@ make_mipmap_tree(struct st_context *st,
|
|||
unpack);
|
||||
|
||||
/* unmap */
|
||||
pipe->region_unmap(pipe, mt->region);
|
||||
pipe->region_unmap(pipe, surface->region);
|
||||
pipe_surface_reference(&surface, NULL);
|
||||
assert(success);
|
||||
|
||||
/* restore */
|
||||
ctx->_ImageTransferState = imageTransferStateSave;
|
||||
}
|
||||
|
||||
#if 0
|
||||
mt->target = PIPE_TEXTURE_2D;
|
||||
mt->internal_format = GL_RGBA;
|
||||
mt->format = pipeFormat;
|
||||
mt->first_level = 0;
|
||||
mt->last_level = 0;
|
||||
mt->width0 = width;
|
||||
mt->height0 = height;
|
||||
mt->depth0 = 1;
|
||||
mt->cpp = cpp;
|
||||
mt->compressed = 0;
|
||||
mt->pitch = mt->pitch;
|
||||
mt->depth_pitch = 0;
|
||||
mt->total_height = height;
|
||||
mt->level[0].level_offset = 0;
|
||||
mt->level[0].width = width;
|
||||
mt->level[0].height = height;
|
||||
mt->level[0].depth = 1;
|
||||
mt->level[0].nr_images = 1;
|
||||
mt->level[0].image_offset = NULL;
|
||||
mt->refcount = 1;
|
||||
#endif
|
||||
return mt;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_mipmap_tree(struct pipe_context *pipe, struct pipe_mipmap_tree *mt)
|
||||
{
|
||||
pipe->winsys->region_release(pipe->winsys, &mt->region);
|
||||
free(mt);
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -693,7 +627,7 @@ static void
|
|||
draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||
GLsizei width, GLsizei height,
|
||||
GLfloat zoomX, GLfloat zoomY,
|
||||
struct pipe_mipmap_tree *mt,
|
||||
struct pipe_texture *pt,
|
||||
struct st_vertex_program *stvp,
|
||||
struct st_fragment_program *stfp,
|
||||
const GLfloat *color,
|
||||
|
|
@ -761,9 +695,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
|||
pipe->set_viewport_state(pipe, &vp);
|
||||
}
|
||||
|
||||
/* mipmap tree state: */
|
||||
/* texture state: */
|
||||
{
|
||||
pipe->set_texture_state(pipe, unit, mt);
|
||||
pipe->set_texture_state(pipe, unit, pt);
|
||||
}
|
||||
|
||||
/* Compute window coords (y=0=bottom) with pixel zoom.
|
||||
|
|
@ -1025,14 +959,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
any_pixel_transfer_ops(st) ||
|
||||
!compatible_formats(format, type, ps->format)) {
|
||||
/* textured quad */
|
||||
struct pipe_mipmap_tree *mt
|
||||
= make_mipmap_tree(ctx->st, width, height, format, type,
|
||||
unpack, pixels);
|
||||
if (mt) {
|
||||
struct pipe_texture *pt
|
||||
= make_texture(ctx->st, width, height, format, type, unpack, pixels);
|
||||
if (pt) {
|
||||
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
|
||||
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
||||
mt, stvp, stfp, color, GL_FALSE);
|
||||
free_mipmap_tree(st->pipe, mt);
|
||||
pt, stvp, stfp, color, GL_FALSE);
|
||||
st->pipe->texture_release(st->pipe, &pt);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -1046,26 +979,29 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
/**
|
||||
* Create a texture which represents a bitmap image.
|
||||
*/
|
||||
static struct pipe_mipmap_tree *
|
||||
static struct pipe_texture *
|
||||
make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
||||
const struct gl_pixelstore_attrib *unpack,
|
||||
const GLubyte *bitmap)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
const uint flags = PIPE_SURFACE_FLAG_TEXTURE;
|
||||
struct pipe_surface *surface;
|
||||
uint format = 0, cpp, comp;
|
||||
GLenum internal_format;
|
||||
ubyte *dest;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
int row, col;
|
||||
|
||||
/* find a texture format we know */
|
||||
if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_I8 )) {
|
||||
format = PIPE_FORMAT_U_I8;
|
||||
internal_format = GL_INTENSITY8;
|
||||
cpp = 1;
|
||||
comp = 0;
|
||||
}
|
||||
else if (pipe->is_format_supported( pipe, PIPE_FORMAT_U_A8_R8_G8_B8 )) {
|
||||
format = PIPE_FORMAT_U_A8_R8_G8_B8;
|
||||
internal_format = GL_RGBA8;
|
||||
cpp = 4;
|
||||
comp = 3; /* alpha channel */ /*XXX little-endian dependency */
|
||||
}
|
||||
|
|
@ -1075,31 +1011,25 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a mipmap tree.
|
||||
* Create a texture.
|
||||
*/
|
||||
mt = CALLOC_STRUCT(pipe_mipmap_tree);
|
||||
if (!mt)
|
||||
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, internal_format,
|
||||
0, 0, width, height, 1, 0);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
|
||||
if (unpack->BufferObj && unpack->BufferObj->Name) {
|
||||
/*
|
||||
mt->region = buffer_object_region(unpack->BufferObj);
|
||||
pt->region = buffer_object_region(unpack->BufferObj);
|
||||
*/
|
||||
printf("st_Bitmap (sourcing from PBO not implemented yet)\n");
|
||||
}
|
||||
|
||||
|
||||
/* allocate texture region/storage */
|
||||
mt->pitch = pipe->winsys->surface_pitch(pipe->winsys, cpp, width, flags);
|
||||
mt->region = pipe->winsys->region_alloc(pipe->winsys,
|
||||
mt->pitch * cpp * height, flags);
|
||||
surface = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
|
||||
|
||||
/* map texture region */
|
||||
dest = pipe->region_map(pipe, mt->region);
|
||||
if (!dest) {
|
||||
printf("st_Bitmap region_map() failed!?!");
|
||||
return NULL;
|
||||
}
|
||||
(void) pipe->region_map(pipe, surface->region);
|
||||
dest = surface->region->map + surface->offset;
|
||||
|
||||
/* Put image into texture region.
|
||||
* Note that the image is actually going to be upside down in
|
||||
|
|
@ -1109,7 +1039,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
|||
for (row = 0; row < height; row++) {
|
||||
const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
|
||||
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
|
||||
ubyte *destRow = dest + row * mt->pitch * cpp;
|
||||
ubyte *destRow = dest + row * surface->pitch * cpp;
|
||||
|
||||
if (unpack->LsbFirst) {
|
||||
/* Lsb first */
|
||||
|
|
@ -1158,30 +1088,13 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
|
|||
|
||||
} /* row */
|
||||
|
||||
/* unmap */
|
||||
pipe->region_unmap(pipe, mt->region);
|
||||
/* Release surface */
|
||||
pipe->region_unmap(pipe, surface->region);
|
||||
pipe_surface_reference(&surface, NULL);
|
||||
|
||||
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;
|
||||
pt->format = format;
|
||||
|
||||
return mt;
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1193,21 +1106,21 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
|||
struct st_fragment_program *stfp;
|
||||
struct st_vertex_program *stvp;
|
||||
struct st_context *st = ctx->st;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
|
||||
stvp = make_vertex_shader(ctx->st, GL_TRUE);
|
||||
stfp = combined_bitmap_fragment_program(ctx);
|
||||
|
||||
st_validate_state(st);
|
||||
|
||||
mt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
|
||||
if (mt) {
|
||||
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
|
||||
if (pt) {
|
||||
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
|
||||
width, height, 1.0, 1.0,
|
||||
mt, stvp, stfp,
|
||||
pt, stvp, stfp,
|
||||
ctx->Current.RasterColor, GL_FALSE);
|
||||
|
||||
free_mipmap_tree(st->pipe, mt);
|
||||
st->pipe->texture_release(st->pipe, &pt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1296,7 +1209,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
|||
struct st_fragment_program *stfp;
|
||||
struct pipe_surface *psRead;
|
||||
struct pipe_surface *psTex;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
GLfloat *color;
|
||||
uint format;
|
||||
|
||||
|
|
@ -1327,11 +1240,12 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
|||
psRead = rbRead->surface;
|
||||
format = psRead->format;
|
||||
|
||||
mt = alloc_mipmap_tree(ctx->st, width, height, format);
|
||||
if (!mt)
|
||||
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format,
|
||||
rbRead->Base.InternalFormat, 0, 0, width, height, 1, 0);
|
||||
if (!pt)
|
||||
return;
|
||||
|
||||
psTex = pipe->get_tex_surface(pipe, mt, 0, 0, 0);
|
||||
psTex = pipe->get_tex_surface(pipe, pt, 0, 0, 0);
|
||||
|
||||
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
|
||||
srcy = ctx->DrawBuffer->Height - srcy - height;
|
||||
|
|
@ -1368,10 +1282,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
|||
/* draw textured quad */
|
||||
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
|
||||
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
||||
mt, stvp, stfp, color, GL_TRUE);
|
||||
pt, stvp, stfp, color, GL_TRUE);
|
||||
|
||||
pipe_surface_reference(&psTex, NULL);
|
||||
free_mipmap_tree(st->pipe, mt);
|
||||
st->pipe->texture_release(st->pipe, &pt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ st_render_texture(GLcontext *ctx,
|
|||
struct st_renderbuffer *strb;
|
||||
struct gl_renderbuffer *rb;
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
|
||||
assert(!att->Renderbuffer);
|
||||
|
||||
|
|
@ -302,26 +302,26 @@ st_render_texture(GLcontext *ctx,
|
|||
rb->AllocStorage = NULL; /* should not get called */
|
||||
strb = st_renderbuffer(rb);
|
||||
|
||||
/* get the mipmap tree for the texture */
|
||||
mt = st_get_texobj_mipmap_tree(att->Texture);
|
||||
assert(mt);
|
||||
assert(mt->level[att->TextureLevel].width);
|
||||
/* get the texture for the texture object */
|
||||
pt = st_get_texobj_texture(att->Texture);
|
||||
assert(pt);
|
||||
assert(pt->width[att->TextureLevel]);
|
||||
|
||||
rb->Width = mt->level[att->TextureLevel].width;
|
||||
rb->Height = mt->level[att->TextureLevel].height;
|
||||
rb->Width = pt->width[att->TextureLevel];
|
||||
rb->Height = pt->height[att->TextureLevel];
|
||||
|
||||
/* the renderbuffer's surface is inside the mipmap_tree: */
|
||||
strb->surface = pipe->get_tex_surface(pipe, mt,
|
||||
/* the renderbuffer's surface is inside the texture */
|
||||
strb->surface = pipe->get_tex_surface(pipe, pt,
|
||||
att->CubeMapFace,
|
||||
att->TextureLevel,
|
||||
att->Zoffset);
|
||||
assert(strb->surface);
|
||||
|
||||
init_renderbuffer_bits(strb, mt->format);
|
||||
init_renderbuffer_bits(strb, pt->format);
|
||||
|
||||
/*
|
||||
printf("RENDER TO TEXTURE obj=%p mt=%p surf=%p %d x %d\n",
|
||||
att->Texture, mt, strb->surface, rb->Width, rb->Height);
|
||||
printf("RENDER TO TEXTURE obj=%p pt=%p surf=%p %d x %d\n",
|
||||
att->Texture, pt, strb->surface, rb->Width, rb->Height);
|
||||
*/
|
||||
|
||||
/* Invalidate buffer state so that the pipe's framebuffer state
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "state_tracker/st_cb_fbo.h"
|
||||
#include "state_tracker/st_cb_texture.h"
|
||||
#include "state_tracker/st_format.h"
|
||||
#include "state_tracker/st_mipmap_tree.h"
|
||||
#include "state_tracker/st_texture.h"
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
|
@ -54,8 +54,7 @@ struct st_texture_object
|
|||
{
|
||||
struct gl_texture_object base; /* The "parent" object */
|
||||
|
||||
/* The mipmap tree must include at least these levels once
|
||||
* validated:
|
||||
/* The texture must include at least these levels once validated:
|
||||
*/
|
||||
GLuint firstLevel;
|
||||
GLuint lastLevel;
|
||||
|
|
@ -67,7 +66,7 @@ struct st_texture_object
|
|||
/* On validation any active images held in main memory or in other
|
||||
* regions will be copied to this region and the old storage freed.
|
||||
*/
|
||||
struct pipe_mipmap_tree *mt;
|
||||
struct pipe_texture *pt;
|
||||
|
||||
GLboolean imageOverride;
|
||||
GLint depthOverride;
|
||||
|
|
@ -76,24 +75,6 @@ struct st_texture_object
|
|||
|
||||
|
||||
|
||||
struct st_texture_image
|
||||
{
|
||||
struct gl_texture_image base;
|
||||
|
||||
/* These aren't stored in gl_texture_image
|
||||
*/
|
||||
GLuint level;
|
||||
GLuint face;
|
||||
|
||||
/* If stImage->mt != NULL, image data is stored here.
|
||||
* Else if stImage->base.Data != NULL, image is stored there.
|
||||
* Else there is no image data.
|
||||
*/
|
||||
struct pipe_mipmap_tree *mt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static INLINE struct st_texture_object *
|
||||
st_texture_object(struct gl_texture_object *obj)
|
||||
|
|
@ -108,11 +89,11 @@ st_texture_image(struct gl_texture_image *img)
|
|||
}
|
||||
|
||||
|
||||
struct pipe_mipmap_tree *
|
||||
st_get_texobj_mipmap_tree(struct gl_texture_object *texObj)
|
||||
struct pipe_texture *
|
||||
st_get_texobj_texture(struct gl_texture_object *texObj)
|
||||
{
|
||||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
return stObj->mt;
|
||||
return stObj->pt;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -174,9 +155,9 @@ st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj)
|
|||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
|
||||
return
|
||||
stObj->mt &&
|
||||
stObj->mt->region &&
|
||||
intel_is_region_resident(intel, stObj->mt->region);
|
||||
stObj->pt &&
|
||||
stObj->pt->region &&
|
||||
intel_is_region_resident(intel, stObj->pt->region);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -207,11 +188,10 @@ static void
|
|||
st_DeleteTextureObject(GLcontext *ctx,
|
||||
struct gl_texture_object *texObj)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
|
||||
if (stObj->mt)
|
||||
st_miptree_release(pipe, &stObj->mt);
|
||||
if (stObj->pt)
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
|
||||
|
||||
_mesa_delete_texture_object(ctx, texObj);
|
||||
}
|
||||
|
|
@ -220,13 +200,12 @@ st_DeleteTextureObject(GLcontext *ctx,
|
|||
static void
|
||||
st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_texture_image *stImage = st_texture_image(texImage);
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
if (stImage->mt) {
|
||||
st_miptree_release(pipe, &stImage->mt);
|
||||
if (stImage->pt) {
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt);
|
||||
}
|
||||
|
||||
if (texImage->Data) {
|
||||
|
|
@ -287,10 +266,10 @@ do_memcpy(void *dest, const void *src, size_t n)
|
|||
}
|
||||
|
||||
|
||||
/* Functions to store texture images. Where possible, mipmap_tree's
|
||||
/* Functions to store texture images. Where possible, textures
|
||||
* will be created or further instantiated with image data, otherwise
|
||||
* images will be stored in malloc'd memory. A validation step is
|
||||
* required to pull those images into a mipmap tree, or otherwise
|
||||
* required to pull those images into a texture, or otherwise
|
||||
* decide a fallback is required.
|
||||
*/
|
||||
|
||||
|
|
@ -313,17 +292,16 @@ logbase2(int n)
|
|||
/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
|
||||
* 1).
|
||||
*
|
||||
* Otherwise, if max_level >= level >= min_level, create tree with
|
||||
* space for textures from min_level down to max_level.
|
||||
* Otherwise, if max_level >= level >= min_level, create texture with
|
||||
* space for images from min_level down to max_level.
|
||||
*
|
||||
* Otherwise, create tree with space for textures from (level
|
||||
* 0)..(1x1). Consider pruning this tree at a validation if the
|
||||
* saving is worth it.
|
||||
* Otherwise, create texture with space for images from (level 0)..(1x1).
|
||||
* Consider pruning this texture at a validation if the saving is worth it.
|
||||
*/
|
||||
static void
|
||||
guess_and_alloc_mipmap_tree(struct pipe_context *pipe,
|
||||
struct st_texture_object *stObj,
|
||||
struct st_texture_image *stImage)
|
||||
guess_and_alloc_texture(struct st_context *st,
|
||||
struct st_texture_object *stObj,
|
||||
struct st_texture_image *stImage)
|
||||
{
|
||||
GLuint firstLevel;
|
||||
GLuint lastLevel;
|
||||
|
|
@ -382,23 +360,20 @@ guess_and_alloc_mipmap_tree(struct pipe_context *pipe,
|
|||
lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
|
||||
}
|
||||
|
||||
assert(!stObj->mt);
|
||||
assert(!stObj->pt);
|
||||
if (stImage->base.IsCompressed)
|
||||
comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat);
|
||||
stObj->mt = st_miptree_create(pipe,
|
||||
stObj->pt = st_texture_create(st,
|
||||
gl_target_to_pipe(stObj->base.Target),
|
||||
stImage->base.InternalFormat,
|
||||
st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat),
|
||||
stImage->base.InternalFormat,
|
||||
firstLevel,
|
||||
lastLevel,
|
||||
width,
|
||||
height,
|
||||
depth,
|
||||
stImage->base.TexFormat->TexelBytes,
|
||||
comp_byte);
|
||||
|
||||
stObj->mt->format
|
||||
= st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
|
||||
|
||||
DBG("%s - success\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -482,11 +457,11 @@ try_pbo_upload(GLcontext *ctx,
|
|||
else
|
||||
src_stride = width;
|
||||
|
||||
dst_offset = st_miptree_image_offset(stImage->mt,
|
||||
dst_offset = st_texture_image_offset(stImage->pt,
|
||||
stImage->face,
|
||||
stImage->level);
|
||||
|
||||
dst_stride = stImage->mt->pitch;
|
||||
dst_stride = stImage->pt->pitch;
|
||||
|
||||
{
|
||||
struct _DriBufferObject *src_buffer =
|
||||
|
|
@ -495,11 +470,11 @@ try_pbo_upload(GLcontext *ctx,
|
|||
/* Temporary hack: cast to _DriBufferObject:
|
||||
*/
|
||||
struct _DriBufferObject *dst_buffer =
|
||||
(struct _DriBufferObject *)stImage->mt->region->buffer;
|
||||
(struct _DriBufferObject *)stImage->pt->region->buffer;
|
||||
|
||||
|
||||
intelEmitCopyBlit(intel,
|
||||
stImage->mt->cpp,
|
||||
stImage->pt->cpp,
|
||||
src_stride, src_buffer, src_offset,
|
||||
dst_stride, dst_buffer, dst_offset,
|
||||
0, 0, 0, 0, width, height,
|
||||
|
|
@ -540,7 +515,6 @@ st_TexImage(GLcontext * ctx,
|
|||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
struct st_texture_image *stImage = st_texture_image(texImage);
|
||||
GLint postConvWidth = width;
|
||||
|
|
@ -589,58 +563,58 @@ st_TexImage(GLcontext * ctx,
|
|||
/* Release the reference to a potentially orphaned buffer.
|
||||
* Release any old malloced memory.
|
||||
*/
|
||||
if (stImage->mt) {
|
||||
st_miptree_release(pipe, &stImage->mt);
|
||||
if (stImage->pt) {
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt);
|
||||
assert(!texImage->Data);
|
||||
}
|
||||
else if (texImage->Data) {
|
||||
_mesa_align_free(texImage->Data);
|
||||
}
|
||||
|
||||
/* If this is the only texture image in the tree, could call
|
||||
/* If this is the only texture image in the texture, could call
|
||||
* bmBufferData with NULL data to free the old block and avoid
|
||||
* waiting on any outstanding fences.
|
||||
*/
|
||||
if (stObj->mt &&
|
||||
stObj->mt->first_level == level &&
|
||||
stObj->mt->last_level == level &&
|
||||
stObj->mt->target != PIPE_TEXTURE_CUBE &&
|
||||
!st_miptree_match_image(stObj->mt, &stImage->base,
|
||||
if (stObj->pt &&
|
||||
stObj->pt->first_level == level &&
|
||||
stObj->pt->last_level == level &&
|
||||
stObj->pt->target != PIPE_TEXTURE_CUBE &&
|
||||
!st_texture_match_image(stObj->pt, &stImage->base,
|
||||
stImage->face, stImage->level)) {
|
||||
|
||||
DBG("release it\n");
|
||||
st_miptree_release(pipe, &stObj->mt);
|
||||
assert(!stObj->mt);
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
|
||||
assert(!stObj->pt);
|
||||
}
|
||||
|
||||
if (!stObj->mt) {
|
||||
guess_and_alloc_mipmap_tree(pipe, stObj, stImage);
|
||||
if (!stObj->mt) {
|
||||
DBG("guess_and_alloc_mipmap_tree: failed\n");
|
||||
if (!stObj->pt) {
|
||||
guess_and_alloc_texture(ctx->st, stObj, stImage);
|
||||
if (!stObj->pt) {
|
||||
DBG("guess_and_alloc_texture: failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
assert(!stImage->mt);
|
||||
assert(!stImage->pt);
|
||||
|
||||
if (stObj->mt &&
|
||||
st_miptree_match_image(stObj->mt, &stImage->base,
|
||||
if (stObj->pt &&
|
||||
st_texture_match_image(stObj->pt, &stImage->base,
|
||||
stImage->face, stImage->level)) {
|
||||
|
||||
st_miptree_reference(&stImage->mt, stObj->mt);
|
||||
assert(stImage->mt);
|
||||
pipe_texture_reference(ctx->st->pipe, &stImage->pt, stObj->pt);
|
||||
assert(stImage->pt);
|
||||
}
|
||||
|
||||
if (!stImage->mt)
|
||||
DBG("XXX: Image did not fit into tree - storing in local memory!\n");
|
||||
if (!stImage->pt)
|
||||
DBG("XXX: Image did not fit into texture - storing in local memory!\n");
|
||||
|
||||
#if 0 /* XXX FIX when st_buffer_objects are in place */
|
||||
/* PBO fastpaths:
|
||||
*/
|
||||
if (dims <= 2 &&
|
||||
stImage->mt &&
|
||||
stImage->pt &&
|
||||
intel_buffer_object(unpack->BufferObj) &&
|
||||
check_pbo_format(internalFormat, format,
|
||||
type, stImage->base.TexFormat)) {
|
||||
type, texImage->TexFormat)) {
|
||||
|
||||
DBG("trying pbo upload\n");
|
||||
|
||||
|
|
@ -650,9 +624,9 @@ st_TexImage(GLcontext * ctx,
|
|||
* performance (in particular when pipe_region_cow() is
|
||||
* required).
|
||||
*/
|
||||
if (stObj->mt == stImage->mt &&
|
||||
stObj->mt->first_level == level &&
|
||||
stObj->mt->last_level == level) {
|
||||
if (stObj->pt == stImage->pt &&
|
||||
stObj->pt->first_level == level &&
|
||||
stObj->pt->last_level == level) {
|
||||
|
||||
if (try_pbo_zcopy(intel, stImage, unpack,
|
||||
internalFormat,
|
||||
|
|
@ -683,7 +657,7 @@ st_TexImage(GLcontext * ctx,
|
|||
|
||||
|
||||
/* intelCopyTexImage calls this function with pixels == NULL, with
|
||||
* the expectation that the mipmap tree will be set up but nothing
|
||||
* the expectation that the texture will be set up but nothing
|
||||
* more will be done. This is where those calls return:
|
||||
*/
|
||||
if (compressed) {
|
||||
|
|
@ -698,13 +672,9 @@ st_TexImage(GLcontext * ctx,
|
|||
if (!pixels)
|
||||
return;
|
||||
|
||||
if (stImage->mt) {
|
||||
texImage->Data = st_miptree_image_map(pipe,
|
||||
stImage->mt,
|
||||
stImage->face,
|
||||
stImage->level,
|
||||
&dstRowStride,
|
||||
stImage->base.ImageOffsets);
|
||||
if (stImage->pt) {
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
|
||||
dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
|
||||
}
|
||||
else {
|
||||
/* Allocate regular memory and store the image there temporarily. */
|
||||
|
|
@ -732,22 +702,36 @@ st_TexImage(GLcontext * ctx,
|
|||
if (compressed) {
|
||||
memcpy(texImage->Data, pixels, imageSize);
|
||||
}
|
||||
else if (!texImage->TexFormat->StoreImage(ctx, dims,
|
||||
texImage->_BaseFormat,
|
||||
texImage->TexFormat,
|
||||
texImage->Data,
|
||||
0, 0, 0, /* dstX/Y/Zoffset */
|
||||
dstRowStride,
|
||||
texImage->ImageOffsets,
|
||||
width, height, depth,
|
||||
format, type, pixels, unpack)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
else {
|
||||
GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height,
|
||||
format, type);
|
||||
int i;
|
||||
|
||||
for (i = 0; i++ < depth;) {
|
||||
if (!texImage->TexFormat->StoreImage(ctx, dims,
|
||||
texImage->_BaseFormat,
|
||||
texImage->TexFormat,
|
||||
texImage->Data,
|
||||
0, 0, 0, /* dstX/Y/Zoffset */
|
||||
dstRowStride,
|
||||
texImage->ImageOffsets,
|
||||
width, height, 1,
|
||||
format, type, pixels, unpack)) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
}
|
||||
|
||||
if (stImage->pt && i < depth) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, i);
|
||||
pixels += srcImageStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_unmap_teximage_pbo(ctx, unpack);
|
||||
|
||||
if (stImage->mt) {
|
||||
st_miptree_image_unmap(pipe, stImage->mt);
|
||||
if (stImage->pt) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -839,49 +823,58 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
|
|||
/*
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
*/
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_texture_image *stImage = st_texture_image(texImage);
|
||||
GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width,
|
||||
texImage->Height, format,
|
||||
type);
|
||||
GLuint depth;
|
||||
int i;
|
||||
|
||||
/* Map */
|
||||
if (stImage->mt) {
|
||||
if (stImage->pt) {
|
||||
/* Image is stored in hardware format in a buffer managed by the
|
||||
* kernel. Need to explicitly map and unmap it.
|
||||
*/
|
||||
stImage->base.Data =
|
||||
st_miptree_image_map(pipe,
|
||||
stImage->mt,
|
||||
stImage->face,
|
||||
stImage->level,
|
||||
&stImage->base.RowStride,
|
||||
stImage->base.ImageOffsets);
|
||||
stImage->base.RowStride /= stImage->mt->cpp;
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, 0);
|
||||
texImage->RowStride = stImage->surface->pitch;
|
||||
}
|
||||
else {
|
||||
/* Otherwise, the image should actually be stored in
|
||||
* stImage->base.Data. This is pretty confusing for
|
||||
* texImage->Data. This is pretty confusing for
|
||||
* everybody, I'd much prefer to separate the two functions of
|
||||
* texImage->Data - storage for texture images in main memory
|
||||
* and access (ie mappings) of images. In other words, we'd
|
||||
* create a new texImage->Map field and leave Data simply for
|
||||
* storage.
|
||||
*/
|
||||
assert(stImage->base.Data);
|
||||
assert(texImage->Data);
|
||||
}
|
||||
|
||||
depth = texImage->Depth;
|
||||
texImage->Depth = 1;
|
||||
|
||||
if (compressed) {
|
||||
_mesa_get_compressed_teximage(ctx, target, level, pixels,
|
||||
texObj, texImage);
|
||||
} else {
|
||||
_mesa_get_teximage(ctx, target, level, format, type, pixels,
|
||||
texObj, texImage);
|
||||
for (i = 0; i++ < depth;) {
|
||||
if (compressed) {
|
||||
_mesa_get_compressed_teximage(ctx, target, level, pixels,
|
||||
texObj, texImage);
|
||||
} else {
|
||||
_mesa_get_teximage(ctx, target, level, format, type, pixels,
|
||||
texObj, texImage);
|
||||
}
|
||||
|
||||
if (stImage->pt && i < depth) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, i);
|
||||
pixels += dstImageStride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
texImage->Depth = depth;
|
||||
|
||||
/* Unmap */
|
||||
if (stImage->mt) {
|
||||
st_miptree_image_unmap(pipe, stImage->mt);
|
||||
stImage->base.Data = NULL;
|
||||
if (stImage->pt) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -921,9 +914,11 @@ st_TexSubimage(GLcontext * ctx,
|
|||
struct gl_texture_object *texObj,
|
||||
struct gl_texture_image *texImage)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct st_texture_image *stImage = st_texture_image(texImage);
|
||||
GLuint dstRowStride;
|
||||
GLuint srcImageStride = _mesa_image_image_stride(packing, width, height,
|
||||
format, type);
|
||||
int i;
|
||||
|
||||
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
|
||||
_mesa_lookup_enum_by_nr(target),
|
||||
|
|
@ -938,25 +933,28 @@ st_TexSubimage(GLcontext * ctx,
|
|||
/* Map buffer if necessary. Need to lock to prevent other contexts
|
||||
* from uploading the buffer under us.
|
||||
*/
|
||||
if (stImage->mt)
|
||||
texImage->Data = st_miptree_image_map(pipe,
|
||||
stImage->mt,
|
||||
stImage->face,
|
||||
stImage->level,
|
||||
&dstRowStride,
|
||||
texImage->ImageOffsets);
|
||||
if (stImage->pt) {
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset);
|
||||
dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
|
||||
}
|
||||
|
||||
assert(dstRowStride);
|
||||
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 (!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 && i < depth) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i);
|
||||
pixels += srcImageStride;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -970,8 +968,8 @@ st_TexSubimage(GLcontext * ctx,
|
|||
|
||||
_mesa_unmap_teximage_pbo(ctx, packing);
|
||||
|
||||
if (stImage->mt) {
|
||||
st_miptree_image_unmap(pipe, stImage->mt);
|
||||
if (stImage->pt) {
|
||||
st_texture_image_unmap(ctx->st, stImage);
|
||||
texImage->Data = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1074,7 +1072,7 @@ fallback_copy_texsubimage(GLcontext *ctx,
|
|||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
const uint face = texture_face(target);
|
||||
struct pipe_mipmap_tree *mt = stImage->mt;
|
||||
struct pipe_texture *pt = stImage->pt;
|
||||
struct pipe_surface *src_surf, *dest_surf;
|
||||
GLfloat *data;
|
||||
GLint row, yStep;
|
||||
|
|
@ -1090,7 +1088,7 @@ fallback_copy_texsubimage(GLcontext *ctx,
|
|||
|
||||
src_surf = strb->surface;
|
||||
|
||||
dest_surf = pipe->get_tex_surface(pipe, mt,
|
||||
dest_surf = pipe->get_tex_surface(pipe, pt,
|
||||
face, level, destZ);
|
||||
|
||||
(void) pipe->region_map(pipe, dest_surf->region);
|
||||
|
|
@ -1150,7 +1148,7 @@ do_copy_texsubimage(GLcontext *ctx,
|
|||
struct gl_framebuffer *fb = ctx->ReadBuffer;
|
||||
struct st_renderbuffer *strb;
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct pipe_region *src_region, *dest_region;
|
||||
struct pipe_surface *dest_surface;
|
||||
uint dest_format, src_format;
|
||||
|
||||
(void) texImage;
|
||||
|
|
@ -1169,29 +1167,24 @@ do_copy_texsubimage(GLcontext *ctx,
|
|||
|
||||
assert(strb);
|
||||
assert(strb->surface);
|
||||
assert(stImage->mt);
|
||||
assert(stImage->pt);
|
||||
|
||||
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
|
||||
srcY = strb->Base.Height - srcY - height;
|
||||
}
|
||||
|
||||
src_format = strb->surface->format;
|
||||
dest_format = stImage->mt->format;
|
||||
dest_format = stImage->pt->format;
|
||||
|
||||
src_region = strb->surface->region;
|
||||
dest_region = stImage->mt->region;
|
||||
dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face,
|
||||
stImage->level, destZ);
|
||||
|
||||
if (src_format == dest_format &&
|
||||
ctx->_ImageTransferState == 0x0 &&
|
||||
src_region &&
|
||||
dest_region &&
|
||||
strb->surface->cpp == stImage->mt->cpp) {
|
||||
strb->surface->region &&
|
||||
dest_surface->region &&
|
||||
strb->surface->cpp == stImage->pt->cpp) {
|
||||
/* do blit-style copy */
|
||||
struct pipe_surface *dest_surface = pipe->get_tex_surface(pipe,
|
||||
stImage->mt,
|
||||
stImage->face,
|
||||
stImage->level,
|
||||
destZ);
|
||||
|
||||
/* XXX may need to invert image depending on window
|
||||
* vs. user-created FBO
|
||||
|
|
@ -1203,12 +1196,12 @@ do_copy_texsubimage(GLcontext *ctx,
|
|||
* worth it:
|
||||
*/
|
||||
intelEmitCopyBlit(intel,
|
||||
stImage->mt->cpp,
|
||||
stImage->pt->cpp,
|
||||
-src->pitch,
|
||||
src->buffer,
|
||||
src->height * src->pitch * src->cpp,
|
||||
stImage->mt->pitch,
|
||||
stImage->mt->region->buffer,
|
||||
stImage->pt->pitch,
|
||||
stImage->pt->region->buffer,
|
||||
dest_offset,
|
||||
x, y + height, dstx, dsty, width, height,
|
||||
GL_COPY); /* ? */
|
||||
|
|
@ -1224,8 +1217,6 @@ do_copy_texsubimage(GLcontext *ctx,
|
|||
/* size */
|
||||
width, height);
|
||||
#endif
|
||||
|
||||
pipe_surface_reference(&dest_surface, NULL);
|
||||
}
|
||||
else {
|
||||
fallback_copy_texsubimage(ctx, target, level,
|
||||
|
|
@ -1234,6 +1225,7 @@ do_copy_texsubimage(GLcontext *ctx,
|
|||
srcX, srcY, width, height);
|
||||
}
|
||||
|
||||
pipe_surface_reference(&dest_surface, NULL);
|
||||
|
||||
#if 0
|
||||
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
|
||||
|
|
@ -1267,7 +1259,7 @@ st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
|
|||
goto fail;
|
||||
#endif
|
||||
|
||||
/* Setup or redefine the texture object, mipmap tree and texture
|
||||
/* Setup or redefine the texture object, texture and texture
|
||||
* image. Don't populate yet.
|
||||
*/
|
||||
ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
|
||||
|
|
@ -1299,7 +1291,7 @@ st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
|
|||
goto fail;
|
||||
#endif
|
||||
|
||||
/* Setup or redefine the texture object, mipmap tree and texture
|
||||
/* Setup or redefine the texture object, texture and texture
|
||||
* image. Don't populate yet.
|
||||
*/
|
||||
ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
|
||||
|
|
@ -1407,28 +1399,28 @@ calculate_first_last_level(struct st_texture_object *stObj)
|
|||
|
||||
|
||||
static void
|
||||
copy_image_data_to_tree(struct pipe_context *pipe,
|
||||
struct st_texture_object *stObj,
|
||||
struct st_texture_image *stImage)
|
||||
copy_image_data_to_texture(struct st_context *st,
|
||||
struct st_texture_object *stObj,
|
||||
struct st_texture_image *stImage)
|
||||
{
|
||||
if (stImage->mt) {
|
||||
if (stImage->pt) {
|
||||
/* Copy potentially with the blitter:
|
||||
*/
|
||||
st_miptree_image_copy(pipe,
|
||||
stObj->mt, /* dest miptree */
|
||||
st_texture_image_copy(st->pipe,
|
||||
stObj->pt, /* dest texture */
|
||||
stImage->face, stImage->level,
|
||||
stImage->mt /* src miptree */
|
||||
stImage->pt /* src texture */
|
||||
);
|
||||
|
||||
st_miptree_release(pipe, &stImage->mt);
|
||||
st->pipe->texture_release(st->pipe, &stImage->pt);
|
||||
}
|
||||
else {
|
||||
assert(stImage->base.Data != NULL);
|
||||
|
||||
/* More straightforward upload.
|
||||
*/
|
||||
st_miptree_image_data(pipe,
|
||||
stObj->mt,
|
||||
st_texture_image_data(st->pipe,
|
||||
stObj->pt,
|
||||
stImage->face,
|
||||
stImage->level,
|
||||
stImage->base.Data,
|
||||
|
|
@ -1439,16 +1431,16 @@ copy_image_data_to_tree(struct pipe_context *pipe,
|
|||
stImage->base.Data = NULL;
|
||||
}
|
||||
|
||||
st_miptree_reference(&stImage->mt, stObj->mt);
|
||||
pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
GLboolean
|
||||
st_finalize_mipmap_tree(GLcontext *ctx,
|
||||
struct pipe_context *pipe, GLuint unit,
|
||||
GLboolean *needFlush)
|
||||
st_finalize_texture(GLcontext *ctx,
|
||||
struct pipe_context *pipe, GLuint unit,
|
||||
GLboolean *needFlush)
|
||||
{
|
||||
struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
|
||||
struct st_texture_object *stObj = st_texture_object(tObj);
|
||||
|
|
@ -1465,7 +1457,7 @@ st_finalize_mipmap_tree(GLcontext *ctx,
|
|||
*/
|
||||
assert(stObj->base._Complete);
|
||||
|
||||
/* What levels must the tree include at a minimum?
|
||||
/* What levels must the texture include at a minimum?
|
||||
*/
|
||||
calculate_first_last_level(stObj);
|
||||
firstImage =
|
||||
|
|
@ -1474,27 +1466,27 @@ st_finalize_mipmap_tree(GLcontext *ctx,
|
|||
/* Fallback case:
|
||||
*/
|
||||
if (firstImage->base.Border) {
|
||||
if (stObj->mt) {
|
||||
st_miptree_release(pipe, &stObj->mt);
|
||||
if (stObj->pt) {
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* If both firstImage and stObj have a tree which can contain
|
||||
/* If both firstImage and stObj point to a texture which can contain
|
||||
* all active images, favour firstImage. Note that because of the
|
||||
* completeness requirement, we know that the image dimensions
|
||||
* will match.
|
||||
*/
|
||||
if (firstImage->mt &&
|
||||
firstImage->mt != stObj->mt &&
|
||||
firstImage->mt->first_level <= stObj->firstLevel &&
|
||||
firstImage->mt->last_level >= stObj->lastLevel) {
|
||||
if (firstImage->pt &&
|
||||
firstImage->pt != stObj->pt &&
|
||||
firstImage->pt->first_level <= stObj->firstLevel &&
|
||||
firstImage->pt->last_level >= stObj->lastLevel) {
|
||||
|
||||
if (stObj->mt)
|
||||
st_miptree_release(pipe, &stObj->mt);
|
||||
if (stObj->pt)
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
|
||||
|
||||
st_miptree_reference(&stObj->mt, firstImage->mt);
|
||||
pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt);
|
||||
}
|
||||
|
||||
if (firstImage->base.IsCompressed) {
|
||||
|
|
@ -1505,48 +1497,45 @@ st_finalize_mipmap_tree(GLcontext *ctx,
|
|||
cpp = firstImage->base.TexFormat->TexelBytes;
|
||||
}
|
||||
|
||||
/* Check tree can hold all active levels. Check tree matches
|
||||
/* Check texture can hold all active levels. Check texture matches
|
||||
* target, imageFormat, etc.
|
||||
*
|
||||
* XXX: For some layouts (eg i945?), the test might have to be
|
||||
* first_level == firstLevel, as the tree isn't valid except at the
|
||||
* first_level == firstLevel, as the texture isn't valid except at the
|
||||
* original start level. Hope to get around this by
|
||||
* programming minLod, maxLod, baseLevel into the hardware and
|
||||
* leaving the tree alone.
|
||||
* leaving the texture alone.
|
||||
*/
|
||||
if (stObj->mt &&
|
||||
(stObj->mt->target != gl_target_to_pipe(stObj->base.Target) ||
|
||||
stObj->mt->internal_format != firstImage->base.InternalFormat ||
|
||||
stObj->mt->first_level != stObj->firstLevel ||
|
||||
stObj->mt->last_level != stObj->lastLevel ||
|
||||
stObj->mt->width0 != firstImage->base.Width ||
|
||||
stObj->mt->height0 != firstImage->base.Height ||
|
||||
stObj->mt->depth0 != firstImage->base.Depth ||
|
||||
stObj->mt->cpp != cpp ||
|
||||
stObj->mt->compressed != firstImage->base.IsCompressed)) {
|
||||
st_miptree_release(pipe, &stObj->mt);
|
||||
if (stObj->pt &&
|
||||
(stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
|
||||
stObj->pt->internal_format != firstImage->base.InternalFormat ||
|
||||
stObj->pt->first_level != stObj->firstLevel ||
|
||||
stObj->pt->last_level != stObj->lastLevel ||
|
||||
stObj->pt->width[0] != firstImage->base.Width ||
|
||||
stObj->pt->height[0] != firstImage->base.Height ||
|
||||
stObj->pt->depth[0] != firstImage->base.Depth ||
|
||||
stObj->pt->cpp != cpp ||
|
||||
stObj->pt->compressed != firstImage->base.IsCompressed)) {
|
||||
ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt);
|
||||
}
|
||||
|
||||
|
||||
/* May need to create a new tree:
|
||||
/* May need to create a new texture:
|
||||
*/
|
||||
if (!stObj->mt) {
|
||||
stObj->mt = st_miptree_create(pipe,
|
||||
if (!stObj->pt) {
|
||||
stObj->pt = st_texture_create(ctx->st,
|
||||
gl_target_to_pipe(stObj->base.Target),
|
||||
firstImage->base.InternalFormat,
|
||||
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
|
||||
firstImage->base.InternalFormat,
|
||||
stObj->firstLevel,
|
||||
stObj->lastLevel,
|
||||
firstImage->base.Width,
|
||||
firstImage->base.Height,
|
||||
firstImage->base.Depth,
|
||||
cpp,
|
||||
comp_byte);
|
||||
|
||||
stObj->mt->format
|
||||
= st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
|
||||
}
|
||||
|
||||
/* Pull in any images not in the object's tree:
|
||||
/* Pull in any images not in the object's texture:
|
||||
*/
|
||||
nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
for (face = 0; face < nr_faces; face++) {
|
||||
|
|
@ -1554,10 +1543,10 @@ st_finalize_mipmap_tree(GLcontext *ctx,
|
|||
struct st_texture_image *stImage =
|
||||
st_texture_image(stObj->base.Image[face][i]);
|
||||
|
||||
/* Need to import images in main memory or held in other trees.
|
||||
/* Need to import images in main memory or held in other textures.
|
||||
*/
|
||||
if (stObj->mt != stImage->mt) {
|
||||
copy_image_data_to_tree(pipe, stObj, stImage);
|
||||
if (stObj->pt != stImage->pt) {
|
||||
copy_image_data_to_texture(ctx->st, stObj, stImage);
|
||||
*needFlush = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
#define ST_CB_TEXTURE_H
|
||||
|
||||
|
||||
extern struct pipe_mipmap_tree *
|
||||
st_get_texobj_mipmap_tree(struct gl_texture_object *texObj);
|
||||
extern struct pipe_texture *
|
||||
st_get_texobj_texture(struct gl_texture_object *texObj);
|
||||
|
||||
|
||||
extern GLboolean
|
||||
st_finalize_mipmap_tree(GLcontext *ctx,
|
||||
struct pipe_context *pipe, GLuint unit,
|
||||
GLboolean *needFlush);
|
||||
st_finalize_texture(GLcontext *ctx,
|
||||
struct pipe_context *pipe, GLuint unit,
|
||||
GLboolean *needFlush);
|
||||
|
||||
|
||||
extern void
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
struct st_context;
|
||||
struct st_region;
|
||||
struct st_texture_object;
|
||||
struct st_texture_image;
|
||||
struct st_fragment_program;
|
||||
struct draw_context;
|
||||
struct draw_stage;
|
||||
|
|
@ -61,6 +60,25 @@ struct st_tracked_state {
|
|||
|
||||
|
||||
|
||||
struct st_texture_image
|
||||
{
|
||||
struct gl_texture_image base;
|
||||
|
||||
/* These aren't stored in gl_texture_image
|
||||
*/
|
||||
GLuint level;
|
||||
GLuint face;
|
||||
|
||||
/* If stImage->pt != NULL, image data is stored here.
|
||||
* Else if stImage->base.Data != NULL, image is stored there.
|
||||
* Else there is no image data.
|
||||
*/
|
||||
struct pipe_texture *pt;
|
||||
|
||||
struct pipe_surface *surface;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct st_context
|
||||
{
|
||||
|
|
@ -91,7 +109,7 @@ struct st_context
|
|||
struct pipe_constant_buffer constants[2];
|
||||
struct pipe_feedback_state feedback;
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_poly_stipple poly_stipple;
|
||||
struct pipe_scissor_state scissor;
|
||||
struct pipe_viewport_state viewport;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "st_mipmap_tree.h"
|
||||
#include "st_context.h"
|
||||
#include "st_format.h"
|
||||
#include "st_texture.h"
|
||||
#include "enums.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
|
@ -56,19 +58,19 @@ target_to_target(GLenum target)
|
|||
}
|
||||
#endif
|
||||
|
||||
struct pipe_mipmap_tree *
|
||||
st_miptree_create(struct pipe_context *pipe,
|
||||
struct pipe_texture *
|
||||
st_texture_create(struct st_context *st,
|
||||
unsigned target,
|
||||
GLenum internal_format,
|
||||
GLuint first_level,
|
||||
GLuint last_level,
|
||||
GLuint width0,
|
||||
GLuint height0,
|
||||
GLuint depth0, GLuint cpp, GLuint compress_byte)
|
||||
unsigned format,
|
||||
GLenum internal_format,
|
||||
GLuint first_level,
|
||||
GLuint last_level,
|
||||
GLuint width0,
|
||||
GLuint height0,
|
||||
GLuint depth0,
|
||||
GLuint compress_byte)
|
||||
{
|
||||
GLboolean ok;
|
||||
struct pipe_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||
GLbitfield flags = 0x0;
|
||||
struct pipe_texture *pt = CALLOC_STRUCT(pipe_texture);
|
||||
|
||||
assert(target <= PIPE_TEXTURE_CUBE);
|
||||
|
||||
|
|
@ -76,102 +78,64 @@ st_miptree_create(struct pipe_context *pipe,
|
|||
_mesa_lookup_enum_by_nr(target),
|
||||
_mesa_lookup_enum_by_nr(internal_format), first_level, last_level);
|
||||
|
||||
mt->target = target;
|
||||
mt->internal_format = internal_format;
|
||||
mt->first_level = first_level;
|
||||
mt->last_level = last_level;
|
||||
mt->width0 = width0;
|
||||
mt->height0 = height0;
|
||||
mt->depth0 = depth0;
|
||||
mt->cpp = compress_byte ? compress_byte : cpp;
|
||||
mt->compressed = compress_byte ? 1 : 0;
|
||||
mt->refcount = 1;
|
||||
|
||||
ok = pipe->mipmap_tree_layout(pipe, mt);
|
||||
if (ok) {
|
||||
mt->region = pipe->winsys->region_alloc(pipe->winsys,
|
||||
mt->pitch * mt->cpp *
|
||||
mt->total_height, flags);
|
||||
}
|
||||
|
||||
if (!mt->region) {
|
||||
free(mt);
|
||||
if (!pt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mt;
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
st->pipe->texture_create(st->pipe, &pt);
|
||||
|
||||
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;
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Can the image be pulled into a unified mipmap tree. This mirrors
|
||||
/* Can the image be pulled into a unified mipmap texture. This mirrors
|
||||
* the completeness test in a lot of ways.
|
||||
*
|
||||
* Not sure whether I want to pass gl_texture_image here.
|
||||
*/
|
||||
GLboolean
|
||||
st_miptree_match_image(struct pipe_mipmap_tree *mt,
|
||||
st_texture_match_image(struct pipe_texture *pt,
|
||||
struct gl_texture_image *image,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
/* Images with borders are never pulled into mipmap trees.
|
||||
/* Images with borders are never pulled into mipmap textures.
|
||||
*/
|
||||
if (image->Border)
|
||||
return GL_FALSE;
|
||||
|
||||
if (image->InternalFormat != mt->internal_format ||
|
||||
image->IsCompressed != mt->compressed)
|
||||
if (image->InternalFormat != pt->internal_format ||
|
||||
image->IsCompressed != pt->compressed)
|
||||
return GL_FALSE;
|
||||
|
||||
/* Test image dimensions against the base level image adjusted for
|
||||
* minification. This will also catch images not present in the
|
||||
* tree, changed targets, etc.
|
||||
* texture, changed targets, etc.
|
||||
*/
|
||||
if (image->Width != mt->level[level].width ||
|
||||
image->Height != mt->level[level].height ||
|
||||
image->Depth != mt->level[level].depth)
|
||||
if (image->Width != pt->width[level] ||
|
||||
image->Height != pt->height[level] ||
|
||||
image->Depth != pt->depth[level])
|
||||
return GL_FALSE;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#if 000
|
||||
/* Although we use the image_offset[] array to store relative offsets
|
||||
* to cube faces, Mesa doesn't know anything about this and expects
|
||||
* each cube face to be treated as a separate image.
|
||||
|
|
@ -179,14 +143,14 @@ st_miptree_match_image(struct pipe_mipmap_tree *mt,
|
|||
* These functions present that view to mesa:
|
||||
*/
|
||||
const GLuint *
|
||||
st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
|
||||
st_texture_depth_offsets(struct pipe_texture *pt, GLuint level)
|
||||
{
|
||||
static const GLuint zero = 0;
|
||||
|
||||
if (mt->target != PIPE_TEXTURE_3D || mt->level[level].nr_images == 1)
|
||||
if (pt->target != PIPE_TEXTURE_3D || pt->level[level].nr_images == 1)
|
||||
return &zero;
|
||||
else
|
||||
return mt->level[level].image_offset;
|
||||
return pt->level[level].image_offset;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -195,63 +159,47 @@ st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level)
|
|||
* texture memory buffer, in bytes.
|
||||
*/
|
||||
GLuint
|
||||
st_miptree_image_offset(const struct pipe_mipmap_tree * mt,
|
||||
st_texture_image_offset(const struct pipe_texture * pt,
|
||||
GLuint face, GLuint level)
|
||||
{
|
||||
if (mt->target == PIPE_TEXTURE_CUBE)
|
||||
return (mt->level[level].level_offset +
|
||||
mt->level[level].image_offset[face] * mt->cpp);
|
||||
if (pt->target == PIPE_TEXTURE_CUBE)
|
||||
return (pt->level[level].level_offset +
|
||||
pt->level[level].image_offset[face] * pt->cpp);
|
||||
else
|
||||
return mt->level[level].level_offset;
|
||||
return pt->level[level].level_offset;
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
st_miptree_texel_offset(const struct pipe_mipmap_tree * mt,
|
||||
GLuint face, GLuint level,
|
||||
GLuint col, GLuint row, GLuint img)
|
||||
{
|
||||
GLuint imgOffset = st_miptree_image_offset(mt, face, level);
|
||||
|
||||
return imgOffset + row * (mt->pitch + col) * mt->cpp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Map a teximage in a mipmap tree.
|
||||
* Map a teximage in a mipmap texture.
|
||||
* \param row_stride returns row stride in bytes
|
||||
* \param image_stride returns image stride in bytes (for 3D textures).
|
||||
* \return address of mapping
|
||||
*/
|
||||
GLubyte *
|
||||
st_miptree_image_map(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree * mt,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
GLuint * row_stride, GLuint * image_offsets)
|
||||
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
|
||||
GLuint zoffset)
|
||||
{
|
||||
GLubyte *ptr;
|
||||
struct pipe_texture *pt = stImage->pt;
|
||||
DBG("%s \n", __FUNCTION__);
|
||||
|
||||
if (row_stride)
|
||||
*row_stride = mt->pitch * mt->cpp;
|
||||
stImage->surface = st->pipe->get_tex_surface(st->pipe, pt, stImage->face,
|
||||
stImage->level, zoffset);
|
||||
|
||||
if (image_offsets)
|
||||
memcpy(image_offsets, mt->level[level].image_offset,
|
||||
mt->level[level].depth * sizeof(GLuint));
|
||||
(void) st->pipe->region_map(st->pipe, stImage->surface->region);
|
||||
|
||||
ptr = pipe->region_map(pipe, mt->region);
|
||||
|
||||
return ptr + st_miptree_image_offset(mt, face, level);
|
||||
return stImage->surface->region->map + stImage->surface->offset;
|
||||
}
|
||||
|
||||
void
|
||||
st_miptree_image_unmap(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *mt)
|
||||
st_texture_image_unmap(struct st_context *st, struct st_texture_image *stImage)
|
||||
{
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
pipe->region_unmap(pipe, mt->region);
|
||||
|
||||
st->pipe->region_unmap(st->pipe, stImage->surface->region);
|
||||
|
||||
pipe_surface_reference(&stImage->surface, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -259,14 +207,14 @@ st_miptree_image_unmap(struct pipe_context *pipe,
|
|||
/* Upload data for a particular image.
|
||||
*/
|
||||
void
|
||||
st_miptree_image_data(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
st_texture_image_data(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face,
|
||||
GLuint level,
|
||||
void *src,
|
||||
GLuint src_row_pitch, GLuint src_image_pitch)
|
||||
{
|
||||
GLuint depth = dst->level[level].depth;
|
||||
GLuint depth = dst->depth[level];
|
||||
GLuint i;
|
||||
GLuint height = 0;
|
||||
const GLubyte *srcUB = src;
|
||||
|
|
@ -274,7 +222,7 @@ st_miptree_image_data(struct pipe_context *pipe,
|
|||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
for (i = 0; i < depth; i++) {
|
||||
height = dst->level[level].height;
|
||||
height = dst->height[level];
|
||||
if(dst->compressed)
|
||||
height /= 4;
|
||||
|
||||
|
|
@ -285,7 +233,7 @@ st_miptree_image_data(struct pipe_context *pipe,
|
|||
srcUB,
|
||||
src_row_pitch,
|
||||
0, 0, /* source x, y */
|
||||
dst->level[level].width, height); /* width, height */
|
||||
dst->width[level], height); /* width, height */
|
||||
|
||||
pipe_surface_reference(&dst_surface, NULL);
|
||||
|
||||
|
|
@ -293,17 +241,17 @@ st_miptree_image_data(struct pipe_context *pipe,
|
|||
}
|
||||
}
|
||||
|
||||
/* Copy mipmap image between trees
|
||||
/* Copy mipmap image between textures
|
||||
*/
|
||||
void
|
||||
st_miptree_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
st_texture_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct pipe_mipmap_tree *src)
|
||||
struct pipe_texture *src)
|
||||
{
|
||||
GLuint width = src->level[level].width;
|
||||
GLuint height = src->level[level].height;
|
||||
GLuint depth = src->level[level].depth;
|
||||
GLuint width = src->width[level];
|
||||
GLuint height = src->height[level];
|
||||
GLuint depth = src->depth[level];
|
||||
struct pipe_surface *src_surface;
|
||||
struct pipe_surface *dst_surface;
|
||||
GLuint i;
|
||||
|
|
@ -25,94 +25,85 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef ST_MIPMAP_TREE_H
|
||||
#define ST_MIPMAP_TREE_H
|
||||
#ifndef ST_TEXTURE_H
|
||||
#define ST_TEXTURE_H
|
||||
|
||||
|
||||
#include "main/mtypes.h"
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_mipmap_tree;
|
||||
struct pipe_texture;
|
||||
struct pipe_region;
|
||||
|
||||
|
||||
extern struct pipe_mipmap_tree *
|
||||
st_miptree_create(struct pipe_context *pipe,
|
||||
GLenum target,
|
||||
extern struct pipe_texture *
|
||||
st_texture_create(struct st_context *st,
|
||||
unsigned target,
|
||||
unsigned format,
|
||||
GLenum internal_format,
|
||||
GLuint first_level,
|
||||
GLuint last_level,
|
||||
GLuint width0,
|
||||
GLuint height0,
|
||||
GLuint depth0,
|
||||
GLuint cpp,
|
||||
GLuint compress_byte);
|
||||
|
||||
extern void
|
||||
st_miptree_reference(struct pipe_mipmap_tree **dst,
|
||||
struct pipe_mipmap_tree *src);
|
||||
|
||||
extern void
|
||||
st_miptree_release(struct pipe_context *pipe, struct pipe_mipmap_tree **mt);
|
||||
|
||||
|
||||
/* Check if an image fits an existing mipmap tree layout
|
||||
/* Check if an image fits an existing texture
|
||||
*/
|
||||
extern GLboolean
|
||||
st_miptree_match_image(struct pipe_mipmap_tree *mt,
|
||||
st_texture_match_image(struct pipe_texture *pt,
|
||||
struct gl_texture_image *image,
|
||||
GLuint face, GLuint level);
|
||||
|
||||
/* Return a pointer to an image within a tree. Return image stride as
|
||||
/* Return a pointer to an image within a texture. Return image stride as
|
||||
* well.
|
||||
*/
|
||||
extern GLubyte *
|
||||
st_miptree_image_map(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *mt,
|
||||
GLuint face, GLuint level,
|
||||
GLuint * row_stride, GLuint * image_stride);
|
||||
st_texture_image_map(struct st_context *st,
|
||||
struct st_texture_image *stImage,
|
||||
GLuint zoffset);
|
||||
|
||||
extern void
|
||||
st_miptree_image_unmap(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *mt);
|
||||
st_texture_image_unmap(struct st_context *st,
|
||||
struct st_texture_image *stImage);
|
||||
|
||||
|
||||
/* Return pointers to each 2d slice within an image. Indexed by depth
|
||||
* value.
|
||||
*/
|
||||
extern const GLuint *
|
||||
st_miptree_depth_offsets(struct pipe_mipmap_tree *mt, GLuint level);
|
||||
st_texture_depth_offsets(struct pipe_texture *pt, GLuint level);
|
||||
|
||||
|
||||
/* Return the linear offset of an image relative to the start of the
|
||||
* tree:
|
||||
/* Return the linear offset of an image relative to the start of its region:
|
||||
*/
|
||||
extern GLuint
|
||||
st_miptree_image_offset(const struct pipe_mipmap_tree *mt,
|
||||
st_texture_image_offset(const struct pipe_texture *pt,
|
||||
GLuint face, GLuint level);
|
||||
|
||||
extern GLuint
|
||||
st_miptree_texel_offset(const struct pipe_mipmap_tree * mt,
|
||||
st_texture_texel_offset(const struct pipe_texture * pt,
|
||||
GLuint face, GLuint level,
|
||||
GLuint col, GLuint row, GLuint img);
|
||||
|
||||
|
||||
/* Upload an image into a tree
|
||||
/* Upload an image into a texture
|
||||
*/
|
||||
extern void
|
||||
st_miptree_image_data(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
st_texture_image_data(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face, GLuint level, void *src,
|
||||
GLuint src_row_pitch, GLuint src_image_pitch);
|
||||
|
||||
|
||||
/* Copy an image between two trees
|
||||
/* Copy an image between two textures
|
||||
*/
|
||||
extern void
|
||||
st_miptree_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_mipmap_tree *dst,
|
||||
st_texture_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct pipe_mipmap_tree *src);
|
||||
struct pipe_texture *src);
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue