mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
nvfx: refactor sampling code, add support for swizzles and depth tex
This is a significant refactoring of the sampling code that: - Moves all generic functions in nvfx_fragtex.c - Adds a driver-specific sampler view structure and uses it to precompute texture setup as it should be done - Unifies a bit more of code between nv30 and nv40 - Adds support for sampler view swizzles - Support for specifying as sampler view format different from the resource one (only trivially) - Support for sampler view specification of first and last level - Support for depth textures on nv30, both for reading depth and for compare - Support for sRGB textures - Unifies the format table between nv30 and nv40 - Expands the format table to include essentially all supportable formats except mixed sign and "autonormal" formats - Fixes the "is format supported" logic, which was quite broken, and makes it use the format table Only tested on nv30 currently.
This commit is contained in:
parent
4e2080a86e
commit
73b7c6fb33
9 changed files with 530 additions and 398 deletions
|
|
@ -6328,6 +6328,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define NV34TCL_TX_FORMAT_FORMAT_R8G8B8_RECT 0x00001e00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_A8L8_RECT 0x00002000
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DSDT8 0x00002800
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_Z24 0x2a00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_Z24_RECT 0x2b00 /* XXX: guess! */
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_Z16 0x2c00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_Z16_RECT 0x2d00 /* XXX: guess! */
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_HILO16 0x00003300
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_HILO16_RECT 0x00003600
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_HILO8 0x00004400
|
||||
|
|
|
|||
|
|
@ -10,88 +10,75 @@ nv30_sampler_state_init(struct pipe_context *pipe,
|
|||
struct nvfx_sampler_state *ps,
|
||||
const struct pipe_sampler_state *cso)
|
||||
{
|
||||
if (cso->max_anisotropy >= 8) {
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 4) {
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 2) {
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
|
||||
}
|
||||
float limit;
|
||||
|
||||
if (cso->max_anisotropy >= 2)
|
||||
{
|
||||
float limit;
|
||||
|
||||
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
|
||||
ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
|
||||
|
||||
limit = CLAMP(cso->max_lod, 0.0, 15.0);
|
||||
ps->en |= (int)(limit) << 14 /*NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT*/;
|
||||
|
||||
limit = CLAMP(cso->min_lod, 0.0, 15.0);
|
||||
ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/;
|
||||
if (cso->max_anisotropy >= 8)
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
|
||||
else if (cso->max_anisotropy >= 4)
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
|
||||
else if (cso->max_anisotropy >= 2)
|
||||
ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
|
||||
}
|
||||
|
||||
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
|
||||
ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
|
||||
|
||||
ps->max_lod = (int)CLAMP(cso->max_lod, 0.0, 15.0);
|
||||
ps->min_lod = (int)CLAMP(cso->min_lod, 0.0, 15.0);
|
||||
|
||||
ps->en |= NV34TCL_TX_ENABLE_ENABLE;
|
||||
}
|
||||
|
||||
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
|
||||
[PIPE_FORMAT_##m] = { \
|
||||
NV34TCL_TX_FORMAT_FORMAT_##tf, \
|
||||
NV34TCL_TX_FORMAT_FORMAT_##tf##_RECT, \
|
||||
(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) \
|
||||
void
|
||||
nv30_sampler_view_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_view *sv)
|
||||
{
|
||||
struct pipe_resource* pt = sv->base.texture;
|
||||
struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
|
||||
unsigned txf;
|
||||
unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
|
||||
|
||||
assert(tf->fmt[0] >= 0);
|
||||
|
||||
txf = sv->u.init_fmt;
|
||||
txf |= (level != sv->base.last_level ? NV34TCL_TX_FORMAT_MIPMAP : 0);
|
||||
txf |= log2i(u_minify(pt->width0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
|
||||
txf |= log2i(u_minify(pt->height0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
|
||||
txf |= log2i(u_minify(pt->depth0, level)) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
|
||||
txf |= 0x10000;
|
||||
|
||||
sv->u.nv30.fmt[0] = tf->fmt[0] | txf;
|
||||
sv->u.nv30.fmt[1] = tf->fmt[1] | txf;
|
||||
sv->u.nv30.fmt[2] = tf->fmt[2] | txf;
|
||||
sv->u.nv30.fmt[3] = tf->fmt[3] | txf;
|
||||
|
||||
sv->swizzle |= (nvfx_subresource_pitch(pt, 0) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT);
|
||||
|
||||
if(pt->height0 <= 1 || util_format_is_compressed(sv->base.format))
|
||||
sv->u.nv30.rect = -1;
|
||||
else
|
||||
sv->u.nv30.rect = !!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR);
|
||||
|
||||
sv->lod_offset = sv->base.first_level - level;
|
||||
sv->max_lod_limit = sv->base.last_level - level;
|
||||
}
|
||||
|
||||
struct nv30_texture_format {
|
||||
int format;
|
||||
int rect_format;
|
||||
int swizzle;
|
||||
};
|
||||
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT1_RECT NV34TCL_TX_FORMAT_FORMAT_DXT1
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT3_RECT NV34TCL_TX_FORMAT_FORMAT_DXT3
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT5_RECT NV34TCL_TX_FORMAT_FORMAT_DXT5
|
||||
|
||||
static struct nv30_texture_format
|
||||
nv30_texture_formats[PIPE_FORMAT_COUNT] = {
|
||||
[0 ... PIPE_FORMAT_COUNT - 1] = {-1, 0, 0},
|
||||
_(B8G8R8X8_UNORM, A8R8G8B8, S1, S1, S1, ONE, X, Y, Z, W),
|
||||
_(B8G8R8A8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(B5G5R5A1_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(B4G4R4A4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W),
|
||||
_(B5G6R5_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),
|
||||
_(L8A8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y),
|
||||
_(Z16_UNORM , R5G6B5 , S1, S1, S1, ONE, X, X, X, X),
|
||||
_(S8_USCALED_Z24_UNORM , A8R8G8B8, 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),
|
||||
{},
|
||||
};
|
||||
|
||||
void
|
||||
nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
|
||||
{
|
||||
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
|
||||
struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
struct nv30_texture_format *tf;
|
||||
struct nvfx_sampler_view* sv = (struct nvfx_sampler_view*)nvfx->fragment_sampler_views[unit];
|
||||
struct nouveau_bo *bo = ((struct nvfx_miptree *)sv->base.texture)->base.bo;
|
||||
struct nouveau_channel* chan = nvfx->screen->base.channel;
|
||||
uint32_t txf, txs;
|
||||
unsigned txf;
|
||||
unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
|
||||
unsigned use_rect;
|
||||
unsigned max_lod = MIN2(ps->max_lod + sv->lod_offset, sv->max_lod_limit);
|
||||
unsigned min_lod = MIN2(ps->min_lod + sv->lod_offset, max_lod) ;
|
||||
|
||||
tf = &nv30_texture_formats[pt->format];
|
||||
assert(tf->format >= 0);
|
||||
|
||||
if(pt->height0 <= 1 || util_format_is_compressed(pt->format))
|
||||
if(sv->u.nv30.rect < 0)
|
||||
{
|
||||
/* in the case of compressed or 1D textures, we can get away with this,
|
||||
* since the layout is the same
|
||||
|
|
@ -100,9 +87,9 @@ nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
|
|||
}
|
||||
else
|
||||
{
|
||||
static int warned = 0;
|
||||
if(!warned && !ps->fmt != !(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)) {
|
||||
warned = 1;
|
||||
static boolean warned = FALSE;
|
||||
if( !!ps->fmt != sv->u.nv30.rect && !warned) {
|
||||
warned = TRUE;
|
||||
fprintf(stderr,
|
||||
"Unimplemented: coordinate normalization mismatch. Possible reasons:\n"
|
||||
"1. ARB_texture_non_power_of_two is being used despite the fact it isn't supported\n"
|
||||
|
|
@ -110,51 +97,22 @@ nv30_fragtex_set(struct nvfx_context *nvfx, int unit)
|
|||
"3. The state tracker is not supported\n");
|
||||
}
|
||||
|
||||
use_rect = pt->flags & NVFX_RESOURCE_FLAG_LINEAR;
|
||||
use_rect = sv->u.nv30.rect;
|
||||
}
|
||||
|
||||
txf = use_rect ? tf->rect_format : tf->format;
|
||||
txf |= ((pt->last_level>0) ? NV34TCL_TX_FORMAT_MIPMAP : 0);
|
||||
txf |= log2i(pt->width0) << NV34TCL_TX_FORMAT_BASE_SIZE_U_SHIFT;
|
||||
txf |= log2i(pt->height0) << NV34TCL_TX_FORMAT_BASE_SIZE_V_SHIFT;
|
||||
txf |= log2i(pt->depth0) << NV34TCL_TX_FORMAT_BASE_SIZE_W_SHIFT;
|
||||
txf |= NV34TCL_TX_FORMAT_NO_BORDER | 0x10000;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
txf |= NV34TCL_TX_FORMAT_CUBIC;
|
||||
/* fall-through */
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_2D;
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_3D;
|
||||
break;
|
||||
case PIPE_TEXTURE_1D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_1D;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
||||
return;
|
||||
}
|
||||
|
||||
txs = tf->swizzle;
|
||||
|
||||
if(use_rect)
|
||||
txs |= nvfx_subresource_pitch(&mt->base, 0) << NV34TCL_TX_SWIZZLE_RECT_PITCH_SHIFT;
|
||||
txf = sv->u.nv30.fmt[ps->compare + (use_rect ? 2 : 0)];
|
||||
|
||||
MARK_RING(chan, 9, 2);
|
||||
OUT_RING(chan, RING_3D(NV34TCL_TX_OFFSET(unit), 8));
|
||||
OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
OUT_RELOC(chan, bo, txf, tex_flags | NOUVEAU_BO_OR,
|
||||
NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
|
||||
OUT_RING(chan, ps->wrap);
|
||||
OUT_RING(chan, NV34TCL_TX_ENABLE_ENABLE | ps->en);
|
||||
OUT_RING(chan, txs);
|
||||
OUT_RING(chan, ps->filt | 0x2000 /*voodoo*/);
|
||||
OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
|
||||
pt->height0);
|
||||
OUT_RELOC(chan, bo, sv->offset, tex_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
OUT_RELOC(chan, bo, txf,
|
||||
tex_flags | NOUVEAU_BO_OR,
|
||||
NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
|
||||
OUT_RING(chan, (ps->wrap & sv->wrap_mask) | sv->wrap);
|
||||
OUT_RING(chan, ps->en | (min_lod << NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT) | (max_lod << NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT));
|
||||
OUT_RING(chan, sv->swizzle);
|
||||
OUT_RING(chan, ps->filt | sv->filt);
|
||||
OUT_RING(chan, sv->npot_size);
|
||||
OUT_RING(chan, ps->bcol);
|
||||
|
||||
nvfx->hw_txf[unit] = txf;
|
||||
|
|
|
|||
|
|
@ -8,149 +8,97 @@ nv40_sampler_state_init(struct pipe_context *pipe,
|
|||
struct nvfx_sampler_state *ps,
|
||||
const struct pipe_sampler_state *cso)
|
||||
{
|
||||
float limit;
|
||||
if (cso->max_anisotropy >= 2) {
|
||||
/* no idea, binary driver sets it, works without it.. meh.. */
|
||||
ps->wrap |= (1 << 5);
|
||||
|
||||
if (cso->max_anisotropy >= 16) {
|
||||
if (cso->max_anisotropy >= 16)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 12) {
|
||||
else if (cso->max_anisotropy >= 12)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 10) {
|
||||
else if (cso->max_anisotropy >= 10)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 8) {
|
||||
else if (cso->max_anisotropy >= 8)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 6) {
|
||||
else if (cso->max_anisotropy >= 6)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
|
||||
} else
|
||||
if (cso->max_anisotropy >= 4) {
|
||||
else if (cso->max_anisotropy >= 4)
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
|
||||
} else {
|
||||
else
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
float limit;
|
||||
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
|
||||
ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
|
||||
|
||||
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
|
||||
ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
|
||||
ps->max_lod = (int)(CLAMP(cso->max_lod, 0.0, 15.0) * 256.0);
|
||||
ps->min_lod = (int)(CLAMP(cso->min_lod, 0.0, 15.0) * 256.0);
|
||||
|
||||
limit = CLAMP(cso->max_lod, 0.0, 15.0);
|
||||
ps->en |= (int)(limit * 256.0) << 7;
|
||||
ps->en |= NV40TCL_TEX_ENABLE_ENABLE;
|
||||
}
|
||||
|
||||
limit = CLAMP(cso->min_lod, 0.0, 15.0);
|
||||
ps->en |= (int)(limit * 256.0) << 19;
|
||||
void
|
||||
nv40_sampler_view_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_view *sv)
|
||||
{
|
||||
struct pipe_resource* pt = sv->base.texture;
|
||||
struct nvfx_miptree* mt = (struct nvfx_miptree*)pt;
|
||||
struct nvfx_texture_format *tf = &nvfx_texture_formats[sv->base.format];
|
||||
unsigned txf;
|
||||
unsigned level = pt->target == PIPE_TEXTURE_CUBE ? 0 : sv->base.first_level;
|
||||
assert(tf->fmt[4] >= 0);
|
||||
|
||||
txf = sv->u.init_fmt;
|
||||
txf |= 0x8000;
|
||||
if(pt->target == PIPE_TEXTURE_CUBE)
|
||||
txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
|
||||
else
|
||||
txf |= (((sv->base.last_level - sv->base.first_level) + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
|
||||
|
||||
if (!mt->linear_pitch)
|
||||
sv->u.nv40.npot_size2 = 0;
|
||||
else {
|
||||
sv->u.nv40.npot_size2 = mt->linear_pitch;
|
||||
txf |= NV40TCL_TEX_FORMAT_LINEAR;
|
||||
}
|
||||
|
||||
sv->u.nv40.fmt[0] = tf->fmt[4] | txf;
|
||||
sv->u.nv40.fmt[1] = tf->fmt[5] | txf;
|
||||
|
||||
sv->u.nv40.npot_size2 |= (u_minify(pt->depth0, level) << NV40TCL_TEX_SIZE1_DEPTH_SHIFT);
|
||||
|
||||
sv->lod_offset = (sv->base.first_level - level) * 256;
|
||||
sv->max_lod_limit = (sv->base.last_level - level) * 256;
|
||||
}
|
||||
|
||||
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
|
||||
[PIPE_FORMAT_##m] = { \
|
||||
NV40TCL_TEX_FORMAT_FORMAT_##tf, \
|
||||
(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), \
|
||||
((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) | \
|
||||
(NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw)) \
|
||||
}
|
||||
|
||||
struct nv40_texture_format {
|
||||
int format;
|
||||
int swizzle;
|
||||
int sign;
|
||||
};
|
||||
|
||||
static struct nv40_texture_format
|
||||
nv40_texture_formats[PIPE_FORMAT_COUNT] = {
|
||||
[0 ... PIPE_FORMAT_COUNT - 1] = {-1, 0, 0},
|
||||
_(B8G8R8X8_UNORM, A8R8G8B8, S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(B8G8R8A8_UNORM, A8R8G8B8, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(B5G5R5A1_UNORM, A1R5G5B5, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(B4G4R4A4_UNORM, A4R4G4B4, S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(B5G6R5_UNORM , R5G6B5 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(L8_UNORM , L8 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0),
|
||||
_(A8_UNORM , L8 , ZERO, ZERO, ZERO, S1, X, X, X, X, 0, 0, 0, 0),
|
||||
_(R16_SNORM , A16 , ZERO, ZERO, S1, ONE, X, X, X, Y, 1, 1, 1, 1),
|
||||
_(I8_UNORM , L8 , S1, S1, S1, S1, X, X, X, X, 0, 0, 0, 0),
|
||||
_(L8A8_UNORM , A8L8 , S1, S1, S1, S1, X, X, X, Y, 0, 0, 0, 0),
|
||||
_(Z16_UNORM , Z16 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0),
|
||||
_(S8_USCALED_Z24_UNORM , Z24 , S1, S1, S1, ONE, X, X, X, X, 0, 0, 0, 0),
|
||||
_(DXT1_RGB , DXT1 , S1, S1, S1, ONE, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(DXT1_RGBA , DXT1 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(DXT3_RGBA , DXT3 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
_(DXT5_RGBA , DXT5 , S1, S1, S1, S1, X, Y, Z, W, 0, 0, 0, 0),
|
||||
{},
|
||||
};
|
||||
|
||||
void
|
||||
nv40_fragtex_set(struct nvfx_context *nvfx, int unit)
|
||||
{
|
||||
struct nouveau_channel* chan = nvfx->screen->base.channel;
|
||||
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
|
||||
struct nvfx_miptree *mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
|
||||
struct nouveau_bo *bo = mt->base.bo;
|
||||
struct pipe_resource *pt = &mt->base.base;
|
||||
struct nv40_texture_format *tf;
|
||||
|
||||
uint32_t txf, txs, txp;
|
||||
struct nvfx_sampler_view* sv = (struct nvfx_sampler_view*)nvfx->fragment_sampler_views[unit];
|
||||
struct nouveau_bo *bo = ((struct nvfx_miptree *)sv->base.texture)->base.bo;
|
||||
unsigned tex_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
|
||||
unsigned txf;
|
||||
unsigned max_lod = MIN2(ps->max_lod + sv->lod_offset, sv->max_lod_limit);
|
||||
unsigned min_lod = MIN2(ps->min_lod + sv->lod_offset, max_lod);
|
||||
|
||||
tf = &nv40_texture_formats[pt->format];
|
||||
assert(tf->format >= 0);
|
||||
txf = sv->u.nv40.fmt[ps->compare] | ps->fmt;
|
||||
|
||||
txf = ps->fmt;
|
||||
txf |= tf->format | 0x8000;
|
||||
txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
|
||||
|
||||
if (1) /* XXX */
|
||||
txf |= NV34TCL_TX_FORMAT_NO_BORDER;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
txf |= NV34TCL_TX_FORMAT_CUBIC;
|
||||
/* fall-through */
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_2D;
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_3D;
|
||||
break;
|
||||
case PIPE_TEXTURE_1D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_1D;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mt->linear_pitch)
|
||||
txp = 0;
|
||||
else {
|
||||
txp = mt->linear_pitch;
|
||||
txf |= NV40TCL_TEX_FORMAT_LINEAR;
|
||||
}
|
||||
|
||||
txs = tf->swizzle;
|
||||
|
||||
MARK_RING(chan, 11 + 2 * !unit, 2);
|
||||
MARK_RING(chan, 11, 2);
|
||||
OUT_RING(chan, RING_3D(NV34TCL_TX_OFFSET(unit), 8));
|
||||
OUT_RELOC(chan, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
OUT_RELOC(chan, bo, sv->offset, tex_flags | NOUVEAU_BO_LOW, 0, 0);
|
||||
OUT_RELOC(chan, bo, txf, tex_flags | NOUVEAU_BO_OR,
|
||||
NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
|
||||
OUT_RING(chan, ps->wrap);
|
||||
OUT_RING(chan, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
|
||||
OUT_RING(chan, txs);
|
||||
OUT_RING(chan, ps->filt | tf->sign | 0x2000 /*voodoo*/);
|
||||
OUT_RING(chan, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height0);
|
||||
OUT_RING(chan, (ps->wrap & sv->wrap_mask) | sv->wrap);
|
||||
OUT_RING(chan, ps->en | (min_lod << 19) | (max_lod << 7));
|
||||
OUT_RING(chan, sv->swizzle);
|
||||
OUT_RING(chan, ps->filt | sv->filt);
|
||||
OUT_RING(chan, sv->npot_size);
|
||||
OUT_RING(chan, ps->bcol);
|
||||
OUT_RING(chan, RING_3D(NV40TCL_TEX_SIZE1(unit), 1));
|
||||
OUT_RING(chan, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
|
||||
OUT_RING(chan, sv->u.nv40.npot_size2);
|
||||
|
||||
nvfx->hw_txf[unit] = txf;
|
||||
nvfx->hw_samplers |= (1 << unit);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
|
|||
nvfx_init_query_functions(nvfx);
|
||||
nvfx_init_surface_functions(nvfx);
|
||||
nvfx_init_state_functions(nvfx);
|
||||
nvfx_init_sampling_functions(nvfx);
|
||||
nvfx_init_resource_functions(&nvfx->pipe);
|
||||
|
||||
/* Create, configure, and install fallback swtnl path */
|
||||
|
|
|
|||
|
|
@ -201,15 +201,20 @@ extern void
|
|||
nvfx_fragprog_relocate(struct nvfx_context *nvfx);
|
||||
|
||||
/* nvfx_fragtex.c */
|
||||
extern void nvfx_init_sampling_functions(struct nvfx_context *nvfx);
|
||||
extern void nvfx_fragtex_validate(struct nvfx_context *nvfx);
|
||||
extern void
|
||||
nvfx_fragtex_relocate(struct nvfx_context *nvfx);
|
||||
extern void nvfx_fragtex_relocate(struct nvfx_context *nvfx);
|
||||
|
||||
struct nvfx_sampler_view;
|
||||
|
||||
/* nv30_fragtex.c */
|
||||
extern void
|
||||
nv30_sampler_state_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_state *ps,
|
||||
const struct pipe_sampler_state *cso);
|
||||
extern void
|
||||
nv30_sampler_view_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_view *sv);
|
||||
extern void nv30_fragtex_set(struct nvfx_context *nvfx, int unit);
|
||||
|
||||
/* nv40_fragtex.c */
|
||||
|
|
@ -217,6 +222,9 @@ extern void
|
|||
nv40_sampler_state_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_state *ps,
|
||||
const struct pipe_sampler_state *cso);
|
||||
extern void
|
||||
nv40_sampler_view_init(struct pipe_context *pipe,
|
||||
struct nvfx_sampler_view *sv);
|
||||
extern void nv40_fragtex_set(struct nvfx_context *nvfx, int unit);
|
||||
|
||||
/* nvfx_state.c */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,177 @@
|
|||
#include "nvfx_context.h"
|
||||
#include "nvfx_resource.h"
|
||||
#include "nvfx_tex.h"
|
||||
|
||||
static void *
|
||||
nvfx_sampler_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *cso)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
struct nvfx_sampler_state *ps;
|
||||
|
||||
ps = MALLOC(sizeof(struct nvfx_sampler_state));
|
||||
|
||||
/* on nv30, we use this as an internal flag */
|
||||
ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT;
|
||||
ps->en = 0;
|
||||
ps->filt = nvfx_tex_filter(cso) | 0x2000; /*voodoo*/
|
||||
ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
|
||||
(nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
|
||||
(nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT);
|
||||
ps->compare = FALSE;
|
||||
|
||||
if(cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
|
||||
{
|
||||
ps->wrap |= nvfx_tex_wrap_compare_mode(cso->compare_func);
|
||||
ps->compare = TRUE;
|
||||
}
|
||||
ps->bcol = nvfx_tex_border_color(cso->border_color);
|
||||
|
||||
if(nvfx->is_nv4x)
|
||||
nv40_sampler_state_init(pipe, ps, cso);
|
||||
else
|
||||
nv30_sampler_state_init(pipe, ps, cso);
|
||||
|
||||
return (void *)ps;
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
FREE(hwcso);
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
nvfx->tex_sampler[unit] = sampler[unit];
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
for (unit = nr; unit < nvfx->nr_samplers; unit++) {
|
||||
nvfx->tex_sampler[unit] = NULL;
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
nvfx->nr_samplers = nr;
|
||||
nvfx->dirty |= NVFX_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
nvfx_create_sampler_view(struct pipe_context *pipe,
|
||||
struct pipe_resource *pt,
|
||||
const struct pipe_sampler_view *templ)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
struct nvfx_sampler_view *sv = CALLOC_STRUCT(nvfx_sampler_view);
|
||||
struct nvfx_texture_format *tf = &nvfx_texture_formats[templ->format];
|
||||
unsigned txf;
|
||||
|
||||
if (!sv)
|
||||
return NULL;
|
||||
|
||||
sv->base = *templ;
|
||||
sv->base.reference.count = 1;
|
||||
sv->base.texture = NULL;
|
||||
pipe_resource_reference(&sv->base.texture, pt);
|
||||
sv->base.context = pipe;
|
||||
|
||||
txf = NV34TCL_TX_FORMAT_NO_BORDER;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
txf |= NV34TCL_TX_FORMAT_CUBIC;
|
||||
/* fall-through */
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_2D;
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_3D;
|
||||
break;
|
||||
case PIPE_TEXTURE_1D:
|
||||
txf |= NV34TCL_TX_FORMAT_DIMS_1D;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
sv->u.init_fmt = txf;
|
||||
|
||||
sv->swizzle = 0
|
||||
| (tf->src[sv->base.swizzle_r] << NV34TCL_TX_SWIZZLE_S0_Z_SHIFT)
|
||||
| (tf->src[sv->base.swizzle_g] << NV34TCL_TX_SWIZZLE_S0_Y_SHIFT)
|
||||
| (tf->src[sv->base.swizzle_b] << NV34TCL_TX_SWIZZLE_S0_X_SHIFT)
|
||||
| (tf->src[sv->base.swizzle_a] << NV34TCL_TX_SWIZZLE_S0_W_SHIFT)
|
||||
| (tf->comp[sv->base.swizzle_r] << NV34TCL_TX_SWIZZLE_S1_Z_SHIFT)
|
||||
| (tf->comp[sv->base.swizzle_g] << NV34TCL_TX_SWIZZLE_S1_Y_SHIFT)
|
||||
| (tf->comp[sv->base.swizzle_b] << NV34TCL_TX_SWIZZLE_S1_X_SHIFT)
|
||||
| (tf->comp[sv->base.swizzle_a] << NV34TCL_TX_SWIZZLE_S1_W_SHIFT);
|
||||
|
||||
sv->filt = tf->sign;
|
||||
sv->wrap = tf->wrap;
|
||||
sv->wrap_mask = ~0;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE)
|
||||
{
|
||||
sv->offset = 0;
|
||||
sv->npot_size = (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | pt->height0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sv->offset = nvfx_subresource_offset(pt, 0, sv->base.first_level, 0);
|
||||
sv->npot_size = (u_minify(pt->width0, sv->base.first_level) << NV34TCL_TX_NPOT_SIZE_W_SHIFT) | u_minify(pt->height0, sv->base.first_level);
|
||||
|
||||
/* apparently, we need to ignore the t coordinate for 1D textures to fix piglit tex1d-2dborder */
|
||||
if(pt->target == PIPE_TEXTURE_1D)
|
||||
{
|
||||
sv->wrap_mask &=~ NV34TCL_TX_WRAP_T_MASK;
|
||||
sv->wrap |= NV34TCL_TX_WRAP_T_REPEAT;
|
||||
}
|
||||
}
|
||||
|
||||
if(nvfx->is_nv4x)
|
||||
nv40_sampler_view_init(pipe, sv);
|
||||
else
|
||||
nv30_sampler_view_init(pipe, sv);
|
||||
|
||||
return &sv->base;
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_sampler_view_destroy(struct pipe_context *pipe,
|
||||
struct pipe_sampler_view *view)
|
||||
{
|
||||
pipe_resource_reference(&view->texture, NULL);
|
||||
FREE(view);
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
|
||||
unsigned nr,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
|
||||
views[unit]);
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
for (unit = nr; unit < nvfx->nr_textures; unit++) {
|
||||
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
|
||||
NULL);
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
nvfx->nr_textures = nr;
|
||||
nvfx->dirty |= NVFX_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
void
|
||||
nvfx_fragtex_validate(struct nvfx_context *nvfx)
|
||||
|
|
@ -60,3 +232,126 @@ nvfx_fragtex_relocate(struct nvfx_context *nvfx)
|
|||
NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvfx_init_sampling_functions(struct nvfx_context *nvfx)
|
||||
{
|
||||
nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
|
||||
nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
|
||||
nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
|
||||
nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
|
||||
nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
|
||||
nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
|
||||
}
|
||||
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT1_RECT NV34TCL_TX_FORMAT_FORMAT_DXT1
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT3_RECT NV34TCL_TX_FORMAT_FORMAT_DXT3
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_DXT5_RECT NV34TCL_TX_FORMAT_FORMAT_DXT5
|
||||
|
||||
#define NV40TCL_TEX_FORMAT_FORMAT_HILO16 NV40TCL_TEX_FORMAT_FORMAT_A16L16
|
||||
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_RGBA16F 0x00004a00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_RGBA16F_RECT NV34TCL_TX_FORMAT_FORMAT_RGBA16F
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_RGBA32F 0x00004b00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_RGBA32F_RECT NV34TCL_TX_FORMAT_FORMAT_RGBA32F
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_R32F 0x00004c00
|
||||
#define NV34TCL_TX_FORMAT_FORMAT_R32F_RECT NV34TCL_TX_FORMAT_FORMAT_R32F
|
||||
|
||||
// TODO: guess!
|
||||
#define NV40TCL_TEX_FORMAT_FORMAT_R32F 0x00001c00
|
||||
|
||||
#define SRGB 0x00700000
|
||||
|
||||
#define __(m,tf,tfc,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign,wrap) \
|
||||
[PIPE_FORMAT_##m] = { \
|
||||
{NV34TCL_TX_FORMAT_FORMAT_##tf, \
|
||||
NV34TCL_TX_FORMAT_FORMAT_##tfc, \
|
||||
NV34TCL_TX_FORMAT_FORMAT_##tf##_RECT, \
|
||||
NV34TCL_TX_FORMAT_FORMAT_##tfc##_RECT, \
|
||||
NV40TCL_TEX_FORMAT_FORMAT_##tf, \
|
||||
NV40TCL_TEX_FORMAT_FORMAT_##tfc}, \
|
||||
sign, wrap, \
|
||||
{ts0z, ts0y, ts0x, ts0w, 0, 1}, {ts1z, ts1y, ts1x, ts1w, 0, 0} \
|
||||
}
|
||||
|
||||
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap) \
|
||||
__(m,tf,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap)
|
||||
|
||||
/* Depth formats works by reading the depth value most significant 8/16 bits.
|
||||
* We are losing precision, but nVidia loses even more by using A8R8G8B8 instead of HILO16
|
||||
* There is no 32-bit integer texture support, so other things are infeasible.
|
||||
*
|
||||
* TODO: is it possible to read 16 bits for Z16? A16 doesn't seem to work, either due to normalization or endianness issues
|
||||
*/
|
||||
|
||||
#define T 2
|
||||
|
||||
#define X 3
|
||||
#define Y 2
|
||||
#define Z 1
|
||||
#define W 0
|
||||
|
||||
#define SNORM ((NV34TCL_TX_FILTER_SIGNED_RED) | (NV34TCL_TX_FILTER_SIGNED_GREEN) | (NV34TCL_TX_FILTER_SIGNED_BLUE) | (NV34TCL_TX_FILTER_SIGNED_ALPHA))
|
||||
#define UNORM 0
|
||||
|
||||
struct nvfx_texture_format
|
||||
nvfx_texture_formats[PIPE_FORMAT_COUNT] = {
|
||||
[0 ... PIPE_FORMAT_COUNT - 1] = {{-1, -1, -1, -1, -1, -1}},
|
||||
_(B8G8R8X8_UNORM, A8R8G8B8, T, T, T, 1, X, Y, Z, W, UNORM, 0),
|
||||
_(B8G8R8X8_SRGB, A8R8G8B8, T, T, T, 1, X, Y, Z, W, UNORM, SRGB),
|
||||
_(B8G8R8A8_UNORM, A8R8G8B8, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(B8G8R8A8_SRGB, A8R8G8B8, T, T, T, T, X, Y, Z, W, UNORM, SRGB),
|
||||
|
||||
_(R8G8B8A8_UNORM, A8R8G8B8, T, T, T, T, Z, Y, X, W, UNORM, 0),
|
||||
_(R8G8B8A8_SRGB, A8R8G8B8, T, T, T, T, Z, Y, X, W, UNORM, SRGB),
|
||||
_(R8G8B8X8_UNORM, A8R8G8B8, T, T, T, 1, Z, Y, X, W, UNORM, 0),
|
||||
|
||||
_(A8R8G8B8_UNORM, A8R8G8B8, T, T, T, T, W, Z, Y, X, UNORM, 0),
|
||||
_(A8R8G8B8_SRGB, A8R8G8B8, T, T, T, T, W, Z, Y, X, UNORM, SRGB),
|
||||
_(A8B8G8R8_UNORM, A8R8G8B8, T, T, T, T, W, X, Y, Z, UNORM, 0),
|
||||
_(A8B8G8R8_SRGB, A8R8G8B8, T, T, T, T, W, X, Y, Z, UNORM, SRGB),
|
||||
_(X8R8G8B8_UNORM, A8R8G8B8, T, T, T, 1, W, Z, Y, X, UNORM, 0),
|
||||
_(X8R8G8B8_SRGB, A8R8G8B8, T, T, T, 1, W, Z, Y, X, UNORM, SRGB),
|
||||
|
||||
_(B5G5R5A1_UNORM, A1R5G5B5, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(B5G5R5X1_UNORM, A1R5G5B5, T, T, T, 1, X, Y, Z, W, UNORM, 0),
|
||||
|
||||
_(B4G4R4A4_UNORM, A4R4G4B4, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(B4G4R4X4_UNORM, A4R4G4B4, T, T, T, 1, X, Y, Z, W, UNORM, 0),
|
||||
|
||||
_(B5G6R5_UNORM, R5G6B5, T, T, T, 1, X, Y, Z, W, UNORM, 0),
|
||||
|
||||
_(R8_UNORM, L8, T, 0, 0, 1, X, X, X, X, UNORM, 0),
|
||||
_(R8_SNORM, L8, T, 0, 0, 1, X, X, X, X, SNORM, 0),
|
||||
_(L8_UNORM, L8, T, T, T, 1, X, X, X, X, UNORM, 0),
|
||||
_(L8_SRGB, L8, T, T, T, 1, X, X, X, X, UNORM, SRGB),
|
||||
_(A8_UNORM, L8, 0, 0, 0, T, X, X, X, X, UNORM, 0),
|
||||
_(I8_UNORM, L8, T, T, T, T, X, X, X, X, UNORM, 0),
|
||||
|
||||
_(R8G8_UNORM, A8L8, T, T, T, T, X, X, X, W, UNORM, 0),
|
||||
_(R8G8_SNORM, A8L8, T, T, T, T, X, X, X, W, SNORM, 0),
|
||||
_(L8A8_UNORM, A8L8, T, T, T, T, X, X, X, W, UNORM, 0),
|
||||
_(L8A8_SRGB, A8L8, T, T, T, T, X, X, X, W, UNORM, SRGB),
|
||||
|
||||
_(DXT1_RGB, DXT1, T, T, T, 1, X, Y, Z, W, UNORM, 0),
|
||||
_(DXT1_SRGB, DXT1, T, T, T, 1, X, Y, Z, W, UNORM, SRGB),
|
||||
_(DXT1_RGBA, DXT1, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(DXT1_SRGBA, DXT1, T, T, T, T, X, Y, Z, W, UNORM, SRGB),
|
||||
_(DXT3_RGBA, DXT3, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(DXT3_SRGBA, DXT3, T, T, T, T, X, Y, Z, W, UNORM, SRGB),
|
||||
_(DXT5_RGBA, DXT5, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(DXT5_SRGBA, DXT5, T, T, T, T, X, Y, Z, W, UNORM, SRGB),
|
||||
|
||||
__(Z16_UNORM, A8L8, Z16, T, T, T, 1, W, W, W, W, UNORM, 0),
|
||||
__(S8_USCALED_Z24_UNORM,HILO16,Z24, T, T, T, 1, W, W, W, W, UNORM, 0),
|
||||
__(X8Z24_UNORM, HILO16,Z24, T, T, T, 1, W, W, W, W, UNORM, 0),
|
||||
|
||||
_(R16_UNORM, A16, T, 0, 0, 1, X, X, X, X, UNORM, 0),
|
||||
_(R16_SNORM, A16, T, 0, 0, 1, X, X, X, X, SNORM, 0),
|
||||
_(R16G16_UNORM, HILO16, T, T, 0, 1, X, Y, X, X, UNORM, 0),
|
||||
_(R16G16_SNORM, HILO16, T, T, 0, 1, X, Y, X, X, SNORM, 0),
|
||||
|
||||
_(R16G16B16A16_FLOAT, RGBA16F, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(R32G32B32A32_FLOAT, RGBA32F, T, T, T, T, X, Y, Z, W, UNORM, 0),
|
||||
_(R32_FLOAT, R32F, T, 0, 0, 1, X, X, X, X, UNORM, 0)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nvfx_context.h"
|
||||
#include "nvfx_screen.h"
|
||||
#include "nvfx_resource.h"
|
||||
#include "nvfx_tex.h"
|
||||
|
||||
#define NV30TCL_CHIPSET_3X_MASK 0x00000003
|
||||
#define NV34TCL_CHIPSET_3X_MASK 0x00000010
|
||||
|
|
@ -179,58 +180,45 @@ nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
|
|||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
} else
|
||||
}
|
||||
|
||||
if (tex_usage & PIPE_BIND_DEPTH_STENCIL) {
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
return TRUE;
|
||||
break;
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
/* TODO: this nv30 limitation probably does not exist */
|
||||
if (!screen->is_nv4x && front)
|
||||
return (front->format == PIPE_FORMAT_B5G6R5_UNORM);
|
||||
return TRUE;
|
||||
default:
|
||||
if (!screen->is_nv4x && front && front->format != PIPE_FORMAT_B5G6R5_UNORM)
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_DXT1_RGB:
|
||||
case PIPE_FORMAT_DXT1_RGBA:
|
||||
case PIPE_FORMAT_DXT3_RGBA:
|
||||
case PIPE_FORMAT_DXT5_RGBA:
|
||||
return util_format_s3tc_enabled;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
case PIPE_FORMAT_B5G5R5A1_UNORM:
|
||||
case PIPE_FORMAT_B4G4R4A4_UNORM:
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
case PIPE_FORMAT_I8_UNORM:
|
||||
case PIPE_FORMAT_L8A8_UNORM:
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
return TRUE;
|
||||
/* TODO: does nv30 support this? */
|
||||
case PIPE_FORMAT_R16_SNORM:
|
||||
return !!screen->is_nv4x;
|
||||
default:
|
||||
break;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
if (tex_usage & PIPE_BIND_SAMPLER_VIEW) {
|
||||
struct nvfx_texture_format* tf = &nvfx_texture_formats[format];
|
||||
if(util_format_is_s3tc(format) && !util_format_s3tc_enabled)
|
||||
return FALSE;
|
||||
|
||||
if(screen->is_nv4x)
|
||||
{
|
||||
if(tf->fmt[4] < 0)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tf->fmt[0] < 0)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -81,111 +81,6 @@ nvfx_blend_state_delete(struct pipe_context *pipe, void *hwcso)
|
|||
FREE(bso);
|
||||
}
|
||||
|
||||
static void *
|
||||
nvfx_sampler_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *cso)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
struct nvfx_sampler_state *ps;
|
||||
|
||||
ps = MALLOC(sizeof(struct nvfx_sampler_state));
|
||||
|
||||
/* on nv30, we use this as an internal flag */
|
||||
ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT;
|
||||
ps->en = 0;
|
||||
ps->filt = nvfx_tex_filter(cso);
|
||||
ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
|
||||
(nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
|
||||
(nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT) |
|
||||
nvfx_tex_wrap_compare_mode(cso);
|
||||
ps->bcol = nvfx_tex_border_color(cso->border_color);
|
||||
|
||||
if(nvfx->is_nv4x)
|
||||
nv40_sampler_state_init(pipe, ps, cso);
|
||||
else
|
||||
nv30_sampler_state_init(pipe, ps, cso);
|
||||
|
||||
return (void *)ps;
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
nvfx->tex_sampler[unit] = sampler[unit];
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
for (unit = nr; unit < nvfx->nr_samplers; unit++) {
|
||||
nvfx->tex_sampler[unit] = NULL;
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
nvfx->nr_samplers = nr;
|
||||
nvfx->dirty |= NVFX_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
FREE(hwcso);
|
||||
}
|
||||
|
||||
static void
|
||||
nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
|
||||
unsigned nr,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
struct nvfx_context *nvfx = nvfx_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
|
||||
views[unit]);
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
for (unit = nr; unit < nvfx->nr_textures; unit++) {
|
||||
pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
|
||||
NULL);
|
||||
nvfx->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
|
||||
nvfx->nr_textures = nr;
|
||||
nvfx->dirty |= NVFX_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
nvfx_create_sampler_view(struct pipe_context *pipe,
|
||||
struct pipe_resource *texture,
|
||||
const struct pipe_sampler_view *templ)
|
||||
{
|
||||
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
|
||||
|
||||
if (view) {
|
||||
*view = *templ;
|
||||
view->reference.count = 1;
|
||||
view->texture = NULL;
|
||||
pipe_resource_reference(&view->texture, texture);
|
||||
view->context = pipe;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nvfx_sampler_view_destroy(struct pipe_context *pipe,
|
||||
struct pipe_sampler_view *view)
|
||||
{
|
||||
pipe_resource_reference(&view->texture, NULL);
|
||||
FREE(view);
|
||||
}
|
||||
|
||||
static void *
|
||||
nvfx_rasterizer_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_rasterizer_state *cso)
|
||||
|
|
@ -630,13 +525,6 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
|
|||
nvfx->pipe.bind_blend_state = nvfx_blend_state_bind;
|
||||
nvfx->pipe.delete_blend_state = nvfx_blend_state_delete;
|
||||
|
||||
nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
|
||||
nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
|
||||
nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
|
||||
nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
|
||||
nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
|
||||
nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
|
||||
|
||||
nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
|
||||
nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;
|
||||
nvfx->pipe.delete_rasterizer_state = nvfx_rasterizer_state_delete;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
#ifndef NVFX_TEX_H_
|
||||
#define NVFX_TEX_H_
|
||||
|
||||
#include "util/u_math.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include <nouveau/nouveau_class.h>
|
||||
|
||||
static inline unsigned
|
||||
nvfx_tex_wrap_mode(unsigned wrap) {
|
||||
unsigned ret;
|
||||
|
|
@ -31,7 +36,7 @@ nvfx_tex_wrap_mode(unsigned wrap) {
|
|||
ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
|
||||
assert(0);
|
||||
ret = NV34TCL_TX_WRAP_S_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
|
@ -40,31 +45,29 @@ nvfx_tex_wrap_mode(unsigned wrap) {
|
|||
}
|
||||
|
||||
static inline unsigned
|
||||
nvfx_tex_wrap_compare_mode(const struct pipe_sampler_state* cso)
|
||||
nvfx_tex_wrap_compare_mode(unsigned func)
|
||||
{
|
||||
if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
|
||||
switch (cso->compare_func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
return NV34TCL_TX_WRAP_RCOMP_NEVER;
|
||||
case PIPE_FUNC_GREATER:
|
||||
return NV34TCL_TX_WRAP_RCOMP_GREATER;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_EQUAL;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_GEQUAL;
|
||||
case PIPE_FUNC_LESS:
|
||||
return NV34TCL_TX_WRAP_RCOMP_LESS;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_LEQUAL;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
return NV34TCL_TX_WRAP_RCOMP_ALWAYS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
return NV34TCL_TX_WRAP_RCOMP_NEVER;
|
||||
case PIPE_FUNC_GREATER:
|
||||
return NV34TCL_TX_WRAP_RCOMP_GREATER;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_EQUAL;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_GEQUAL;
|
||||
case PIPE_FUNC_LESS:
|
||||
return NV34TCL_TX_WRAP_RCOMP_LESS;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
return NV34TCL_TX_WRAP_RCOMP_LEQUAL;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
return NV34TCL_TX_WRAP_RCOMP_ALWAYS;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned nvfx_tex_filter(const struct pipe_sampler_state* cso)
|
||||
|
|
@ -128,6 +131,45 @@ struct nvfx_sampler_state {
|
|||
uint32_t en;
|
||||
uint32_t filt;
|
||||
uint32_t bcol;
|
||||
uint32_t min_lod;
|
||||
uint32_t max_lod;
|
||||
boolean compare;
|
||||
};
|
||||
|
||||
struct nvfx_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
int offset;
|
||||
uint32_t swizzle;
|
||||
uint32_t npot_size;
|
||||
uint32_t filt;
|
||||
uint32_t wrap_mask;
|
||||
uint32_t wrap;
|
||||
uint32_t lod_offset;
|
||||
uint32_t max_lod_limit;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t fmt[4]; /* nv30 has 4 entries, nv40 one */
|
||||
int rect;
|
||||
} nv30;
|
||||
struct
|
||||
{
|
||||
uint32_t fmt[2]; /* nv30 has 4 entries, nv40 one */
|
||||
uint32_t npot_size2; /* nv40 only */
|
||||
} nv40;
|
||||
uint32_t init_fmt;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct nvfx_texture_format {
|
||||
int fmt[6];
|
||||
unsigned sign;
|
||||
unsigned wrap;
|
||||
unsigned char src[6];
|
||||
unsigned char comp[6];
|
||||
};
|
||||
|
||||
extern struct nvfx_texture_format nvfx_texture_formats[PIPE_FORMAT_COUNT];
|
||||
|
||||
#endif /* NVFX_TEX_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue