mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 08:20:12 +01:00
gallium: clean-up, simplification of mipmapped textures
Remove pipe_texture->first_level (always implicitly zero). This means there's never any unused mipmap levels at the top. In the state tracker, we no longer re-layout mipmapped textures if the MinLod/MaxLod texture parameters change. It's up to the driver to obey the pipe_sampler->min/max_lod clamps.
This commit is contained in:
parent
5d1af60edb
commit
09e23e077b
13 changed files with 115 additions and 109 deletions
|
|
@ -250,6 +250,13 @@ i915_create_sampler_state(struct pipe_context *pipe,
|
|||
if (sampler->normalized_coords)
|
||||
cso->state[1] |= SS3_NORMALIZED_COORDS;
|
||||
|
||||
if (0) /* XXX not tested yet */
|
||||
{
|
||||
int minlod = (int) (16.0 * sampler->min_lod);
|
||||
minlod = CLAMP(minlod, 0, 16 * 11);
|
||||
cso->state[1] |= (minlod << SS3_MIN_LOD_SHIFT);
|
||||
}
|
||||
|
||||
{
|
||||
ubyte r = float_to_ubyte(sampler->border_color[0]);
|
||||
ubyte g = float_to_ubyte(sampler->border_color[1]);
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ i915_update_texture(struct i915_context *i915, uint unit,
|
|||
const struct pipe_texture *pt = &tex->base;
|
||||
uint format, pitch;
|
||||
const uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
|
||||
const uint num_levels = pt->last_level - pt->first_level;
|
||||
const uint num_levels = pt->last_level;
|
||||
|
||||
assert(tex);
|
||||
assert(width);
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
tex->pitch = pt->width[0];
|
||||
|
||||
/* May need to adjust pitch to accomodate the placement of
|
||||
* the 2nd mipmap. This occurs when the alignment
|
||||
* the 2nd mipmap level. This occurs when the alignment
|
||||
* constraints of mipmap placement push the right edge of the
|
||||
* 2nd mipmap out past the width of its parent.
|
||||
* 2nd mipmap level out past the width of its parent.
|
||||
*/
|
||||
if (pt->first_level != pt->last_level) {
|
||||
if (pt->last_level > 0) {
|
||||
unsigned mip1_width = align_int(minify(pt->width[0]), align_w)
|
||||
+ minify(minify(pt->width[0]));
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp;
|
||||
tex->total_height = 0;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned img_height;
|
||||
|
||||
i915_miptree_set_level_info(tex, level, 1, x, y, width, height, 1);
|
||||
|
|
@ -152,9 +152,9 @@ i945_miptree_layout_2d( struct i915_texture *tex )
|
|||
*/
|
||||
tex->total_height = MAX2(tex->total_height, y + img_height);
|
||||
|
||||
/* Layout_below: step right after second mipmap.
|
||||
/* Layout_below: step right after second mipmap level.
|
||||
*/
|
||||
if (level == pt->first_level + 1) {
|
||||
if (level == 1) {
|
||||
x += align_int(width, align_w);
|
||||
}
|
||||
else {
|
||||
|
|
@ -204,7 +204,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
|
||||
tex->total_height = dim * 4;
|
||||
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 6,
|
||||
0, 0,
|
||||
/*OLD: tex->pitch, tex->total_height,*/
|
||||
|
|
@ -219,7 +219,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
unsigned y = initial_offsets[face][1] * dim;
|
||||
unsigned d = dim;
|
||||
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_image_offset(tex, level, face, x, y);
|
||||
d >>= 1;
|
||||
x += step_offsets[face][0] * d;
|
||||
|
|
@ -240,7 +240,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
|
||||
/* XXX: hardware expects/requires 9 levels at minimum.
|
||||
*/
|
||||
for (level = pt->first_level; level <= MAX2(8, pt->last_level);
|
||||
for (level = 0; level <= MAX2(8, pt->last_level);
|
||||
level++) {
|
||||
i915_miptree_set_level_info(tex, level, depth, 0, tex->total_height,
|
||||
width, height, depth);
|
||||
|
|
@ -256,7 +256,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
/* Fixup depth image_offsets:
|
||||
*/
|
||||
depth = pt->depth[0];
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned i;
|
||||
for (i = 0; i < depth; i++)
|
||||
i915_miptree_set_image_offset(tex, level, i,
|
||||
|
|
@ -282,7 +282,7 @@ i915_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
|
||||
tex->total_height = 0;
|
||||
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 1,
|
||||
0, tex->total_height,
|
||||
width, height, 1);
|
||||
|
|
@ -337,7 +337,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
|
||||
/* Set all the levels to effectively occupy the whole rectangular region.
|
||||
*/
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_level_info(tex, level, 6,
|
||||
0, 0,
|
||||
lvlWidth, lvlHeight, 1);
|
||||
|
|
@ -355,12 +355,12 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
y = tex->total_height - 4;
|
||||
x = (face - 4) * 8;
|
||||
}
|
||||
else if (dim < 4 && (face > 0 || pt->first_level > 0)) {
|
||||
else if (dim < 4 && (face > 0)) {
|
||||
y = tex->total_height - 4;
|
||||
x = face * 8;
|
||||
}
|
||||
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
i915_miptree_set_image_offset(tex, level, face, x, y);
|
||||
|
||||
d >>= 1;
|
||||
|
|
@ -418,7 +418,7 @@ i945_miptree_layout(struct pipe_context *pipe, struct i915_texture * tex)
|
|||
pack_x_pitch = tex->pitch;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for (level = pt->first_level; level <= pt->last_level; level++) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
|
|||
* constraints of mipmap placement push the right edge of the
|
||||
* 2nd mipmap out past the width of its parent.
|
||||
*/
|
||||
if (pt->first_level != pt->last_level) {
|
||||
if (pt->last_level > 0) {
|
||||
unsigned mip1_width;
|
||||
|
||||
if (pt->compressed) {
|
||||
|
|
@ -168,7 +168,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
|
|||
tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
|
||||
tex->total_height = 0;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned img_height;
|
||||
|
||||
intel_miptree_set_level_info(tex, level, 1, x, y, width,
|
||||
|
|
@ -187,7 +187,7 @@ static void i945_miptree_layout_2d(struct brw_texture *tex)
|
|||
|
||||
/* Layout_below: step right after second mipmap.
|
||||
*/
|
||||
if (level == pt->first_level + 1) {
|
||||
if (level == 1) {
|
||||
x += align(width, align_w);
|
||||
}
|
||||
else {
|
||||
|
|
@ -234,7 +234,7 @@ static boolean brw_miptree_layout(struct pipe_context *pipe, struct brw_texture
|
|||
pack_x_pitch = tex->pitch;
|
||||
pack_x_nr = 1;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ void brw_update_texture_surface( struct brw_context *brw,
|
|||
/* Updated in emit_reloc */
|
||||
surf.ss1.base_addr = brw_buffer_offset( brw, tObj->buffer );
|
||||
|
||||
surf.ss2.mip_count = tObj->base.last_level - tObj->base.first_level;
|
||||
surf.ss2.mip_count = tObj->base.last_level;
|
||||
surf.ss2.width = tObj->base.width[0] - 1;
|
||||
surf.ss2.height = tObj->base.height[0] - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -234,14 +234,9 @@ struct pipe_sampler_state
|
|||
unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */
|
||||
unsigned compare_func:3; /**< PIPE_FUNC_x */
|
||||
unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */
|
||||
float shadow_ambient; /**< shadow test fail color/intensity */
|
||||
float min_lod;
|
||||
float max_lod;
|
||||
float lod_bias;
|
||||
#if 0 /* need these? */
|
||||
int BaseLevel; /**< min mipmap level, OpenGL 1.2 */
|
||||
int MaxLevel; /**< max mipmap level, OpenGL 1.2 */
|
||||
#endif
|
||||
float shadow_ambient; /**< shadow test fail color/intensity */
|
||||
float lod_bias; /**< LOD/lambda bias */
|
||||
float min_lod, max_lod; /**< LOD clamp range, after bias */
|
||||
float border_color[4];
|
||||
float max_anisotropy;
|
||||
};
|
||||
|
|
@ -277,8 +272,7 @@ struct pipe_texture
|
|||
enum pipe_texture_target target; /**< PIPE_TEXTURE_x */
|
||||
enum pipe_format format; /**< PIPE_FORMAT_x */
|
||||
|
||||
unsigned first_level;
|
||||
unsigned last_level;
|
||||
unsigned last_level; /**< Index of last mipmap level present/defined */
|
||||
|
||||
unsigned width[PIPE_MAX_TEXTURE_LEVELS];
|
||||
unsigned height[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "sp_state.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_tile_cache.h"
|
||||
#include "pipe/draw/draw_context.h"
|
||||
|
||||
|
||||
|
||||
void *
|
||||
|
|
@ -73,6 +75,8 @@ softpipe_set_sampler_texture(struct pipe_context *pipe,
|
|||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
assert(unit < PIPE_MAX_SAMPLERS);
|
||||
softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */
|
||||
|
||||
|
|
|
|||
|
|
@ -449,7 +449,6 @@ compute_lambda(struct tgsi_sampler *sampler,
|
|||
}
|
||||
|
||||
lambda = LOG2(rho);
|
||||
|
||||
lambda += lodbias + sampler->state->lod_bias;
|
||||
lambda = CLAMP(lambda, sampler->state->min_lod, sampler->state->max_lod);
|
||||
|
||||
|
|
@ -457,7 +456,6 @@ compute_lambda(struct tgsi_sampler *sampler,
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Do several things here:
|
||||
* 1. Compute lambda from the texcoords, if needed
|
||||
|
|
@ -477,7 +475,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
|
|||
if (sampler->state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
|
||||
/* no mipmap selection needed */
|
||||
*imgFilter = sampler->state->mag_img_filter;
|
||||
*level0 = *level1 = sampler->texture->first_level;
|
||||
*level0 = *level1 = (int) sampler->state->min_lod;
|
||||
}
|
||||
else {
|
||||
float lambda;
|
||||
|
|
@ -492,7 +490,7 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
|
|||
if (lambda < 0.0) { /* XXX threshold depends on the filter */
|
||||
/* magnifying */
|
||||
*imgFilter = sampler->state->mag_img_filter;
|
||||
*level0 = *level1 = sampler->texture->first_level;
|
||||
*level0 = *level1 = 0;
|
||||
}
|
||||
else {
|
||||
/* minifying */
|
||||
|
|
@ -503,19 +501,13 @@ choose_mipmap_levels(struct tgsi_sampler *sampler,
|
|||
/* Nearest mipmap level */
|
||||
const int lvl = (int) (lambda + 0.5);
|
||||
*level0 =
|
||||
*level1 = CLAMP(lvl,
|
||||
(int) sampler->texture->first_level,
|
||||
(int) sampler->texture->last_level);
|
||||
*level1 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
|
||||
}
|
||||
else {
|
||||
/* Linear interpolation between mipmap levels */
|
||||
const int lvl = (int) lambda;
|
||||
*level0 = CLAMP(lvl,
|
||||
(int) sampler->texture->first_level,
|
||||
(int) sampler->texture->last_level);
|
||||
*level1 = CLAMP(lvl + 1,
|
||||
(int) sampler->texture->first_level,
|
||||
(int) sampler->texture->last_level);
|
||||
*level0 = CLAMP(lvl, 0, (int) sampler->texture->last_level);
|
||||
*level1 = CLAMP(lvl + 1, 0, (int) sampler->texture->last_level);
|
||||
*levelBlend = FRAC(lambda); /* blending weight between levels */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ softpipe_texture_layout(struct softpipe_texture * spt)
|
|||
|
||||
spt->buffer_size = 0;
|
||||
|
||||
for ( level = pt->first_level ; level <= pt->last_level ; level++ ) {
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
pt->width[level] = width;
|
||||
pt->height[level] = height;
|
||||
pt->depth[level] = depth;
|
||||
|
|
@ -139,6 +139,8 @@ softpipe_get_tex_surface(struct pipe_context *pipe,
|
|||
struct softpipe_texture *spt = softpipe_texture(pt);
|
||||
struct pipe_surface *ps;
|
||||
|
||||
assert(level <= pt->last_level);
|
||||
|
||||
ps = pipe->winsys->surface_alloc(pipe->winsys);
|
||||
if (ps) {
|
||||
assert(ps->refcount);
|
||||
|
|
|
|||
|
|
@ -57,15 +57,10 @@ struct st_texture_object
|
|||
{
|
||||
struct gl_texture_object base; /* The "parent" object */
|
||||
|
||||
/* The texture must include at least these levels once validated:
|
||||
/* The texture must include at levels [0..lastLevel] once validated:
|
||||
*/
|
||||
GLuint firstLevel;
|
||||
GLuint lastLevel;
|
||||
|
||||
/* Offset for firstLevel image:
|
||||
*/
|
||||
GLuint textureOffset;
|
||||
|
||||
/* On validation any active images held in main memory or in other
|
||||
* textures will be copied to this texture and the old storage freed.
|
||||
*/
|
||||
|
|
@ -585,12 +580,12 @@ st_TexImage(GLcontext * ctx,
|
|||
_mesa_align_free(texImage->Data);
|
||||
}
|
||||
|
||||
/* If this is the only texture image in the texture, could call
|
||||
/* If this is the only mipmap level in the texture, could call
|
||||
* bmBufferData with NULL data to free the old block and avoid
|
||||
* waiting on any outstanding fences.
|
||||
*/
|
||||
if (stObj->pt &&
|
||||
stObj->pt->first_level == level &&
|
||||
/*stObj->pt->first_level == level &&*/
|
||||
stObj->pt->last_level == level &&
|
||||
stObj->pt->target != PIPE_TEXTURE_CUBE &&
|
||||
!st_texture_match_image(stObj->pt, &stImage->base,
|
||||
|
|
@ -1363,13 +1358,8 @@ calculate_first_last_level(struct st_texture_object *stObj)
|
|||
firstLevel = lastLevel = tObj->BaseLevel;
|
||||
}
|
||||
else {
|
||||
firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
|
||||
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
|
||||
lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
|
||||
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
|
||||
lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
|
||||
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
|
||||
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
|
||||
firstLevel = 0;
|
||||
lastLevel = MIN2(tObj->MaxLevel - tObj->BaseLevel, baseImage->MaxLog2);
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_RECTANGLE_NV:
|
||||
|
|
@ -1380,8 +1370,6 @@ calculate_first_last_level(struct st_texture_object *stObj)
|
|||
return;
|
||||
}
|
||||
|
||||
/* save these values */
|
||||
stObj->firstLevel = firstLevel;
|
||||
stObj->lastLevel = lastLevel;
|
||||
}
|
||||
|
||||
|
|
@ -1389,15 +1377,16 @@ calculate_first_last_level(struct st_texture_object *stObj)
|
|||
static void
|
||||
copy_image_data_to_texture(struct st_context *st,
|
||||
struct st_texture_object *stObj,
|
||||
GLuint dstLevel,
|
||||
struct st_texture_image *stImage)
|
||||
{
|
||||
if (stImage->pt) {
|
||||
/* Copy potentially with the blitter:
|
||||
*/
|
||||
st_texture_image_copy(st->pipe,
|
||||
stObj->pt, /* dest texture */
|
||||
stImage->face, stImage->level,
|
||||
stImage->pt /* src texture */
|
||||
stObj->pt, dstLevel, /* dest texture, level */
|
||||
stImage->pt, /* src texture */
|
||||
stImage->face
|
||||
);
|
||||
|
||||
st->pipe->texture_release(st->pipe, &stImage->pt);
|
||||
|
|
@ -1438,7 +1427,7 @@ st_finalize_texture(GLcontext *ctx,
|
|||
const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||
int comp_byte = 0;
|
||||
int cpp;
|
||||
GLuint face, i;
|
||||
GLuint face;
|
||||
struct st_texture_image *firstImage;
|
||||
|
||||
*needFlush = GL_FALSE;
|
||||
|
|
@ -1450,7 +1439,7 @@ st_finalize_texture(GLcontext *ctx,
|
|||
/* What levels must the texture include at a minimum?
|
||||
*/
|
||||
calculate_first_last_level(stObj);
|
||||
firstImage = st_texture_image(stObj->base.Image[0][stObj->firstLevel]);
|
||||
firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
|
||||
|
||||
/* Fallback case:
|
||||
*/
|
||||
|
|
@ -1469,7 +1458,6 @@ st_finalize_texture(GLcontext *ctx,
|
|||
*/
|
||||
if (firstImage->pt &&
|
||||
firstImage->pt != stObj->pt &&
|
||||
firstImage->pt->first_level <= stObj->firstLevel &&
|
||||
firstImage->pt->last_level >= stObj->lastLevel) {
|
||||
|
||||
if (stObj->pt)
|
||||
|
|
@ -1488,18 +1476,11 @@ st_finalize_texture(GLcontext *ctx,
|
|||
|
||||
/* 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 texture isn't valid except at the
|
||||
* original start level. Hope to get around this by
|
||||
* programming minLod, maxLod, baseLevel into the hardware and
|
||||
* leaving the texture alone.
|
||||
*/
|
||||
if (stObj->pt &&
|
||||
(stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
|
||||
stObj->pt->format !=
|
||||
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) ||
|
||||
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 ||
|
||||
|
|
@ -1516,7 +1497,7 @@ st_finalize_texture(GLcontext *ctx,
|
|||
stObj->pt = st_texture_create(ctx->st,
|
||||
gl_target_to_pipe(stObj->base.Target),
|
||||
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
|
||||
stObj->firstLevel,
|
||||
0, /* first level */
|
||||
stObj->lastLevel,
|
||||
firstImage->base.Width,
|
||||
firstImage->base.Height,
|
||||
|
|
@ -1527,14 +1508,16 @@ st_finalize_texture(GLcontext *ctx,
|
|||
/* Pull in any images not in the object's texture:
|
||||
*/
|
||||
for (face = 0; face < nr_faces; face++) {
|
||||
for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) {
|
||||
GLuint level;
|
||||
for (level = 0; level <= stObj->lastLevel; level++) {
|
||||
struct st_texture_image *stImage =
|
||||
st_texture_image(stObj->base.Image[face][i]);
|
||||
//st_texture_image(stObj->base.Image[face][level]);
|
||||
st_texture_image(stObj->base.Image[face][stObj->base.BaseLevel + level]);
|
||||
|
||||
/* Need to import images in main memory or held in other textures.
|
||||
*/
|
||||
if (stObj->pt != stImage->pt) {
|
||||
copy_image_data_to_texture(ctx->st, stObj, stImage);
|
||||
copy_image_data_to_texture(ctx->st, stObj, level, stImage);
|
||||
*needFlush = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
static void *blend_cso = NULL;
|
||||
static void *depthstencil_cso = NULL;
|
||||
static void *rasterizer_cso = NULL;
|
||||
static void *sampler_cso = NULL;
|
||||
|
||||
static struct st_fragment_program *stfp = NULL;
|
||||
static struct st_vertex_program *stvp = NULL;
|
||||
|
|
@ -118,7 +117,6 @@ st_init_generate_mipmap(struct st_context *st)
|
|||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
struct pipe_sampler_state sampler;
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
|
||||
assert(!blend_cso);
|
||||
|
|
@ -133,16 +131,6 @@ st_init_generate_mipmap(struct st_context *st)
|
|||
memset(&rasterizer, 0, sizeof(rasterizer));
|
||||
rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer);
|
||||
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.normalized_coords = 1;
|
||||
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
|
||||
|
||||
stfp = make_tex_fragment_program(st->ctx);
|
||||
stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
||||
}
|
||||
|
|
@ -156,14 +144,12 @@ st_destroy_generate_mipmpap(struct st_context *st)
|
|||
pipe->delete_blend_state(pipe, blend_cso);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, depthstencil_cso);
|
||||
pipe->delete_rasterizer_state(pipe, rasterizer_cso);
|
||||
pipe->delete_sampler_state(pipe, sampler_cso);
|
||||
|
||||
/* XXX free stfp, stvp */
|
||||
|
||||
blend_cso = NULL;
|
||||
depthstencil_cso = NULL;
|
||||
rasterizer_cso = NULL;
|
||||
sampler_cso = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -248,8 +234,10 @@ st_render_mipmap(struct st_context *st,
|
|||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_framebuffer_state fb;
|
||||
struct pipe_sampler_state sampler;
|
||||
void *sampler_cso;
|
||||
const uint face = _mesa_tex_target_to_face(target), zslice = 0;
|
||||
const uint first_level_save = pt->first_level;
|
||||
/*const uint first_level_save = pt->first_level;*/
|
||||
uint dstLevel;
|
||||
|
||||
assert(target != GL_TEXTURE_3D); /* not done yet */
|
||||
|
|
@ -263,11 +251,21 @@ st_render_mipmap(struct st_context *st,
|
|||
memset(&fb, 0, sizeof(fb));
|
||||
fb.num_cbufs = 1;
|
||||
|
||||
/* sampler state */
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.normalized_coords = 1;
|
||||
|
||||
|
||||
/* bind CSOs */
|
||||
pipe->bind_blend_state(pipe, blend_cso);
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, depthstencil_cso);
|
||||
pipe->bind_rasterizer_state(pipe, rasterizer_cso);
|
||||
pipe->bind_sampler_state(pipe, 0, sampler_cso);
|
||||
|
||||
/* bind shaders */
|
||||
pipe->bind_fs_state(pipe, stfp->fs->data);
|
||||
|
|
@ -286,20 +284,29 @@ st_render_mipmap(struct st_context *st,
|
|||
fb.cbufs[0] = pipe->get_tex_surface(pipe, pt, face, dstLevel, zslice);
|
||||
pipe->set_framebuffer_state(pipe, &fb);
|
||||
|
||||
/*
|
||||
* Setup sampler state
|
||||
*/
|
||||
sampler.min_lod = sampler.max_lod = srcLevel;
|
||||
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
|
||||
pipe->bind_sampler_state(pipe, 0, sampler_cso);
|
||||
|
||||
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
|
||||
|
||||
/*
|
||||
* Setup src texture, override pt->first_level so we sample from
|
||||
* the right mipmap level.
|
||||
*/
|
||||
pt->first_level = srcLevel;
|
||||
/*pt->first_level = srcLevel;*/
|
||||
pipe->set_sampler_texture(pipe, 0, pt);
|
||||
|
||||
draw_quad(st->ctx);
|
||||
|
||||
pipe->delete_sampler_state(pipe, sampler_cso);
|
||||
}
|
||||
|
||||
/* restore first_level */
|
||||
pt->first_level = first_level_save;
|
||||
/*pt->first_level = first_level_save;*/
|
||||
|
||||
/* restore pipe state */
|
||||
if (st->state.rasterizer)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ target_to_target(GLenum target)
|
|||
|
||||
/**
|
||||
* Allocate a new pipe_texture object
|
||||
* width0, height0, depth0 are the dimensions of the level 0 image
|
||||
* (the highest resolution). last_level indicates how many mipmap levels
|
||||
* to allocate storage for. For non-mipmapped textures, this will be zero.
|
||||
* XXX first_level obsolete
|
||||
*/
|
||||
struct pipe_texture *
|
||||
st_texture_create(struct st_context *st,
|
||||
|
|
@ -84,9 +88,9 @@ st_texture_create(struct st_context *st,
|
|||
|
||||
assert(format);
|
||||
|
||||
memset(&pt, 0, sizeof(pt));
|
||||
pt.target = target;
|
||||
pt.format = format;
|
||||
pt.first_level = first_level;
|
||||
pt.last_level = last_level;
|
||||
pt.width[0] = width0;
|
||||
pt.height[0] = height0;
|
||||
|
|
@ -266,23 +270,36 @@ st_texture_image_data(struct pipe_context *pipe,
|
|||
*/
|
||||
void
|
||||
st_texture_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct pipe_texture *src)
|
||||
struct pipe_texture *dst, GLuint dstLevel,
|
||||
struct pipe_texture *src,
|
||||
GLuint face)
|
||||
{
|
||||
GLuint width = src->width[level];
|
||||
GLuint height = src->height[level];
|
||||
GLuint depth = src->depth[level];
|
||||
GLuint width = dst->width[dstLevel];
|
||||
GLuint height = dst->height[dstLevel];
|
||||
GLuint depth = dst->depth[dstLevel];
|
||||
struct pipe_surface *src_surface;
|
||||
struct pipe_surface *dst_surface;
|
||||
GLuint i;
|
||||
|
||||
/* XXX this is a hack */
|
||||
if (dst->compressed)
|
||||
height /= 4;
|
||||
|
||||
for (i = 0; i < depth; i++) {
|
||||
dst_surface = pipe->get_tex_surface(pipe, dst, face, level, i);
|
||||
src_surface = pipe->get_tex_surface(pipe, src, face, level, i);
|
||||
GLuint srcLevel;
|
||||
|
||||
/* find src texture level of needed size */
|
||||
for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
|
||||
if (src->width[srcLevel] == width &&
|
||||
src->height[srcLevel] == height) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(src->width[srcLevel] == width);
|
||||
assert(src->height[srcLevel] == height);
|
||||
|
||||
dst_surface = pipe->get_tex_surface(pipe, dst, face, dstLevel, i);
|
||||
src_surface = pipe->get_tex_surface(pipe, src, face, srcLevel, i);
|
||||
|
||||
pipe->surface_copy(pipe,
|
||||
dst_surface,
|
||||
|
|
|
|||
|
|
@ -98,9 +98,9 @@ st_texture_image_data(struct pipe_context *pipe,
|
|||
*/
|
||||
extern void
|
||||
st_texture_image_copy(struct pipe_context *pipe,
|
||||
struct pipe_texture *dst,
|
||||
GLuint face, GLuint level,
|
||||
struct pipe_texture *src);
|
||||
struct pipe_texture *dst, GLuint dstLevel,
|
||||
struct pipe_texture *src,
|
||||
GLuint face);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue