Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / nvfx / nvfx_fragtex.c
1 #include "nvfx_context.h"
2 #include "nvfx_resource.h"
3 #include "nvfx_tex.h"
4
5 static void *
6 nvfx_sampler_state_create(struct pipe_context *pipe,
7                           const struct pipe_sampler_state *cso)
8 {
9         struct nvfx_context *nvfx = nvfx_context(pipe);
10         struct nvfx_sampler_state *ps;
11
12         ps = MALLOC(sizeof(struct nvfx_sampler_state));
13
14         /* on nv30, we use this as an internal flag */
15         ps->fmt = cso->normalized_coords ? 0 : NV40_3D_TEX_FORMAT_RECT;
16         ps->en = 0;
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);
21         ps->compare = FALSE;
22
23         if(cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
24         {
25                 ps->wrap |= nvfx_tex_wrap_compare_mode(cso->compare_func);
26                 ps->compare = TRUE;
27         }
28         ps->bcol = nvfx_tex_border_color(cso->border_color);
29
30         if(nvfx->is_nv4x)
31                 nv40_sampler_state_init(pipe, ps, cso);
32         else
33                 nv30_sampler_state_init(pipe, ps, cso);
34
35         return (void *)ps;
36 }
37
38 static void
39 nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
40 {
41         FREE(hwcso);
42 }
43
44 static void
45 nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
46 {
47         struct nvfx_context *nvfx = nvfx_context(pipe);
48         unsigned unit;
49
50         for (unit = 0; unit < nr; unit++) {
51                 nvfx->tex_sampler[unit] = sampler[unit];
52                 nvfx->dirty_samplers |= (1 << unit);
53         }
54
55         for (unit = nr; unit < nvfx->nr_samplers; unit++) {
56                 nvfx->tex_sampler[unit] = NULL;
57                 nvfx->dirty_samplers |= (1 << unit);
58         }
59
60         nvfx->nr_samplers = nr;
61         nvfx->dirty |= NVFX_NEW_SAMPLER;
62 }
63
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)
68 {
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];
72         unsigned txf;
73
74         if (!sv)
75                 return NULL;
76
77         sv->base = *templ;
78         sv->base.reference.count = 1;
79         sv->base.texture = NULL;
80         pipe_resource_reference(&sv->base.texture, pt);
81         sv->base.context = pipe;
82
83         txf = NV30_3D_TEX_FORMAT_NO_BORDER;
84
85         switch (pt->target) {
86         case PIPE_TEXTURE_CUBE:
87                 txf |= NV30_3D_TEX_FORMAT_CUBIC;
88                 /* fall-through */
89         case PIPE_TEXTURE_2D:
90         case PIPE_TEXTURE_RECT:
91                 txf |= NV30_3D_TEX_FORMAT_DIMS_2D;
92                 break;
93         case PIPE_TEXTURE_3D:
94                 txf |= NV30_3D_TEX_FORMAT_DIMS_3D;
95                 break;
96         case PIPE_TEXTURE_1D:
97                 txf |= NV30_3D_TEX_FORMAT_DIMS_1D;
98                 break;
99         default:
100                 assert(0);
101         }
102         sv->u.init_fmt = txf;
103
104         sv->swizzle = 0
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);
113
114         sv->filt = tf->sign;
115         sv->wrap = tf->wrap;
116         sv->wrap_mask = ~0;
117
118         if (pt->target == PIPE_TEXTURE_CUBE)
119         {
120                 sv->offset = 0;
121                 sv->npot_size = (pt->width0 << NV30_3D_TEX_NPOT_SIZE_W__SHIFT) | pt->height0;
122         }
123         else
124         {
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);
127
128                 /* apparently, we need to ignore the t coordinate for 1D textures to fix piglit tex1d-2dborder */
129                 if(pt->target == PIPE_TEXTURE_1D)
130                 {
131                         sv->wrap_mask &=~ NV30_3D_TEX_WRAP_T__MASK;
132                         sv->wrap |= NV30_3D_TEX_WRAP_T_REPEAT;
133                 }
134         }
135
136         if(nvfx->is_nv4x)
137                 nv40_sampler_view_init(pipe, sv);
138         else
139                 nv30_sampler_view_init(pipe, sv);
140
141         return &sv->base;
142 }
143
144 static void
145 nvfx_sampler_view_destroy(struct pipe_context *pipe,
146                           struct pipe_sampler_view *view)
147 {
148         pipe_resource_reference(&view->texture, NULL);
149         FREE(view);
150 }
151
152 static void
153 nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
154                                 unsigned nr,
155                                 struct pipe_sampler_view **views)
156 {
157         struct nvfx_context *nvfx = nvfx_context(pipe);
158         unsigned unit;
159
160         for (unit = 0; unit < nr; unit++) {
161                 pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
162                                             views[unit]);
163                 nvfx->dirty_samplers |= (1 << unit);
164         }
165
166         for (unit = nr; unit < nvfx->nr_textures; unit++) {
167                 pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
168                                             NULL);
169                 nvfx->dirty_samplers |= (1 << unit);
170         }
171
172         nvfx->nr_textures = nr;
173         nvfx->dirty |= NVFX_NEW_SAMPLER;
174 }
175
176 void
177 nvfx_fragtex_validate(struct nvfx_context *nvfx)
178 {
179         struct nouveau_channel* chan = nvfx->screen->base.channel;
180         struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
181         unsigned samplers, unit;
182
183         samplers = nvfx->dirty_samplers;
184         if(!samplers)
185                 return;
186
187         while (samplers) {
188                 unit = ffs(samplers) - 1;
189                 samplers &= ~(1 << unit);
190
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,
194                                         nvfx_surface_flush);
195
196                         if(!nvfx->is_nv4x)
197                                 nv30_fragtex_set(nvfx, unit);
198                         else
199                                 nv40_fragtex_set(nvfx, unit);
200                 } else {
201                         /* this is OK for nv40 too */
202                         BEGIN_RING(chan, eng3d, NV30_3D_TEX_ENABLE(unit), 1);
203                         OUT_RING(chan, 0);
204                         nvfx->hw_samplers &= ~(1 << unit);
205                 }
206         }
207         nvfx->dirty_samplers = 0;
208         nvfx->relocs_needed &=~ NVFX_RELOCATE_FRAGTEX;
209 }
210
211 void
212 nvfx_fragtex_relocate(struct nvfx_context *nvfx)
213 {
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;
217
218         samplers = nvfx->hw_samplers;
219         while (samplers) {
220                 struct nvfx_miptree* mt;
221                 struct nouveau_bo *bo;
222
223                 unit = ffs(samplers) - 1;
224                 samplers &= ~(1 << unit);
225
226                 mt = (struct nvfx_miptree*)nvfx->fragment_sampler_views[unit]->texture;
227                 bo = mt->base.bo;
228
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);
234         }
235         nvfx->relocs_needed &=~ NVFX_RELOCATE_FRAGTEX;
236 }
237
238 void
239 nvfx_init_sampling_functions(struct nvfx_context *nvfx)
240 {
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;
247 }
248
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
252
253 #define NV40_3D_TEX_FORMAT_FORMAT_HILO16 NV40_3D_TEX_FORMAT_FORMAT_A16L16
254
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
261
262 // TODO: guess!
263 #define NV40_3D_TEX_FORMAT_FORMAT_R32F 0x00001c00
264
265 #define SRGB 0x00700000
266
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}, \
275   sign, wrap, \
276   {ts0z, ts0y, ts0x, ts0w, 0, 1}, {ts1z, ts1y, ts1x, ts1w, 0, 0} \
277 }
278
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)
281
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.
285  *
286  * TODO: is it possible to read 16 bits for Z16? A16 doesn't seem to work, either due to normalization or endianness issues
287  */
288
289 #define T 2
290
291 #define X 3
292 #define Y 2
293 #define Z 1
294 #define W 0
295
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))
297 #define UNORM 0
298
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),
306
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),
310
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),
317
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),
320
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),
323
324         _(B5G6R5_UNORM,         R5G6B5,         T, T, T, 1, X, Y, Z, W, UNORM, 0),
325
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),
332
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),
337
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),
346
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),
350
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),
355
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)
359 };