1 #include "util/u_format.h"
2 #include "nvfx_context.h"
6 nv40_sampler_state_init(struct pipe_context
*pipe
,
7 struct nvfx_sampler_state
*ps
,
8 const struct pipe_sampler_state
*cso
)
10 if (cso
->max_anisotropy
>= 2) {
11 /* no idea, binary driver sets it, works without it.. meh.. */
14 if (cso
->max_anisotropy
>= 16) {
15 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_16X
;
17 if (cso
->max_anisotropy
>= 12) {
18 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_12X
;
20 if (cso
->max_anisotropy
>= 10) {
21 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_10X
;
23 if (cso
->max_anisotropy
>= 8) {
24 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_8X
;
26 if (cso
->max_anisotropy
>= 6) {
27 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_6X
;
29 if (cso
->max_anisotropy
>= 4) {
30 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_4X
;
32 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_2X
;
39 limit
= CLAMP(cso
->lod_bias
, -16.0, 15.0);
40 ps
->filt
|= (int)(cso
->lod_bias
* 256.0) & 0x1fff;
42 limit
= CLAMP(cso
->max_lod
, 0.0, 15.0);
43 ps
->en
|= (int)(limit
* 256.0) << 7;
45 limit
= CLAMP(cso
->min_lod
, 0.0, 15.0);
46 ps
->en
|= (int)(limit
* 256.0) << 19;
50 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
54 NV40TCL_TEX_FORMAT_FORMAT_##tf, \
55 (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
56 NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
57 NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
58 NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \
59 ((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) | \
60 (NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw)) \
63 struct nv40_texture_format
{
71 static struct nv40_texture_format
72 nv40_texture_formats
[] = {
73 _(B8G8R8X8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
74 _(B8G8R8A8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
75 _(B5G5R5A1_UNORM
, A1R5G5B5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
76 _(B4G4R4A4_UNORM
, A4R4G4B4
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
77 _(B5G6R5_UNORM
, R5G6B5
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
78 _(L8_UNORM
, L8
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
79 _(A8_UNORM
, L8
, ZERO
, ZERO
, ZERO
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
80 _(R16_SNORM
, A16
, ZERO
, ZERO
, S1
, ONE
, X
, X
, X
, Y
, 1, 1, 1, 1),
81 _(I8_UNORM
, L8
, S1
, S1
, S1
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
82 _(L8A8_UNORM
, A8L8
, S1
, S1
, S1
, S1
, X
, X
, X
, Y
, 0, 0, 0, 0),
83 _(Z16_UNORM
, Z16
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
84 _(S8Z24_UNORM
, Z24
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
85 _(DXT1_RGB
, DXT1
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
86 _(DXT1_RGBA
, DXT1
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
87 _(DXT3_RGBA
, DXT3
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
88 _(DXT5_RGBA
, DXT5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
92 static struct nv40_texture_format
*
93 nv40_fragtex_format(uint pipe_format
)
95 struct nv40_texture_format
*tf
= nv40_texture_formats
;
98 if (tf
->pipe
== pipe_format
)
103 NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format
));
108 struct nouveau_stateobj
*
109 nv40_fragtex_build(struct nvfx_context
*nvfx
, int unit
)
111 struct nvfx_sampler_state
*ps
= nvfx
->tex_sampler
[unit
];
112 struct nvfx_miptree
*nv40mt
= nvfx
->tex_miptree
[unit
];
113 struct nouveau_bo
*bo
= nouveau_bo(nv40mt
->buffer
);
114 struct pipe_texture
*pt
= &nv40mt
->base
;
115 struct nv40_texture_format
*tf
;
116 struct nouveau_stateobj
*so
;
117 uint32_t txf
, txs
, txp
;
118 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
120 tf
= nv40_fragtex_format(pt
->format
);
125 txf
|= tf
->format
| 0x8000;
126 txf
|= ((pt
->last_level
+ 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT
);
129 txf
|= NV34TCL_TX_FORMAT_NO_BORDER
;
131 switch (pt
->target
) {
132 case PIPE_TEXTURE_CUBE
:
133 txf
|= NV34TCL_TX_FORMAT_CUBIC
;
135 case PIPE_TEXTURE_2D
:
136 txf
|= NV34TCL_TX_FORMAT_DIMS_2D
;
138 case PIPE_TEXTURE_3D
:
139 txf
|= NV34TCL_TX_FORMAT_DIMS_3D
;
141 case PIPE_TEXTURE_1D
:
142 txf
|= NV34TCL_TX_FORMAT_DIMS_1D
;
145 NOUVEAU_ERR("Unknown target %d\n", pt
->target
);
149 if (!(pt
->tex_usage
& NOUVEAU_TEXTURE_USAGE_LINEAR
)) {
152 txp
= nv40mt
->level
[0].pitch
;
153 txf
|= NV40TCL_TEX_FORMAT_LINEAR
;
158 so
= so_new(2, 9, 2);
159 so_method(so
, nvfx
->screen
->eng3d
, NV34TCL_TX_OFFSET(unit
), 8);
160 so_reloc (so
, bo
, 0, tex_flags
| NOUVEAU_BO_LOW
, 0, 0);
161 so_reloc (so
, bo
, txf
, tex_flags
| NOUVEAU_BO_OR
,
162 NV34TCL_TX_FORMAT_DMA0
, NV34TCL_TX_FORMAT_DMA1
);
163 so_data (so
, ps
->wrap
);
164 so_data (so
, NV40TCL_TEX_ENABLE_ENABLE
| ps
->en
);
166 so_data (so
, ps
->filt
| tf
->sign
| 0x2000 /*voodoo*/);
167 so_data (so
, (pt
->width0
<< NV34TCL_TX_NPOT_SIZE_W_SHIFT
) |
169 so_data (so
, ps
->bcol
);
170 so_method(so
, nvfx
->screen
->eng3d
, NV40TCL_TEX_SIZE1(unit
), 1);
171 so_data (so
, (pt
->depth0
<< NV40TCL_TEX_SIZE1_DEPTH_SHIFT
) | txp
);