nvc0: implement support for maxwell texture headers
[mesa.git] / src / gallium / drivers / nouveau / nvc0 / nvc0_tex.c
1 /*
2 * Copyright 2008 Ben Skeggs
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include "nvc0/nvc0_context.h"
24 #include "nvc0/nvc0_resource.h"
25 #include "nvc0/gm107_texture.xml.h"
26 #include "nv50/g80_texture.xml.h"
27 #include "nv50/g80_defs.xml.h"
28
29 #include "util/u_format.h"
30
31 #define NVE4_TIC_ENTRY_INVALID 0x000fffff
32 #define NVE4_TSC_ENTRY_INVALID 0xfff00000
33
34 static inline uint32_t
35 nv50_tic_swizzle(const struct nvc0_format *fmt, unsigned swz, bool tex_int)
36 {
37 switch (swz) {
38 case PIPE_SWIZZLE_RED : return fmt->tic.src_x;
39 case PIPE_SWIZZLE_GREEN: return fmt->tic.src_y;
40 case PIPE_SWIZZLE_BLUE : return fmt->tic.src_z;
41 case PIPE_SWIZZLE_ALPHA: return fmt->tic.src_w;
42 case PIPE_SWIZZLE_ONE:
43 return tex_int ? G80_TIC_SOURCE_ONE_INT : G80_TIC_SOURCE_ONE_FLOAT;
44 case PIPE_SWIZZLE_ZERO:
45 default:
46 return G80_TIC_SOURCE_ZERO;
47 }
48 }
49
50 struct pipe_sampler_view *
51 nvc0_create_sampler_view(struct pipe_context *pipe,
52 struct pipe_resource *res,
53 const struct pipe_sampler_view *templ)
54 {
55 uint32_t flags = 0;
56
57 if (templ->target == PIPE_TEXTURE_RECT || templ->target == PIPE_BUFFER)
58 flags |= NV50_TEXVIEW_SCALED_COORDS;
59
60 return nvc0_create_texture_view(pipe, res, templ, flags, templ->target);
61 }
62
63 static struct pipe_sampler_view *
64 gm107_create_texture_view(struct pipe_context *pipe,
65 struct pipe_resource *texture,
66 const struct pipe_sampler_view *templ,
67 uint32_t flags,
68 enum pipe_texture_target target)
69 {
70 const struct util_format_description *desc;
71 const struct nvc0_format *fmt;
72 uint64_t address;
73 uint32_t *tic;
74 uint32_t swz[4];
75 uint32_t width, height;
76 uint32_t depth;
77 struct nv50_tic_entry *view;
78 struct nv50_miptree *mt;
79 bool tex_int;
80
81 view = MALLOC_STRUCT(nv50_tic_entry);
82 if (!view)
83 return NULL;
84 mt = nv50_miptree(texture);
85
86 view->pipe = *templ;
87 view->pipe.reference.count = 1;
88 view->pipe.texture = NULL;
89 view->pipe.context = pipe;
90
91 view->id = -1;
92
93 pipe_resource_reference(&view->pipe.texture, texture);
94
95 tic = &view->tic[0];
96
97 desc = util_format_description(view->pipe.format);
98 tex_int = util_format_is_pure_integer(view->pipe.format);
99
100 fmt = &nvc0_format_table[view->pipe.format];
101 swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int);
102 swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int);
103 swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int);
104 swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int);
105
106 tic[0] = fmt->tic.format << GM107_TIC2_0_COMPONENTS_SIZES__SHIFT;
107 tic[0] |= fmt->tic.type_r << GM107_TIC2_0_R_DATA_TYPE__SHIFT;
108 tic[0] |= fmt->tic.type_g << GM107_TIC2_0_G_DATA_TYPE__SHIFT;
109 tic[0] |= fmt->tic.type_b << GM107_TIC2_0_B_DATA_TYPE__SHIFT;
110 tic[0] |= fmt->tic.type_a << GM107_TIC2_0_A_DATA_TYPE__SHIFT;
111 tic[0] |= swz[0] << GM107_TIC2_0_X_SOURCE__SHIFT;
112 tic[0] |= swz[1] << GM107_TIC2_0_Y_SOURCE__SHIFT;
113 tic[0] |= swz[2] << GM107_TIC2_0_Z_SOURCE__SHIFT;
114 tic[0] |= swz[3] << GM107_TIC2_0_W_SOURCE__SHIFT;
115
116 address = mt->base.address;
117
118 tic[3] = GM107_TIC2_3_LOD_ANISO_QUALITY_2;
119 tic[4] = GM107_TIC2_4_SECTOR_PROMOTION_PROMOTE_TO_2_V;
120 tic[4] |= GM107_TIC2_4_BORDER_SIZE_SAMPLER_COLOR;
121
122 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
123 tic[4] |= GM107_TIC2_4_SRGB_CONVERSION;
124
125 if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
126 tic[5] = GM107_TIC2_5_NORMALIZED_COORDS;
127 else
128 tic[5] = 0;
129
130 /* check for linear storage type */
131 if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
132 if (texture->target == PIPE_BUFFER) {
133 assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS));
134 width = view->pipe.u.buf.last_element - view->pipe.u.buf.first_element;
135 address +=
136 view->pipe.u.buf.first_element * desc->block.bits / 8;
137 tic[2] = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER;
138 tic[3] |= width >> 16;
139 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER;
140 tic[4] |= width & 0xffff;
141 } else {
142 assert(!(mt->level[0].pitch & 0x1f));
143 /* must be 2D texture without mip maps */
144 tic[2] = GM107_TIC2_2_HEADER_VERSION_PITCH;
145 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
146 tic[3] |= mt->level[0].pitch >> 5;
147 tic[4] |= mt->base.base.width0 - 1;
148 tic[5] |= 0 << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT;
149 tic[5] |= mt->base.base.height0 - 1;
150 }
151 tic[1] = address;
152 tic[2] |= address >> 32;
153 tic[6] = 0;
154 tic[7] = 0;
155 return &view->pipe;
156 }
157
158 tic[2] = GM107_TIC2_2_HEADER_VERSION_BLOCKLINEAR;
159 tic[3] |=
160 ((mt->level[0].tile_mode & 0x0f0) >> 4 << 3) |
161 ((mt->level[0].tile_mode & 0xf00) >> 8 << 6);
162
163 depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
164
165 if (mt->base.base.array_size > 1) {
166 /* there doesn't seem to be a base layer field in TIC */
167 address += view->pipe.u.tex.first_layer * mt->layer_stride;
168 depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
169 }
170 tic[1] = address;
171 tic[2] |= address >> 32;
172
173 switch (target) {
174 case PIPE_TEXTURE_1D:
175 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D;
176 break;
177 case PIPE_TEXTURE_2D:
178 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D;
179 break;
180 case PIPE_TEXTURE_RECT:
181 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D;
182 break;
183 case PIPE_TEXTURE_3D:
184 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_THREE_D;
185 break;
186 case PIPE_TEXTURE_CUBE:
187 depth /= 6;
188 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBEMAP;
189 break;
190 case PIPE_TEXTURE_1D_ARRAY:
191 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_ARRAY;
192 break;
193 case PIPE_TEXTURE_2D_ARRAY:
194 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_ARRAY;
195 break;
196 case PIPE_TEXTURE_CUBE_ARRAY:
197 depth /= 6;
198 tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBE_ARRAY;
199 break;
200 default:
201 unreachable("unexpected/invalid texture target");
202 }
203
204 tic[3] |= (flags & NV50_TEXVIEW_FILTER_MSAA8) ?
205 GM107_TIC2_3_USE_HEADER_OPT_CONTROL :
206 GM107_TIC2_3_LOD_ANISO_QUALITY_HIGH |
207 GM107_TIC2_3_LOD_ISO_QUALITY_HIGH;
208
209 if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
210 width = mt->base.base.width0 << mt->ms_x;
211 height = mt->base.base.height0 << mt->ms_y;
212 } else {
213 width = mt->base.base.width0;
214 height = mt->base.base.height0;
215 }
216
217 tic[4] |= width - 1;
218
219 tic[5] |= (height - 1) & 0xffff;
220 tic[5] |= (depth - 1) << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT;
221 tic[3] |= mt->base.base.last_level << GM107_TIC2_3_MAX_MIP_LEVEL__SHIFT;
222
223 /* sampling points: (?) */
224 if ((flags & NV50_TEXVIEW_ACCESS_RESOLVE) && mt->ms_x > 1) {
225 tic[6] = GM107_TIC2_6_ANISO_FINE_SPREAD_MODIFIER_CONST_TWO;
226 tic[6] |= GM107_TIC2_6_MAX_ANISOTROPY_2_TO_1;
227 } else {
228 tic[6] = GM107_TIC2_6_ANISO_FINE_SPREAD_FUNC_TWO;
229 tic[6] |= GM107_TIC2_6_ANISO_COARSE_SPREAD_FUNC_ONE;
230 }
231
232 tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
233 tic[7] |= mt->ms_mode << GM107_TIC2_7_MULTI_SAMPLE_COUNT__SHIFT;
234
235 return &view->pipe;
236 }
237
238 static struct pipe_sampler_view *
239 gf100_create_texture_view(struct pipe_context *pipe,
240 struct pipe_resource *texture,
241 const struct pipe_sampler_view *templ,
242 uint32_t flags,
243 enum pipe_texture_target target)
244 {
245 const struct util_format_description *desc;
246 const struct nvc0_format *fmt;
247 uint64_t address;
248 uint32_t *tic;
249 uint32_t swz[4];
250 uint32_t width, height;
251 uint32_t depth;
252 struct nv50_tic_entry *view;
253 struct nv50_miptree *mt;
254 bool tex_int;
255
256 view = MALLOC_STRUCT(nv50_tic_entry);
257 if (!view)
258 return NULL;
259 mt = nv50_miptree(texture);
260
261 view->pipe = *templ;
262 view->pipe.reference.count = 1;
263 view->pipe.texture = NULL;
264 view->pipe.context = pipe;
265
266 view->id = -1;
267
268 pipe_resource_reference(&view->pipe.texture, texture);
269
270 tic = &view->tic[0];
271
272 desc = util_format_description(view->pipe.format);
273
274 fmt = &nvc0_format_table[view->pipe.format];
275
276 tex_int = util_format_is_pure_integer(view->pipe.format);
277
278 swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int);
279 swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int);
280 swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int);
281 swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int);
282 tic[0] = (fmt->tic.format << G80_TIC_0_COMPONENTS_SIZES__SHIFT) |
283 (fmt->tic.type_r << G80_TIC_0_R_DATA_TYPE__SHIFT) |
284 (fmt->tic.type_g << G80_TIC_0_G_DATA_TYPE__SHIFT) |
285 (fmt->tic.type_b << G80_TIC_0_B_DATA_TYPE__SHIFT) |
286 (fmt->tic.type_a << G80_TIC_0_A_DATA_TYPE__SHIFT) |
287 (swz[0] << G80_TIC_0_X_SOURCE__SHIFT) |
288 (swz[1] << G80_TIC_0_Y_SOURCE__SHIFT) |
289 (swz[2] << G80_TIC_0_Z_SOURCE__SHIFT) |
290 (swz[3] << G80_TIC_0_W_SOURCE__SHIFT);
291
292 address = mt->base.address;
293
294 tic[2] = 0x10001000 | G80_TIC_2_BORDER_SOURCE_COLOR;
295
296 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
297 tic[2] |= G80_TIC_2_SRGB_CONVERSION;
298
299 if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
300 tic[2] |= G80_TIC_2_NORMALIZED_COORDS;
301
302 /* check for linear storage type */
303 if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
304 if (texture->target == PIPE_BUFFER) {
305 assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS));
306 address +=
307 view->pipe.u.buf.first_element * desc->block.bits / 8;
308 tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
309 tic[3] = 0;
310 tic[4] = /* width */
311 view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
312 tic[5] = 0;
313 } else {
314 /* must be 2D texture without mip maps */
315 tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
316 tic[3] = mt->level[0].pitch;
317 tic[4] = mt->base.base.width0;
318 tic[5] = (1 << 16) | mt->base.base.height0;
319 }
320 tic[6] =
321 tic[7] = 0;
322 tic[1] = address;
323 tic[2] |= address >> 32;
324 return &view->pipe;
325 }
326
327 tic[2] |=
328 ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
329 ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
330
331 depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
332
333 if (mt->base.base.array_size > 1) {
334 /* there doesn't seem to be a base layer field in TIC */
335 address += view->pipe.u.tex.first_layer * mt->layer_stride;
336 depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
337 }
338 tic[1] = address;
339 tic[2] |= address >> 32;
340
341 switch (target) {
342 case PIPE_TEXTURE_1D:
343 tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D;
344 break;
345 case PIPE_TEXTURE_2D:
346 tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D;
347 break;
348 case PIPE_TEXTURE_RECT:
349 tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D;
350 break;
351 case PIPE_TEXTURE_3D:
352 tic[2] |= G80_TIC_2_TEXTURE_TYPE_THREE_D;
353 break;
354 case PIPE_TEXTURE_CUBE:
355 depth /= 6;
356 tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBEMAP;
357 break;
358 case PIPE_TEXTURE_1D_ARRAY:
359 tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D_ARRAY;
360 break;
361 case PIPE_TEXTURE_2D_ARRAY:
362 tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D_ARRAY;
363 break;
364 case PIPE_TEXTURE_CUBE_ARRAY:
365 depth /= 6;
366 tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBE_ARRAY;
367 break;
368 default:
369 unreachable("unexpected/invalid texture target");
370 }
371
372 tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
373
374 if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
375 width = mt->base.base.width0 << mt->ms_x;
376 height = mt->base.base.height0 << mt->ms_y;
377 } else {
378 width = mt->base.base.width0;
379 height = mt->base.base.height0;
380 }
381
382 tic[4] = (1 << 31) | width;
383
384 tic[5] = height & 0xffff;
385 tic[5] |= depth << 16;
386 tic[5] |= mt->base.base.last_level << 28;
387
388 /* sampling points: (?) */
389 if (flags & NV50_TEXVIEW_ACCESS_RESOLVE)
390 tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000;
391 else
392 tic[6] = 0x03000000;
393
394 tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
395 tic[7] |= mt->ms_mode << 12;
396
397 return &view->pipe;
398 }
399
400 struct pipe_sampler_view *
401 nvc0_create_texture_view(struct pipe_context *pipe,
402 struct pipe_resource *texture,
403 const struct pipe_sampler_view *templ,
404 uint32_t flags,
405 enum pipe_texture_target target)
406 {
407 if (nvc0_context(pipe)->screen->tic.maxwell)
408 return gm107_create_texture_view(pipe, texture, templ, flags, target);
409 return gf100_create_texture_view(pipe, texture, templ, flags, target);
410 }
411
412 static void
413 nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic,
414 struct nv04_resource *res)
415 {
416 uint64_t address = res->address;
417 if (res->base.target != PIPE_BUFFER)
418 return;
419 address += tic->pipe.u.buf.first_element *
420 util_format_get_blocksize(tic->pipe.format);
421 if (tic->tic[1] == (uint32_t)address &&
422 (tic->tic[2] & 0xff) == address >> 32)
423 return;
424
425 nvc0_screen_tic_unlock(nvc0->screen, tic);
426 tic->id = -1;
427 tic->tic[1] = address;
428 tic->tic[2] &= 0xffffff00;
429 tic->tic[2] |= address >> 32;
430 }
431
432 static bool
433 nvc0_validate_tic(struct nvc0_context *nvc0, int s)
434 {
435 uint32_t commands[32];
436 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
437 struct nouveau_bo *txc = nvc0->screen->txc;
438 unsigned i;
439 unsigned n = 0;
440 bool need_flush = false;
441
442 for (i = 0; i < nvc0->num_textures[s]; ++i) {
443 struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
444 struct nv04_resource *res;
445 const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i));
446
447 if (!tic) {
448 if (dirty)
449 commands[n++] = (i << 1) | 0;
450 continue;
451 }
452 res = nv04_resource(tic->pipe.texture);
453 nvc0_update_tic(nvc0, tic, res);
454
455 if (tic->id < 0) {
456 tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
457
458 PUSH_SPACE(push, 17);
459 BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
460 PUSH_DATAh(push, txc->offset + (tic->id * 32));
461 PUSH_DATA (push, txc->offset + (tic->id * 32));
462 BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
463 PUSH_DATA (push, 32);
464 PUSH_DATA (push, 1);
465 BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
466 PUSH_DATA (push, 0x100111);
467 BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
468 PUSH_DATAp(push, &tic->tic[0], 8);
469
470 need_flush = true;
471 } else
472 if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
473 BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
474 PUSH_DATA (push, (tic->id << 4) | 1);
475 NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1);
476 }
477 nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
478
479 res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
480 res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
481
482 if (!dirty)
483 continue;
484 commands[n++] = (tic->id << 9) | (i << 1) | 1;
485
486 BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
487 }
488 for (; i < nvc0->state.num_textures[s]; ++i)
489 commands[n++] = (i << 1) | 0;
490
491 nvc0->state.num_textures[s] = nvc0->num_textures[s];
492
493 if (n) {
494 BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
495 PUSH_DATAp(push, commands, n);
496 }
497 nvc0->textures_dirty[s] = 0;
498
499 return need_flush;
500 }
501
502 static bool
503 nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
504 {
505 struct nouveau_bo *txc = nvc0->screen->txc;
506 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
507 unsigned i;
508 bool need_flush = false;
509
510 for (i = 0; i < nvc0->num_textures[s]; ++i) {
511 struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
512 struct nv04_resource *res;
513 const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i));
514
515 if (!tic) {
516 nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
517 continue;
518 }
519 res = nv04_resource(tic->pipe.texture);
520 nvc0_update_tic(nvc0, tic, res);
521
522 if (tic->id < 0) {
523 tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
524
525 PUSH_SPACE(push, 16);
526 BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_DST_ADDRESS_HIGH), 2);
527 PUSH_DATAh(push, txc->offset + (tic->id * 32));
528 PUSH_DATA (push, txc->offset + (tic->id * 32));
529 BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_LINE_LENGTH_IN), 2);
530 PUSH_DATA (push, 32);
531 PUSH_DATA (push, 1);
532 BEGIN_1IC0(push, NVE4_P2MF(UPLOAD_EXEC), 9);
533 PUSH_DATA (push, 0x1001);
534 PUSH_DATAp(push, &tic->tic[0], 8);
535
536 need_flush = true;
537 } else
538 if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
539 BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
540 PUSH_DATA (push, (tic->id << 4) | 1);
541 }
542 nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
543
544 res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
545 res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
546
547 nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
548 nvc0->tex_handles[s][i] |= tic->id;
549 if (dirty)
550 BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
551 }
552 for (; i < nvc0->state.num_textures[s]; ++i) {
553 nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
554 nvc0->textures_dirty[s] |= 1 << i;
555 }
556
557 nvc0->state.num_textures[s] = nvc0->num_textures[s];
558
559 return need_flush;
560 }
561
562 void nvc0_validate_textures(struct nvc0_context *nvc0)
563 {
564 bool need_flush = false;
565 int i;
566
567 for (i = 0; i < 5; i++) {
568 if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS)
569 need_flush |= nve4_validate_tic(nvc0, i);
570 else
571 need_flush |= nvc0_validate_tic(nvc0, i);
572 }
573
574 if (need_flush) {
575 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
576 PUSH_DATA (nvc0->base.pushbuf, 0);
577 }
578 }
579
580 static bool
581 nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
582 {
583 uint32_t commands[16];
584 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
585 unsigned i;
586 unsigned n = 0;
587 bool need_flush = false;
588
589 for (i = 0; i < nvc0->num_samplers[s]; ++i) {
590 struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
591
592 if (!(nvc0->samplers_dirty[s] & (1 << i)))
593 continue;
594 if (!tsc) {
595 commands[n++] = (i << 4) | 0;
596 continue;
597 }
598 if (tsc->id < 0) {
599 tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
600
601 nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc,
602 65536 + tsc->id * 32, NV_VRAM_DOMAIN(&nvc0->screen->base),
603 32, tsc->tsc);
604 need_flush = true;
605 }
606 nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
607
608 commands[n++] = (tsc->id << 12) | (i << 4) | 1;
609 }
610 for (; i < nvc0->state.num_samplers[s]; ++i)
611 commands[n++] = (i << 4) | 0;
612
613 nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
614
615 if (n) {
616 BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n);
617 PUSH_DATAp(push, commands, n);
618 }
619 nvc0->samplers_dirty[s] = 0;
620
621 return need_flush;
622 }
623
624 bool
625 nve4_validate_tsc(struct nvc0_context *nvc0, int s)
626 {
627 struct nouveau_bo *txc = nvc0->screen->txc;
628 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
629 unsigned i;
630 bool need_flush = false;
631
632 for (i = 0; i < nvc0->num_samplers[s]; ++i) {
633 struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
634
635 if (!tsc) {
636 nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
637 continue;
638 }
639 if (tsc->id < 0) {
640 tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
641
642 PUSH_SPACE(push, 16);
643 BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_DST_ADDRESS_HIGH), 2);
644 PUSH_DATAh(push, txc->offset + 65536 + (tsc->id * 32));
645 PUSH_DATA (push, txc->offset + 65536 + (tsc->id * 32));
646 BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_LINE_LENGTH_IN), 2);
647 PUSH_DATA (push, 32);
648 PUSH_DATA (push, 1);
649 BEGIN_1IC0(push, NVE4_P2MF(UPLOAD_EXEC), 9);
650 PUSH_DATA (push, 0x1001);
651 PUSH_DATAp(push, &tsc->tsc[0], 8);
652
653 need_flush = true;
654 }
655 nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
656
657 nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID;
658 nvc0->tex_handles[s][i] |= tsc->id << 20;
659 }
660 for (; i < nvc0->state.num_samplers[s]; ++i) {
661 nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
662 nvc0->samplers_dirty[s] |= 1 << i;
663 }
664
665 nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
666
667 return need_flush;
668 }
669
670 void nvc0_validate_samplers(struct nvc0_context *nvc0)
671 {
672 bool need_flush = false;
673 int i;
674
675 for (i = 0; i < 5; i++) {
676 if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS)
677 need_flush |= nve4_validate_tsc(nvc0, i);
678 else
679 need_flush |= nvc0_validate_tsc(nvc0, i);
680 }
681
682 if (need_flush) {
683 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
684 PUSH_DATA (nvc0->base.pushbuf, 0);
685 }
686 }
687
688 /* Upload the "diagonal" entries for the possible texture sources ($t == $s).
689 * At some point we might want to get a list of the combinations used by a
690 * shader and fill in those entries instead of having it extract the handles.
691 */
692 void
693 nve4_set_tex_handles(struct nvc0_context *nvc0)
694 {
695 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
696 uint64_t address;
697 unsigned s;
698
699 if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)
700 return;
701 address = nvc0->screen->uniform_bo->offset + (5 << 16);
702
703 for (s = 0; s < 5; ++s, address += (1 << 10)) {
704 uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s];
705 if (!dirty)
706 continue;
707 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
708 PUSH_DATA (push, 1024);
709 PUSH_DATAh(push, address);
710 PUSH_DATA (push, address);
711 do {
712 int i = ffs(dirty) - 1;
713 dirty &= ~(1 << i);
714
715 BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
716 PUSH_DATA (push, (8 + i) * 4);
717 PUSH_DATA (push, nvc0->tex_handles[s][i]);
718 } while (dirty);
719
720 nvc0->textures_dirty[s] = 0;
721 nvc0->samplers_dirty[s] = 0;
722 }
723 }
724
725
726 static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT];
727 static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT];
728 static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
729
730 void
731 nve4_set_surface_info(struct nouveau_pushbuf *push,
732 struct pipe_surface *psf,
733 struct nvc0_screen *screen)
734 {
735 struct nv50_surface *sf = nv50_surface(psf);
736 struct nv04_resource *res;
737 uint64_t address;
738 uint32_t *const info = push->cur;
739 uint8_t log2cpp;
740
741 if (psf && !nve4_su_format_map[psf->format])
742 NOUVEAU_ERR("unsupported surface format, try is_format_supported() !\n");
743
744 push->cur += 16;
745
746 if (!psf || !nve4_su_format_map[psf->format]) {
747 memset(info, 0, 16 * sizeof(*info));
748
749 info[0] = 0xbadf0000;
750 info[1] = 0x80004000;
751 info[12] = nve4_suldp_lib_offset[PIPE_FORMAT_R32G32B32A32_UINT] +
752 screen->lib_code->start;
753 return;
754 }
755 res = nv04_resource(sf->base.texture);
756
757 address = res->address + sf->offset;
758
759 info[8] = sf->width;
760 info[9] = sf->height;
761 info[10] = sf->depth;
762 switch (res->base.target) {
763 case PIPE_TEXTURE_1D_ARRAY:
764 info[11] = 1;
765 break;
766 case PIPE_TEXTURE_2D:
767 case PIPE_TEXTURE_RECT:
768 info[11] = 2;
769 break;
770 case PIPE_TEXTURE_3D:
771 info[11] = 3;
772 break;
773 case PIPE_TEXTURE_2D_ARRAY:
774 case PIPE_TEXTURE_CUBE:
775 case PIPE_TEXTURE_CUBE_ARRAY:
776 info[11] = 4;
777 break;
778 default:
779 info[11] = 0;
780 break;
781 }
782 log2cpp = (0xf000 & nve4_su_format_aux_map[sf->base.format]) >> 12;
783
784 info[12] = nve4_suldp_lib_offset[sf->base.format] + screen->lib_code->start;
785
786 /* limit in bytes for raw access */
787 info[13] = (0x06 << 22) | ((sf->width << log2cpp) - 1);
788
789 info[1] = nve4_su_format_map[sf->base.format];
790
791 #if 0
792 switch (util_format_get_blocksizebits(sf->base.format)) {
793 case 16: info[1] |= 1 << 16; break;
794 case 32: info[1] |= 2 << 16; break;
795 case 64: info[1] |= 3 << 16; break;
796 case 128: info[1] |= 4 << 16; break;
797 default:
798 break;
799 }
800 #else
801 info[1] |= log2cpp << 16;
802 info[1] |= 0x4000;
803 info[1] |= (0x0f00 & nve4_su_format_aux_map[sf->base.format]);
804 #endif
805
806 if (res->base.target == PIPE_BUFFER) {
807 info[0] = address >> 8;
808 info[2] = sf->width - 1;
809 info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
810 info[3] = 0;
811 info[4] = 0;
812 info[5] = 0;
813 info[6] = 0;
814 info[7] = 0;
815 info[14] = 0;
816 info[15] = 0;
817 } else {
818 struct nv50_miptree *mt = nv50_miptree(&res->base);
819 struct nv50_miptree_level *lvl = &mt->level[sf->base.u.tex.level];
820 const unsigned z = sf->base.u.tex.first_layer;
821
822 if (z) {
823 if (mt->layout_3d) {
824 address += nvc0_mt_zslice_offset(mt, psf->u.tex.level, z);
825 /* doesn't work if z passes z-tile boundary */
826 assert(sf->depth == 1);
827 } else {
828 address += mt->layer_stride * z;
829 }
830 }
831 info[0] = address >> 8;
832 info[2] = sf->width - 1;
833 /* NOTE: this is really important: */
834 info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
835 info[3] = (0x88 << 24) | (lvl->pitch / 64);
836 info[4] = sf->height - 1;
837 info[4] |= (lvl->tile_mode & 0x0f0) << 25;
838 info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22;
839 info[5] = mt->layer_stride >> 8;
840 info[6] = sf->depth - 1;
841 info[6] |= (lvl->tile_mode & 0xf00) << 21;
842 info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22;
843 info[7] = 0;
844 info[14] = mt->ms_x;
845 info[15] = mt->ms_y;
846 }
847 }
848
849 static inline void
850 nvc0_update_surface_bindings(struct nvc0_context *nvc0)
851 {
852 /* TODO */
853 }
854
855 static inline void
856 nve4_update_surface_bindings(struct nvc0_context *nvc0)
857 {
858 /* TODO */
859 }
860
861 void
862 nvc0_validate_surfaces(struct nvc0_context *nvc0)
863 {
864 if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
865 nve4_update_surface_bindings(nvc0);
866 } else {
867 nvc0_update_surface_bindings(nvc0);
868 }
869 }
870
871
872 static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT] =
873 {
874 [PIPE_FORMAT_R32G32B32A32_FLOAT] = GK104_IMAGE_FORMAT_RGBA32_FLOAT,
875 [PIPE_FORMAT_R32G32B32A32_SINT] = GK104_IMAGE_FORMAT_RGBA32_SINT,
876 [PIPE_FORMAT_R32G32B32A32_UINT] = GK104_IMAGE_FORMAT_RGBA32_UINT,
877 [PIPE_FORMAT_R16G16B16A16_FLOAT] = GK104_IMAGE_FORMAT_RGBA16_FLOAT,
878 [PIPE_FORMAT_R16G16B16A16_UNORM] = GK104_IMAGE_FORMAT_RGBA16_UNORM,
879 [PIPE_FORMAT_R16G16B16A16_SNORM] = GK104_IMAGE_FORMAT_RGBA16_SNORM,
880 [PIPE_FORMAT_R16G16B16A16_SINT] = GK104_IMAGE_FORMAT_RGBA16_SINT,
881 [PIPE_FORMAT_R16G16B16A16_UINT] = GK104_IMAGE_FORMAT_RGBA16_UINT,
882 [PIPE_FORMAT_R8G8B8A8_UNORM] = GK104_IMAGE_FORMAT_RGBA8_UNORM,
883 [PIPE_FORMAT_R8G8B8A8_SNORM] = GK104_IMAGE_FORMAT_RGBA8_SNORM,
884 [PIPE_FORMAT_R8G8B8A8_SINT] = GK104_IMAGE_FORMAT_RGBA8_SINT,
885 [PIPE_FORMAT_R8G8B8A8_UINT] = GK104_IMAGE_FORMAT_RGBA8_UINT,
886 [PIPE_FORMAT_R11G11B10_FLOAT] = GK104_IMAGE_FORMAT_R11G11B10_FLOAT,
887 [PIPE_FORMAT_R10G10B10A2_UNORM] = GK104_IMAGE_FORMAT_RGB10_A2_UNORM,
888 /* [PIPE_FORMAT_R10G10B10A2_UINT] = GK104_IMAGE_FORMAT_RGB10_A2_UINT, */
889 [PIPE_FORMAT_R32G32_FLOAT] = GK104_IMAGE_FORMAT_RG32_FLOAT,
890 [PIPE_FORMAT_R32G32_SINT] = GK104_IMAGE_FORMAT_RG32_SINT,
891 [PIPE_FORMAT_R32G32_UINT] = GK104_IMAGE_FORMAT_RG32_UINT,
892 [PIPE_FORMAT_R16G16_FLOAT] = GK104_IMAGE_FORMAT_RG16_FLOAT,
893 [PIPE_FORMAT_R16G16_UNORM] = GK104_IMAGE_FORMAT_RG16_UNORM,
894 [PIPE_FORMAT_R16G16_SNORM] = GK104_IMAGE_FORMAT_RG16_SNORM,
895 [PIPE_FORMAT_R16G16_SINT] = GK104_IMAGE_FORMAT_RG16_SINT,
896 [PIPE_FORMAT_R16G16_UINT] = GK104_IMAGE_FORMAT_RG16_UINT,
897 [PIPE_FORMAT_R8G8_UNORM] = GK104_IMAGE_FORMAT_RG8_UNORM,
898 [PIPE_FORMAT_R8G8_SNORM] = GK104_IMAGE_FORMAT_RG8_SNORM,
899 [PIPE_FORMAT_R8G8_SINT] = GK104_IMAGE_FORMAT_RG8_SINT,
900 [PIPE_FORMAT_R8G8_UINT] = GK104_IMAGE_FORMAT_RG8_UINT,
901 [PIPE_FORMAT_R32_FLOAT] = GK104_IMAGE_FORMAT_R32_FLOAT,
902 [PIPE_FORMAT_R32_SINT] = GK104_IMAGE_FORMAT_R32_SINT,
903 [PIPE_FORMAT_R32_UINT] = GK104_IMAGE_FORMAT_R32_UINT,
904 [PIPE_FORMAT_R16_FLOAT] = GK104_IMAGE_FORMAT_R16_FLOAT,
905 [PIPE_FORMAT_R16_UNORM] = GK104_IMAGE_FORMAT_R16_UNORM,
906 [PIPE_FORMAT_R16_SNORM] = GK104_IMAGE_FORMAT_R16_SNORM,
907 [PIPE_FORMAT_R16_SINT] = GK104_IMAGE_FORMAT_R16_SINT,
908 [PIPE_FORMAT_R16_UINT] = GK104_IMAGE_FORMAT_R16_UINT,
909 [PIPE_FORMAT_R8_UNORM] = GK104_IMAGE_FORMAT_R8_UNORM,
910 [PIPE_FORMAT_R8_SNORM] = GK104_IMAGE_FORMAT_R8_SNORM,
911 [PIPE_FORMAT_R8_SINT] = GK104_IMAGE_FORMAT_R8_SINT,
912 [PIPE_FORMAT_R8_UINT] = GK104_IMAGE_FORMAT_R8_UINT,
913 };
914
915 /* Auxiliary format description values for surface instructions.
916 * (log2(bytes per pixel) << 12) | (unk8 << 8) | unk22
917 */
918 static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT] =
919 {
920 [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x4842,
921 [PIPE_FORMAT_R32G32B32A32_SINT] = 0x4842,
922 [PIPE_FORMAT_R32G32B32A32_UINT] = 0x4842,
923
924 [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x3933,
925 [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x3933,
926 [PIPE_FORMAT_R16G16B16A16_SINT] = 0x3933,
927 [PIPE_FORMAT_R16G16B16A16_UINT] = 0x3933,
928 [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3933,
929
930 [PIPE_FORMAT_R32G32_FLOAT] = 0x3433,
931 [PIPE_FORMAT_R32G32_SINT] = 0x3433,
932 [PIPE_FORMAT_R32G32_UINT] = 0x3433,
933
934 [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x2a24,
935 /* [PIPE_FORMAT_R10G10B10A2_UINT] = 0x2a24, */
936 [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x2a24,
937 [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x2a24,
938 [PIPE_FORMAT_R8G8B8A8_SINT] = 0x2a24,
939 [PIPE_FORMAT_R8G8B8A8_UINT] = 0x2a24,
940 [PIPE_FORMAT_R11G11B10_FLOAT] = 0x2a24,
941
942 [PIPE_FORMAT_R16G16_UNORM] = 0x2524,
943 [PIPE_FORMAT_R16G16_SNORM] = 0x2524,
944 [PIPE_FORMAT_R16G16_SINT] = 0x2524,
945 [PIPE_FORMAT_R16G16_UINT] = 0x2524,
946 [PIPE_FORMAT_R16G16_FLOAT] = 0x2524,
947
948 [PIPE_FORMAT_R32_SINT] = 0x2024,
949 [PIPE_FORMAT_R32_UINT] = 0x2024,
950 [PIPE_FORMAT_R32_FLOAT] = 0x2024,
951
952 [PIPE_FORMAT_R8G8_UNORM] = 0x1615,
953 [PIPE_FORMAT_R8G8_SNORM] = 0x1615,
954 [PIPE_FORMAT_R8G8_SINT] = 0x1615,
955 [PIPE_FORMAT_R8G8_UINT] = 0x1615,
956
957 [PIPE_FORMAT_R16_UNORM] = 0x1115,
958 [PIPE_FORMAT_R16_SNORM] = 0x1115,
959 [PIPE_FORMAT_R16_SINT] = 0x1115,
960 [PIPE_FORMAT_R16_UINT] = 0x1115,
961 [PIPE_FORMAT_R16_FLOAT] = 0x1115,
962
963 [PIPE_FORMAT_R8_UNORM] = 0x0206,
964 [PIPE_FORMAT_R8_SNORM] = 0x0206,
965 [PIPE_FORMAT_R8_SINT] = 0x0206,
966 [PIPE_FORMAT_R8_UINT] = 0x0206
967 };
968
969 /* NOTE: These are hardcoded offsets for the shader library.
970 * TODO: Automate them.
971 */
972 static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT] =
973 {
974 [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x218,
975 [PIPE_FORMAT_R32G32B32A32_SINT] = 0x218,
976 [PIPE_FORMAT_R32G32B32A32_UINT] = 0x218,
977 [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x248,
978 [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x2b8,
979 [PIPE_FORMAT_R16G16B16A16_SINT] = 0x330,
980 [PIPE_FORMAT_R16G16B16A16_UINT] = 0x388,
981 [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3d8,
982 [PIPE_FORMAT_R32G32_FLOAT] = 0x428,
983 [PIPE_FORMAT_R32G32_SINT] = 0x468,
984 [PIPE_FORMAT_R32G32_UINT] = 0x468,
985 [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x4a8,
986 /* [PIPE_FORMAT_R10G10B10A2_UINT] = 0x530, */
987 [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x588,
988 [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x5f8,
989 [PIPE_FORMAT_R8G8B8A8_SINT] = 0x670,
990 [PIPE_FORMAT_R8G8B8A8_UINT] = 0x6c8,
991 [PIPE_FORMAT_B5G6R5_UNORM] = 0x718,
992 [PIPE_FORMAT_B5G5R5X1_UNORM] = 0x7a0,
993 [PIPE_FORMAT_R16G16_UNORM] = 0x828,
994 [PIPE_FORMAT_R16G16_SNORM] = 0x890,
995 [PIPE_FORMAT_R16G16_SINT] = 0x8f0,
996 [PIPE_FORMAT_R16G16_UINT] = 0x948,
997 [PIPE_FORMAT_R16G16_FLOAT] = 0x998,
998 [PIPE_FORMAT_R32_FLOAT] = 0x9e8,
999 [PIPE_FORMAT_R32_SINT] = 0xa30,
1000 [PIPE_FORMAT_R32_UINT] = 0xa30,
1001 [PIPE_FORMAT_R8G8_UNORM] = 0xa78,
1002 [PIPE_FORMAT_R8G8_SNORM] = 0xae0,
1003 [PIPE_FORMAT_R8G8_UINT] = 0xb48,
1004 [PIPE_FORMAT_R8G8_SINT] = 0xb98,
1005 [PIPE_FORMAT_R16_UNORM] = 0xbe8,
1006 [PIPE_FORMAT_R16_SNORM] = 0xc48,
1007 [PIPE_FORMAT_R16_SINT] = 0xca0,
1008 [PIPE_FORMAT_R16_UINT] = 0xce8,
1009 [PIPE_FORMAT_R16_FLOAT] = 0xd30,
1010 [PIPE_FORMAT_R8_UNORM] = 0xd88,
1011 [PIPE_FORMAT_R8_SNORM] = 0xde0,
1012 [PIPE_FORMAT_R8_SINT] = 0xe38,
1013 [PIPE_FORMAT_R8_UINT] = 0xe88,
1014 [PIPE_FORMAT_R11G11B10_FLOAT] = 0xed0
1015 };