mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 18:00:24 +01:00
nouveau: remove useless NOUVEAU_BO_SWIZZLED flag, copy/paste nv40 work to swizzle textures
This commit is contained in:
parent
fd2492d244
commit
6432d03c3d
6 changed files with 167 additions and 42 deletions
|
|
@ -37,7 +37,6 @@
|
|||
#define NOUVEAU_BO_LOCAL (1 << 9)
|
||||
#define NOUVEAU_BO_TILED (1 << 10)
|
||||
#define NOUVEAU_BO_ZTILE (1 << 11)
|
||||
#define NOUVEAU_BO_SWIZZLED (1 << 12)
|
||||
#define NOUVEAU_BO_DUMMY (1 << 31)
|
||||
|
||||
struct nouveau_bo {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ static INLINE int log2i(int i)
|
|||
return r;
|
||||
}
|
||||
|
||||
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,swsurf) \
|
||||
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
|
||||
{ \
|
||||
TRUE, \
|
||||
PIPE_FORMAT_##m, \
|
||||
|
|
@ -34,8 +34,7 @@ static INLINE int log2i(int i)
|
|||
(NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
|
||||
NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
|
||||
NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
|
||||
NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \
|
||||
swsurf \
|
||||
NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w) \
|
||||
}
|
||||
|
||||
struct nv30_texture_format {
|
||||
|
|
@ -43,25 +42,24 @@ struct nv30_texture_format {
|
|||
uint pipe;
|
||||
int format;
|
||||
int swizzle;
|
||||
int swizzled_surface;
|
||||
};
|
||||
|
||||
static struct nv30_texture_format
|
||||
nv30_texture_formats[] = {
|
||||
_(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W, 1),
|
||||
_(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W, 1),
|
||||
_(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W, 1),
|
||||
_(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W, 1),
|
||||
_(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X, 1),
|
||||
_(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X, 1),
|
||||
_(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X, 1),
|
||||
_(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y, 1),
|
||||
// _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X, 0),
|
||||
// _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X, 0),
|
||||
_(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W, 0),
|
||||
_(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W, 0),
|
||||
_(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W, 0),
|
||||
_(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W, 0),
|
||||
_(A8R8G8B8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(A1R5G5B5_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(A4R4G4B4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(R5G6B5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W),
|
||||
_(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X),
|
||||
_(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X),
|
||||
_(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X),
|
||||
_(A8L8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y),
|
||||
// _(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X),
|
||||
// _(Z24S8_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X),
|
||||
_(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W),
|
||||
_(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W),
|
||||
{},
|
||||
};
|
||||
|
||||
|
|
@ -90,16 +88,13 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
|
|||
struct pipe_texture *pt = &nv30mt->base;
|
||||
struct nv30_texture_format *tf;
|
||||
struct nouveau_stateobj *so;
|
||||
uint32_t txf, txs /*, txp*/;
|
||||
/*int swizzled = 0;*/ /*XXX: implement in region code? */
|
||||
uint32_t txf, txs , txp;
|
||||
unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
|
||||
|
||||
tf = nv30_fragtex_format(pt->format);
|
||||
if (!tf)
|
||||
assert(0);
|
||||
|
||||
tex_flags |= (tf->swizzled_surface ? NOUVEAU_BO_SWIZZLED : 0);
|
||||
|
||||
txf = tf->format;
|
||||
txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
|
||||
txf |= log2i(pt->width[0]) << 20;
|
||||
|
|
@ -125,6 +120,13 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
|
||||
txp = 0;
|
||||
} else {
|
||||
txp = nv30mt->level[0].pitch;
|
||||
txf |= (1<<13) /*FIXME: NV34TCL_TX_FORMAT_LINEAR ? */;
|
||||
}
|
||||
|
||||
txs = tf->swizzle;
|
||||
|
||||
so = so_new(16, 2);
|
||||
|
|
|
|||
|
|
@ -65,6 +65,29 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|||
mt->base = *pt;
|
||||
mt->base.refcount = 1;
|
||||
mt->base.screen = pscreen;
|
||||
mt->shadow_tex = NULL;
|
||||
mt->shadow_surface = NULL;
|
||||
|
||||
/* Swizzled textures must be POT */
|
||||
if (pt->width[0] & (pt->width[0] - 1) ||
|
||||
pt->height[0] & (pt->height[0] - 1))
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else
|
||||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
|
||||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET))
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
else {
|
||||
switch (pt->format) {
|
||||
/* TODO: Figure out which formats can be swizzled */
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
||||
/* XXX: Re-enable when SIFM size limits are fixed */
|
||||
/*case PIPE_FORMAT_R16_SNORM:*/
|
||||
break;
|
||||
default:
|
||||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
nv30_miptree_layout(mt);
|
||||
|
||||
|
|
@ -81,22 +104,29 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
|
|||
}
|
||||
|
||||
static void
|
||||
nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **pt)
|
||||
nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
|
||||
{
|
||||
struct pipe_texture *mt = *pt;
|
||||
struct pipe_texture *pt = *ppt;
|
||||
struct nv30_miptree *mt = (struct nv30_miptree *)pt;
|
||||
int l;
|
||||
|
||||
*pt = NULL;
|
||||
if (--mt->refcount <= 0) {
|
||||
struct nv30_miptree *nv30mt = (struct nv30_miptree *)mt;
|
||||
int l;
|
||||
*ppt = NULL;
|
||||
if (--pt->refcount)
|
||||
return;
|
||||
|
||||
pipe_buffer_reference(pscreen, &nv30mt->buffer, NULL);
|
||||
for (l = 0; l <= mt->last_level; l++) {
|
||||
if (nv30mt->level[l].image_offset)
|
||||
FREE(nv30mt->level[l].image_offset);
|
||||
}
|
||||
FREE(nv30mt);
|
||||
pipe_buffer_reference(pscreen, &mt->buffer, NULL);
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
if (mt->level[l].image_offset)
|
||||
FREE(mt->level[l].image_offset);
|
||||
}
|
||||
|
||||
if (mt->shadow_tex) {
|
||||
assert(mt->shadow_surface);
|
||||
pscreen->tex_surface_release(pscreen, &mt->shadow_surface);
|
||||
nv30_miptree_release(pscreen, &mt->shadow_tex);
|
||||
}
|
||||
|
||||
FREE(mt);
|
||||
}
|
||||
|
||||
static struct pipe_surface *
|
||||
|
|
@ -123,6 +153,9 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
|||
ps->status = PIPE_SURFACE_STATUS_DEFINED;
|
||||
ps->refcount = 1;
|
||||
ps->winsys = pscreen->winsys;
|
||||
ps->face = face;
|
||||
ps->level = level;
|
||||
ps->zslice = zslice;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
||||
ps->offset = nv30mt->level[level].image_offset[face];
|
||||
|
|
|
|||
|
|
@ -128,22 +128,73 @@ static void *
|
|||
nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
|
||||
unsigned flags )
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
void *map;
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct pipe_surface *surface_to_map;
|
||||
void *map;
|
||||
|
||||
map = ws->buffer_map(ws, surface->buffer, flags);
|
||||
if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
|
||||
struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture;
|
||||
|
||||
if (!mt->shadow_tex) {
|
||||
unsigned old_tex_usage = surface->texture->tex_usage;
|
||||
surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR;
|
||||
mt->shadow_tex = screen->texture_create(screen, surface->texture);
|
||||
surface->texture->tex_usage = old_tex_usage;
|
||||
|
||||
assert(mt->shadow_tex->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR);
|
||||
mt->shadow_surface = screen->get_tex_surface
|
||||
(
|
||||
screen, mt->shadow_tex,
|
||||
surface->face, surface->level, surface->zslice,
|
||||
surface->usage
|
||||
);
|
||||
}
|
||||
|
||||
surface_to_map = mt->shadow_surface;
|
||||
}
|
||||
else
|
||||
surface_to_map = surface;
|
||||
|
||||
assert(surface_to_map);
|
||||
|
||||
map = ws->buffer_map(ws, surface_to_map->buffer, flags);
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
return map + surface->offset;
|
||||
return map + surface_to_map->offset;
|
||||
}
|
||||
|
||||
static void
|
||||
nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct pipe_surface *surface_to_unmap;
|
||||
|
||||
ws->buffer_unmap(ws, surface->buffer);
|
||||
/* TODO: Copy from shadow just before push buffer is flushed instead.
|
||||
There are probably some programs that map/unmap excessively
|
||||
before rendering. */
|
||||
if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
|
||||
struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture;
|
||||
|
||||
assert(mt->shadow_tex);
|
||||
|
||||
surface_to_unmap = mt->shadow_surface;
|
||||
}
|
||||
else
|
||||
surface_to_unmap = surface;
|
||||
|
||||
assert(surface_to_unmap);
|
||||
|
||||
ws->buffer_unmap(ws, surface_to_unmap->buffer);
|
||||
|
||||
if (surface_to_unmap != surface) {
|
||||
struct nv30_screen *nvscreen = nv30_screen(screen);
|
||||
|
||||
nvscreen->nvws->surface_copy(nvscreen->nvws,
|
||||
surface, 0, 0,
|
||||
surface_to_unmap, 0, 0,
|
||||
surface->width, surface->height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -76,6 +76,9 @@ struct nv30_miptree {
|
|||
struct pipe_buffer *buffer;
|
||||
uint total_size;
|
||||
|
||||
struct pipe_texture *shadow_tex;
|
||||
struct pipe_surface *shadow_surface;
|
||||
|
||||
struct {
|
||||
uint pitch;
|
||||
uint *image_offset;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,31 @@
|
|||
#include "nv30_context.h"
|
||||
|
||||
static INLINE int log2i(int i)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (i & 0xffff0000) {
|
||||
i >>= 16;
|
||||
r += 16;
|
||||
}
|
||||
if (i & 0x0000ff00) {
|
||||
i >>= 8;
|
||||
r += 8;
|
||||
}
|
||||
if (i & 0x000000f0) {
|
||||
i >>= 4;
|
||||
r += 4;
|
||||
}
|
||||
if (i & 0x0000000c) {
|
||||
i >>= 2;
|
||||
r += 2;
|
||||
}
|
||||
if (i & 0x00000002) {
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv30_state_framebuffer_validate(struct nv30_context *nv30)
|
||||
{
|
||||
|
|
@ -31,7 +57,18 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
|
|||
zeta = fb->zsbuf;
|
||||
}
|
||||
|
||||
rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
|
||||
if (!(rt[0]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
|
||||
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
|
||||
for (i = 1; i < fb->num_cbufs; i++)
|
||||
assert(!(rt[i]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
|
||||
|
||||
/* FIXME: NV34TCL_RT_FORMAT_LOG2_[WIDTH/HEIGHT] */
|
||||
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
|
||||
log2i(fb->width) << 16 /*NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT*/ |
|
||||
log2i(fb->height) << 24 /*NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT*/;
|
||||
}
|
||||
else
|
||||
rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
|
||||
|
||||
switch (colour_format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue