nv30: fix some s3tc layout issues
s3tc layouts are a bit finicky - they're packed, but not swizzled. Adjust logic to allow for that case: - Don't set a uniform pitch for POT-sized compressed textures - Adjust define_rect API to be less confused about block sizes - Only mark a texture as linear if it has a uniform pitch set This has been tested to fix xonotic (as well as the s3tc-* piglits) on nv3x and keeps it working on nv4x. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
ad251330e8
commit
207fb558e4
|
@ -116,8 +116,22 @@ define_rect(struct pipe_resource *pt, unsigned level, unsigned z,
|
|||
|
||||
rect->x0 = util_format_get_nblocksx(pt->format, x) << mt->ms_x;
|
||||
rect->y0 = util_format_get_nblocksy(pt->format, y) << mt->ms_y;
|
||||
rect->x1 = rect->x0 + (w << mt->ms_x);
|
||||
rect->y1 = rect->y0 + (h << mt->ms_y);
|
||||
rect->x1 = rect->x0 + (util_format_get_nblocksx(pt->format, w) << mt->ms_x);
|
||||
rect->y1 = rect->y0 + (util_format_get_nblocksy(pt->format, h) << mt->ms_y);
|
||||
|
||||
/* XXX There's some indication that swizzled formats > 4 bytes are treated
|
||||
* differently. However that only applies to RGBA16_FLOAT, RGBA32_FLOAT,
|
||||
* and the DXT* formats. The former aren't properly supported yet, and the
|
||||
* latter avoid swizzled layouts.
|
||||
|
||||
if (mt->swizzled && rect->cpp > 4) {
|
||||
unsigned scale = rect->cpp / 4;
|
||||
rect->w *= scale;
|
||||
rect->x0 *= scale;
|
||||
rect->x1 *= scale;
|
||||
rect->cpp = 4;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -286,7 +300,7 @@ nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt,
|
|||
tx->nblocksy = util_format_get_nblocksy(pt->format, box->height);
|
||||
|
||||
define_rect(pt, level, box->z, box->x, box->y,
|
||||
tx->nblocksx, tx->nblocksy, &tx->img);
|
||||
box->width, box->height, &tx->img);
|
||||
|
||||
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
|
||||
tx->base.layer_stride * tx->base.box.depth, NULL,
|
||||
|
@ -435,8 +449,7 @@ nv30_miptree_create(struct pipe_screen *pscreen,
|
|||
!util_is_power_of_two_or_zero(pt->width0) ||
|
||||
!util_is_power_of_two_or_zero(pt->height0) ||
|
||||
!util_is_power_of_two_or_zero(pt->depth0) ||
|
||||
util_format_is_compressed(pt->format) ||
|
||||
util_format_is_float(pt->format) || mt->ms_mode) {
|
||||
mt->ms_mode) {
|
||||
mt->uniform_pitch = util_format_get_nblocksx(pt->format, w) * blocksz;
|
||||
mt->uniform_pitch = align(mt->uniform_pitch, 64);
|
||||
if (pt->bind & PIPE_BIND_SCANOUT) {
|
||||
|
@ -449,8 +462,14 @@ nv30_miptree_create(struct pipe_screen *pscreen,
|
|||
}
|
||||
}
|
||||
|
||||
if (!mt->uniform_pitch)
|
||||
if (util_format_is_compressed(pt->format)) {
|
||||
// Compressed (DXT) formats are packed tightly. We don't mark them as
|
||||
// swizzled, since their layout is largely linear. However we do end up
|
||||
// omitting the LINEAR flag when texturing them, as the levels are not
|
||||
// uniformly sized (for POT sizes).
|
||||
} else if (!mt->uniform_pitch) {
|
||||
mt->swizzled = true;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
|
|
|
@ -287,7 +287,7 @@ nv30_sampler_view_create(struct pipe_context *pipe, struct pipe_resource *pt,
|
|||
so->npot_size0 = (pt->width0 << 16) | pt->height0;
|
||||
if (eng3d->oclass >= NV40_3D_CLASS) {
|
||||
so->npot_size1 = (pt->depth0 << 20) | mt->uniform_pitch;
|
||||
if (!mt->swizzled)
|
||||
if (mt->uniform_pitch)
|
||||
so->fmt |= NV40_3D_TEX_FORMAT_LINEAR;
|
||||
so->fmt |= 0x00008000;
|
||||
so->fmt |= (pt->last_level + 1) << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
|
||||
|
|
Loading…
Reference in New Issue