nouveau: remove useless NOUVEAU_BO_SWIZZLED flag, copy/paste nv40 work to swizzle textures

This commit is contained in:
Patrice Mandin 2008-12-12 17:22:41 +01:00
parent fd2492d244
commit 6432d03c3d
6 changed files with 167 additions and 42 deletions

View file

@ -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 {

View file

@ -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);

View file

@ -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];

View file

@ -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

View file

@ -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;

View file

@ -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: