1 #include "nvfx_context.h"
2 #include "nvfx_resource.h"
6 nvfx_sampler_state_create(struct pipe_context
*pipe
,
7 const struct pipe_sampler_state
*cso
)
9 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
10 struct nvfx_sampler_state
*ps
;
12 ps
= MALLOC(sizeof(struct nvfx_sampler_state
));
14 /* on nv30, we use this as an internal flag */
15 ps
->fmt
= cso
->normalized_coords
? 0 : NV40_3D_TEX_FORMAT_RECT
;
17 ps
->filt
= nvfx_tex_filter(cso
) | 0x2000; /*voodoo*/
18 ps
->wrap
= (nvfx_tex_wrap_mode(cso
->wrap_s
) << NV30_3D_TEX_WRAP_S__SHIFT
) |
19 (nvfx_tex_wrap_mode(cso
->wrap_t
) << NV30_3D_TEX_WRAP_T__SHIFT
) |
20 (nvfx_tex_wrap_mode(cso
->wrap_r
) << NV30_3D_TEX_WRAP_R__SHIFT
);
23 if(cso
->compare_mode
== PIPE_TEX_COMPARE_R_TO_TEXTURE
)
25 ps
->wrap
|= nvfx_tex_wrap_compare_mode(cso
->compare_func
);
28 ps
->bcol
= nvfx_tex_border_color(cso
->border_color
);
31 nv40_sampler_state_init(pipe
, ps
, cso
);
33 nv30_sampler_state_init(pipe
, ps
, cso
);
39 nvfx_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
45 nvfx_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
47 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
50 for (unit
= 0; unit
< nr
; unit
++) {
51 nvfx
->tex_sampler
[unit
] = sampler
[unit
];
52 nvfx
->dirty_samplers
|= (1 << unit
);
55 for (unit
= nr
; unit
< nvfx
->nr_samplers
; unit
++) {
56 nvfx
->tex_sampler
[unit
] = NULL
;
57 nvfx
->dirty_samplers
|= (1 << unit
);
60 nvfx
->nr_samplers
= nr
;
61 nvfx
->dirty
|= NVFX_NEW_SAMPLER
;
64 static struct pipe_sampler_view
*
65 nvfx_create_sampler_view(struct pipe_context
*pipe
,
66 struct pipe_resource
*pt
,
67 const struct pipe_sampler_view
*templ
)
69 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
70 struct nvfx_sampler_view
*sv
= CALLOC_STRUCT(nvfx_sampler_view
);
71 struct nvfx_texture_format
*tf
= &nvfx_texture_formats
[templ
->format
];
78 sv
->base
.reference
.count
= 1;
79 sv
->base
.texture
= NULL
;
80 pipe_resource_reference(&sv
->base
.texture
, pt
);
81 sv
->base
.context
= pipe
;
83 txf
= NV30_3D_TEX_FORMAT_NO_BORDER
;
86 case PIPE_TEXTURE_CUBE
:
87 txf
|= NV30_3D_TEX_FORMAT_CUBIC
;
90 case PIPE_TEXTURE_RECT
:
91 txf
|= NV30_3D_TEX_FORMAT_DIMS_2D
;
94 txf
|= NV30_3D_TEX_FORMAT_DIMS_3D
;
97 txf
|= NV30_3D_TEX_FORMAT_DIMS_1D
;
102 sv
->u
.init_fmt
= txf
;
105 | (tf
->src
[sv
->base
.swizzle_r
] << NV30_3D_TEX_SWIZZLE_S0_Z__SHIFT
)
106 | (tf
->src
[sv
->base
.swizzle_g
] << NV30_3D_TEX_SWIZZLE_S0_Y__SHIFT
)
107 | (tf
->src
[sv
->base
.swizzle_b
] << NV30_3D_TEX_SWIZZLE_S0_X__SHIFT
)
108 | (tf
->src
[sv
->base
.swizzle_a
] << NV30_3D_TEX_SWIZZLE_S0_W__SHIFT
)
109 | (tf
->comp
[sv
->base
.swizzle_r
] << NV30_3D_TEX_SWIZZLE_S1_Z__SHIFT
)
110 | (tf
->comp
[sv
->base
.swizzle_g
] << NV30_3D_TEX_SWIZZLE_S1_Y__SHIFT
)
111 | (tf
->comp
[sv
->base
.swizzle_b
] << NV30_3D_TEX_SWIZZLE_S1_X__SHIFT
)
112 | (tf
->comp
[sv
->base
.swizzle_a
] << NV30_3D_TEX_SWIZZLE_S1_W__SHIFT
);
118 if (pt
->target
== PIPE_TEXTURE_CUBE
)
121 sv
->npot_size
= (pt
->width0
<< NV30_3D_TEX_NPOT_SIZE_W__SHIFT
) | pt
->height0
;
125 sv
->offset
= nvfx_subresource_offset(pt
, 0, sv
->base
.u
.tex
.first_level
, 0);
126 sv
->npot_size
= (u_minify(pt
->width0
, sv
->base
.u
.tex
.first_level
) << NV30_3D_TEX_NPOT_SIZE_W__SHIFT
) | u_minify(pt
->height0
, sv
->base
.u
.tex
.first_level
);
128 /* apparently, we need to ignore the t coordinate for 1D textures to fix piglit tex1d-2dborder */
129 if(pt
->target
== PIPE_TEXTURE_1D
)
131 sv
->wrap_mask
&=~ NV30_3D_TEX_WRAP_T__MASK
;
132 sv
->wrap
|= NV30_3D_TEX_WRAP_T_REPEAT
;
137 nv40_sampler_view_init(pipe
, sv
);
139 nv30_sampler_view_init(pipe
, sv
);
145 nvfx_sampler_view_destroy(struct pipe_context
*pipe
,
146 struct pipe_sampler_view
*view
)
148 pipe_resource_reference(&view
->texture
, NULL
);
153 nvfx_set_fragment_sampler_views(struct pipe_context
*pipe
,
155 struct pipe_sampler_view
**views
)
157 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
160 for (unit
= 0; unit
< nr
; unit
++) {
161 pipe_sampler_view_reference(&nvfx
->fragment_sampler_views
[unit
],
163 nvfx
->dirty_samplers
|= (1 << unit
);
166 for (unit
= nr
; unit
< nvfx
->nr_textures
; unit
++) {
167 pipe_sampler_view_reference(&nvfx
->fragment_sampler_views
[unit
],
169 nvfx
->dirty_samplers
|= (1 << unit
);
172 nvfx
->nr_textures
= nr
;
173 nvfx
->dirty
|= NVFX_NEW_SAMPLER
;
177 nvfx_fragtex_validate(struct nvfx_context
*nvfx
)
179 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
180 struct nouveau_grobj
*eng3d
= nvfx
->screen
->eng3d
;
181 unsigned samplers
, unit
;
183 samplers
= nvfx
->dirty_samplers
;
188 unit
= ffs(samplers
) - 1;
189 samplers
&= ~(1 << unit
);
191 if(nvfx
->fragment_sampler_views
[unit
] && nvfx
->tex_sampler
[unit
]) {
192 util_dirty_surfaces_use_for_sampling(&nvfx
->pipe
,
193 &((struct nvfx_miptree
*)nvfx
->fragment_sampler_views
[unit
]->texture
)->dirty_surfaces
,
197 nv30_fragtex_set(nvfx
, unit
);
199 nv40_fragtex_set(nvfx
, unit
);
201 /* this is OK for nv40 too */
202 BEGIN_RING(chan
, eng3d
, NV30_3D_TEX_ENABLE(unit
), 1);
204 nvfx
->hw_samplers
&= ~(1 << unit
);
207 nvfx
->dirty_samplers
= 0;
208 nvfx
->relocs_needed
&=~ NVFX_RELOCATE_FRAGTEX
;
212 nvfx_fragtex_relocate(struct nvfx_context
*nvfx
)
214 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
215 unsigned samplers
, unit
;
216 unsigned tex_flags
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_GART
| NOUVEAU_BO_RD
;
218 samplers
= nvfx
->hw_samplers
;
220 struct nvfx_miptree
* mt
;
221 struct nouveau_bo
*bo
;
223 unit
= ffs(samplers
) - 1;
224 samplers
&= ~(1 << unit
);
226 mt
= (struct nvfx_miptree
*)nvfx
->fragment_sampler_views
[unit
]->texture
;
229 MARK_RING(chan
, 3, 3);
230 OUT_RELOC(chan
, bo
, RING_3D(NV30_3D_TEX_OFFSET(unit
), 2), tex_flags
| NOUVEAU_BO_DUMMY
, 0, 0);
231 OUT_RELOC(chan
, bo
, 0, tex_flags
| NOUVEAU_BO_LOW
| NOUVEAU_BO_DUMMY
, 0, 0);
232 OUT_RELOC(chan
, bo
, nvfx
->hw_txf
[unit
], tex_flags
| NOUVEAU_BO_OR
| NOUVEAU_BO_DUMMY
,
233 NV30_3D_TEX_FORMAT_DMA0
, NV30_3D_TEX_FORMAT_DMA1
);
235 nvfx
->relocs_needed
&=~ NVFX_RELOCATE_FRAGTEX
;
239 nvfx_init_sampling_functions(struct nvfx_context
*nvfx
)
241 nvfx
->pipe
.create_sampler_state
= nvfx_sampler_state_create
;
242 nvfx
->pipe
.bind_fragment_sampler_states
= nvfx_sampler_state_bind
;
243 nvfx
->pipe
.delete_sampler_state
= nvfx_sampler_state_delete
;
244 nvfx
->pipe
.set_fragment_sampler_views
= nvfx_set_fragment_sampler_views
;
245 nvfx
->pipe
.create_sampler_view
= nvfx_create_sampler_view
;
246 nvfx
->pipe
.sampler_view_destroy
= nvfx_sampler_view_destroy
;
249 #define NV30_3D_TEX_FORMAT_FORMAT_DXT1_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT1
250 #define NV30_3D_TEX_FORMAT_FORMAT_DXT3_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT3
251 #define NV30_3D_TEX_FORMAT_FORMAT_DXT5_RECT NV30_3D_TEX_FORMAT_FORMAT_DXT5
253 #define NV40_3D_TEX_FORMAT_FORMAT_HILO16 NV40_3D_TEX_FORMAT_FORMAT_A16L16
255 #define NV30_3D_TEX_FORMAT_FORMAT_RGBA16F 0x00004a00
256 #define NV30_3D_TEX_FORMAT_FORMAT_RGBA16F_RECT NV30_3D_TEX_FORMAT_FORMAT_RGBA16F
257 #define NV30_3D_TEX_FORMAT_FORMAT_RGBA32F 0x00004b00
258 #define NV30_3D_TEX_FORMAT_FORMAT_RGBA32F_RECT NV30_3D_TEX_FORMAT_FORMAT_RGBA32F
259 #define NV30_3D_TEX_FORMAT_FORMAT_R32F 0x00004c00
260 #define NV30_3D_TEX_FORMAT_FORMAT_R32F_RECT NV30_3D_TEX_FORMAT_FORMAT_R32F
263 #define NV40_3D_TEX_FORMAT_FORMAT_R32F 0x00001c00
265 #define SRGB 0x00700000
267 #define __(m,tf,tfc,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign,wrap) \
268 [PIPE_FORMAT_##m] = { \
269 {NV30_3D_TEX_FORMAT_FORMAT_##tf, \
270 NV30_3D_TEX_FORMAT_FORMAT_##tfc, \
271 NV30_3D_TEX_FORMAT_FORMAT_##tf##_RECT, \
272 NV30_3D_TEX_FORMAT_FORMAT_##tfc##_RECT, \
273 NV40_3D_TEX_FORMAT_FORMAT_##tf, \
274 NV40_3D_TEX_FORMAT_FORMAT_##tfc}, \
276 {ts0z, ts0y, ts0x, ts0w, 0, 1}, {ts1z, ts1y, ts1x, ts1w, 0, 0} \
279 #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap) \
280 __(m,tf,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sign, wrap)
282 /* Depth formats works by reading the depth value most significant 8/16 bits.
283 * We are losing precision, but nVidia loses even more by using A8R8G8B8 instead of HILO16
284 * There is no 32-bit integer texture support, so other things are infeasible.
286 * TODO: is it possible to read 16 bits for Z16? A16 doesn't seem to work, either due to normalization or endianness issues
296 #define SNORM ((NV30_3D_TEX_FILTER_SIGNED_RED) | (NV30_3D_TEX_FILTER_SIGNED_GREEN) | (NV30_3D_TEX_FILTER_SIGNED_BLUE) | (NV30_3D_TEX_FILTER_SIGNED_ALPHA))
299 struct nvfx_texture_format
300 nvfx_texture_formats
[PIPE_FORMAT_COUNT
] = {
301 [0 ... PIPE_FORMAT_COUNT
- 1] = {{-1, -1, -1, -1, -1, -1}},
302 _(B8G8R8X8_UNORM
, A8R8G8B8
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, 0),
303 _(B8G8R8X8_SRGB
, A8R8G8B8
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, SRGB
),
304 _(B8G8R8A8_UNORM
, A8R8G8B8
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
305 _(B8G8R8A8_SRGB
, A8R8G8B8
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, SRGB
),
307 _(R8G8B8A8_UNORM
, A8R8G8B8
, T
, T
, T
, T
, Z
, Y
, X
, W
, UNORM
, 0),
308 _(R8G8B8A8_SRGB
, A8R8G8B8
, T
, T
, T
, T
, Z
, Y
, X
, W
, UNORM
, SRGB
),
309 _(R8G8B8X8_UNORM
, A8R8G8B8
, T
, T
, T
, 1, Z
, Y
, X
, W
, UNORM
, 0),
311 _(A8R8G8B8_UNORM
, A8R8G8B8
, T
, T
, T
, T
, W
, Z
, Y
, X
, UNORM
, 0),
312 _(A8R8G8B8_SRGB
, A8R8G8B8
, T
, T
, T
, T
, W
, Z
, Y
, X
, UNORM
, SRGB
),
313 _(A8B8G8R8_UNORM
, A8R8G8B8
, T
, T
, T
, T
, W
, X
, Y
, Z
, UNORM
, 0),
314 _(A8B8G8R8_SRGB
, A8R8G8B8
, T
, T
, T
, T
, W
, X
, Y
, Z
, UNORM
, SRGB
),
315 _(X8R8G8B8_UNORM
, A8R8G8B8
, T
, T
, T
, 1, W
, Z
, Y
, X
, UNORM
, 0),
316 _(X8R8G8B8_SRGB
, A8R8G8B8
, T
, T
, T
, 1, W
, Z
, Y
, X
, UNORM
, SRGB
),
318 _(B5G5R5A1_UNORM
, A1R5G5B5
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
319 _(B5G5R5X1_UNORM
, A1R5G5B5
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, 0),
321 _(B4G4R4A4_UNORM
, A4R4G4B4
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
322 _(B4G4R4X4_UNORM
, A4R4G4B4
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, 0),
324 _(B5G6R5_UNORM
, R5G6B5
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, 0),
326 _(R8_UNORM
, L8
, T
, 0, 0, 1, X
, X
, X
, X
, UNORM
, 0),
327 _(R8_SNORM
, L8
, T
, 0, 0, 1, X
, X
, X
, X
, SNORM
, 0),
328 _(L8_UNORM
, L8
, T
, T
, T
, 1, X
, X
, X
, X
, UNORM
, 0),
329 _(L8_SRGB
, L8
, T
, T
, T
, 1, X
, X
, X
, X
, UNORM
, SRGB
),
330 _(A8_UNORM
, L8
, 0, 0, 0, T
, X
, X
, X
, X
, UNORM
, 0),
331 _(I8_UNORM
, L8
, T
, T
, T
, T
, X
, X
, X
, X
, UNORM
, 0),
333 _(R8G8_UNORM
, A8L8
, T
, T
, T
, T
, X
, X
, X
, W
, UNORM
, 0),
334 _(R8G8_SNORM
, A8L8
, T
, T
, T
, T
, X
, X
, X
, W
, SNORM
, 0),
335 _(L8A8_UNORM
, A8L8
, T
, T
, T
, T
, X
, X
, X
, W
, UNORM
, 0),
336 _(L8A8_SRGB
, A8L8
, T
, T
, T
, T
, X
, X
, X
, W
, UNORM
, SRGB
),
338 _(DXT1_RGB
, DXT1
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, 0),
339 _(DXT1_SRGB
, DXT1
, T
, T
, T
, 1, X
, Y
, Z
, W
, UNORM
, SRGB
),
340 _(DXT1_RGBA
, DXT1
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
341 _(DXT1_SRGBA
, DXT1
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, SRGB
),
342 _(DXT3_RGBA
, DXT3
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
343 _(DXT3_SRGBA
, DXT3
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, SRGB
),
344 _(DXT5_RGBA
, DXT5
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
345 _(DXT5_SRGBA
, DXT5
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, SRGB
),
347 __(Z16_UNORM
, A8L8
, Z16
, T
, T
, T
, 1, W
, W
, W
, W
, UNORM
, 0),
348 __(S8_USCALED_Z24_UNORM
,HILO16
,Z24
, T
, T
, T
, 1, W
, W
, W
, W
, UNORM
, 0),
349 __(X8Z24_UNORM
, HILO16
,Z24
, T
, T
, T
, 1, W
, W
, W
, W
, UNORM
, 0),
351 _(R16_UNORM
, A16
, T
, 0, 0, 1, X
, X
, X
, X
, UNORM
, 0),
352 _(R16_SNORM
, A16
, T
, 0, 0, 1, X
, X
, X
, X
, SNORM
, 0),
353 _(R16G16_UNORM
, HILO16
, T
, T
, 0, 1, X
, Y
, X
, X
, UNORM
, 0),
354 _(R16G16_SNORM
, HILO16
, T
, T
, 0, 1, X
, Y
, X
, X
, SNORM
, 0),
356 _(R16G16B16A16_FLOAT
, RGBA16F
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
357 _(R32G32B32A32_FLOAT
, RGBA32F
, T
, T
, T
, T
, X
, Y
, Z
, W
, UNORM
, 0),
358 _(R32_FLOAT
, R32F
, T
, 0, 0, 1, X
, X
, X
, X
, UNORM
, 0)