1 #include "util/u_format.h"
2 #include "nvfx_context.h"
4 #include "nvfx_resource.h"
7 nv40_sampler_state_init(struct pipe_context
*pipe
,
8 struct nvfx_sampler_state
*ps
,
9 const struct pipe_sampler_state
*cso
)
11 if (cso
->max_anisotropy
>= 2) {
12 /* no idea, binary driver sets it, works without it.. meh.. */
15 if (cso
->max_anisotropy
>= 16) {
16 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_16X
;
18 if (cso
->max_anisotropy
>= 12) {
19 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_12X
;
21 if (cso
->max_anisotropy
>= 10) {
22 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_10X
;
24 if (cso
->max_anisotropy
>= 8) {
25 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_8X
;
27 if (cso
->max_anisotropy
>= 6) {
28 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_6X
;
30 if (cso
->max_anisotropy
>= 4) {
31 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_4X
;
33 ps
->en
|= NV40TCL_TEX_ENABLE_ANISO_2X
;
40 limit
= CLAMP(cso
->lod_bias
, -16.0, 15.0);
41 ps
->filt
|= (int)(cso
->lod_bias
* 256.0) & 0x1fff;
43 limit
= CLAMP(cso
->max_lod
, 0.0, 15.0);
44 ps
->en
|= (int)(limit
* 256.0) << 7;
46 limit
= CLAMP(cso
->min_lod
, 0.0, 15.0);
47 ps
->en
|= (int)(limit
* 256.0) << 19;
51 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
55 NV40TCL_TEX_FORMAT_FORMAT_##tf, \
56 (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
57 NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
58 NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
59 NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \
60 ((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) | \
61 (NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw)) \
64 struct nv40_texture_format
{
72 static struct nv40_texture_format
73 nv40_texture_formats
[] = {
74 _(B8G8R8X8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
75 _(B8G8R8A8_UNORM
, A8R8G8B8
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
76 _(B5G5R5A1_UNORM
, A1R5G5B5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
77 _(B4G4R4A4_UNORM
, A4R4G4B4
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
78 _(B5G6R5_UNORM
, R5G6B5
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
79 _(L8_UNORM
, L8
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
80 _(A8_UNORM
, L8
, ZERO
, ZERO
, ZERO
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
81 _(R16_SNORM
, A16
, ZERO
, ZERO
, S1
, ONE
, X
, X
, X
, Y
, 1, 1, 1, 1),
82 _(I8_UNORM
, L8
, S1
, S1
, S1
, S1
, X
, X
, X
, X
, 0, 0, 0, 0),
83 _(L8A8_UNORM
, A8L8
, S1
, S1
, S1
, S1
, X
, X
, X
, Y
, 0, 0, 0, 0),
84 _(Z16_UNORM
, Z16
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
85 _(S8_USCALED_Z24_UNORM
, Z24
, S1
, S1
, S1
, ONE
, X
, X
, X
, X
, 0, 0, 0, 0),
86 _(DXT1_RGB
, DXT1
, S1
, S1
, S1
, ONE
, X
, Y
, Z
, W
, 0, 0, 0, 0),
87 _(DXT1_RGBA
, DXT1
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
88 _(DXT3_RGBA
, DXT3
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
89 _(DXT5_RGBA
, DXT5
, S1
, S1
, S1
, S1
, X
, Y
, Z
, W
, 0, 0, 0, 0),
93 static struct nv40_texture_format
*
94 nv40_fragtex_format(uint pipe_format
)
96 struct nv40_texture_format
*tf
= nv40_texture_formats
;
99 if (tf
->pipe
== pipe_format
)
104 NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format
));
110 nv40_fragtex_set(struct nvfx_context
*nvfx
, int unit
)
112 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
113 struct nvfx_sampler_state
*ps
= nvfx
->tex_sampler
[unit
];
114 struct nvfx_miptree
*nv40mt
= (struct nvfx_miptree
*)nvfx
->fragment_sampler_views
[unit
]->texture
;
115 struct nouveau_bo
*bo
= nv40mt
->base
.bo
;
116 struct pipe_resource
*pt
= &nv40mt
->base
.base
;
117 struct nv40_texture_format
*tf
;
119 uint32_t txf
, txs
, txp
;
120 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
122 tf
= nv40_fragtex_format(pt
->format
);
127 txf
|= tf
->format
| 0x8000;
128 txf
|= ((pt
->last_level
+ 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT
);
131 txf
|= NV34TCL_TX_FORMAT_NO_BORDER
;
133 switch (pt
->target
) {
134 case PIPE_TEXTURE_CUBE
:
135 txf
|= NV34TCL_TX_FORMAT_CUBIC
;
137 case PIPE_TEXTURE_2D
:
138 txf
|= NV34TCL_TX_FORMAT_DIMS_2D
;
140 case PIPE_TEXTURE_3D
:
141 txf
|= NV34TCL_TX_FORMAT_DIMS_3D
;
143 case PIPE_TEXTURE_1D
:
144 txf
|= NV34TCL_TX_FORMAT_DIMS_1D
;
147 NOUVEAU_ERR("Unknown target %d\n", pt
->target
);
151 if (!(pt
->flags
& NVFX_RESOURCE_FLAG_LINEAR
)) {
154 txp
= nv40mt
->level
[0].pitch
;
155 txf
|= NV40TCL_TEX_FORMAT_LINEAR
;
160 MARK_RING(chan
, 11 + 2 * !unit
, 2);
161 OUT_RING(chan
, RING_3D(NV34TCL_TX_OFFSET(unit
), 8));
162 OUT_RELOC(chan
, bo
, 0, tex_flags
| NOUVEAU_BO_LOW
, 0, 0);
163 OUT_RELOC(chan
, bo
, txf
, tex_flags
| NOUVEAU_BO_OR
,
164 NV34TCL_TX_FORMAT_DMA0
, NV34TCL_TX_FORMAT_DMA1
);
165 OUT_RING(chan
, ps
->wrap
);
166 OUT_RING(chan
, NV40TCL_TEX_ENABLE_ENABLE
| ps
->en
);
168 OUT_RING(chan
, ps
->filt
| tf
->sign
| 0x2000 /*voodoo*/);
169 OUT_RING(chan
, (pt
->width0
<< NV34TCL_TX_NPOT_SIZE_W_SHIFT
) | pt
->height0
);
170 OUT_RING(chan
, ps
->bcol
);
171 OUT_RING(chan
, RING_3D(NV40TCL_TEX_SIZE1(unit
), 1));
172 OUT_RING(chan
, (pt
->depth0
<< NV40TCL_TEX_SIZE1_DEPTH_SHIFT
) | txp
);
174 nvfx
->hw_txf
[unit
] = txf
;
175 nvfx
->hw_samplers
|= (1 << unit
);