Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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_context.h"
24
#include "nvc0_resource.h"
25
#include "nv50/nv50_texture.xml.h"
26
#include "nv50/nv50_defs.xml.h"
27
 
28
#include "util/u_format.h"
29
 
30
#define NVE4_TIC_ENTRY_INVALID 0x000fffff
31
#define NVE4_TSC_ENTRY_INVALID 0xfff00000
32
 
33
#define NV50_TIC_0_SWIZZLE__MASK                      \
34
   (NV50_TIC_0_MAPA__MASK | NV50_TIC_0_MAPB__MASK |   \
35
    NV50_TIC_0_MAPG__MASK | NV50_TIC_0_MAPR__MASK)
36
 
37
static INLINE uint32_t
38
nv50_tic_swizzle(uint32_t tc, unsigned swz, boolean tex_int)
39
{
40
   switch (swz) {
41
   case PIPE_SWIZZLE_RED:
42
      return (tc & NV50_TIC_0_MAPR__MASK) >> NV50_TIC_0_MAPR__SHIFT;
43
   case PIPE_SWIZZLE_GREEN:
44
      return (tc & NV50_TIC_0_MAPG__MASK) >> NV50_TIC_0_MAPG__SHIFT;
45
   case PIPE_SWIZZLE_BLUE:
46
      return (tc & NV50_TIC_0_MAPB__MASK) >> NV50_TIC_0_MAPB__SHIFT;
47
   case PIPE_SWIZZLE_ALPHA:
48
      return (tc & NV50_TIC_0_MAPA__MASK) >> NV50_TIC_0_MAPA__SHIFT;
49
   case PIPE_SWIZZLE_ONE:
50
      return tex_int ? NV50_TIC_MAP_ONE_INT : NV50_TIC_MAP_ONE_FLOAT;
51
   case PIPE_SWIZZLE_ZERO:
52
   default:
53
      return NV50_TIC_MAP_ZERO;
54
   }
55
}
56
 
57
struct pipe_sampler_view *
58
nvc0_create_sampler_view(struct pipe_context *pipe,
59
                         struct pipe_resource *res,
60
                         const struct pipe_sampler_view *templ)
61
{
62
   uint32_t flags = 0;
63
 
64
   if (res->target == PIPE_TEXTURE_RECT || res->target == PIPE_BUFFER)
65
      flags |= NV50_TEXVIEW_SCALED_COORDS;
66
 
67
   return nvc0_create_texture_view(pipe, res, templ, flags, res->target);
68
}
69
 
70
struct pipe_sampler_view *
71
nvc0_create_texture_view(struct pipe_context *pipe,
72
                         struct pipe_resource *texture,
73
                         const struct pipe_sampler_view *templ,
74
                         uint32_t flags,
75
                         enum pipe_texture_target target)
76
{
77
   const struct util_format_description *desc;
78
   uint64_t address;
79
   uint32_t *tic;
80
   uint32_t swz[4];
81
   uint32_t width, height;
82
   uint32_t depth;
83
   struct nv50_tic_entry *view;
84
   struct nv50_miptree *mt;
85
   boolean tex_int;
86
 
87
   view = MALLOC_STRUCT(nv50_tic_entry);
88
   if (!view)
89
      return NULL;
90
   mt = nv50_miptree(texture);
91
 
92
   view->pipe = *templ;
93
   view->pipe.reference.count = 1;
94
   view->pipe.texture = NULL;
95
   view->pipe.context = pipe;
96
 
97
   view->id = -1;
98
 
99
   pipe_resource_reference(&view->pipe.texture, texture);
100
 
101
   tic = &view->tic[0];
102
 
103
   desc = util_format_description(view->pipe.format);
104
 
105
   tic[0] = nvc0_format_table[view->pipe.format].tic;
106
 
107
   tex_int = util_format_is_pure_integer(view->pipe.format);
108
 
109
   swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r, tex_int);
110
   swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g, tex_int);
111
   swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b, tex_int);
112
   swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a, tex_int);
113
   tic[0] = (tic[0] & ~NV50_TIC_0_SWIZZLE__MASK) |
114
      (swz[0] << NV50_TIC_0_MAPR__SHIFT) |
115
      (swz[1] << NV50_TIC_0_MAPG__SHIFT) |
116
      (swz[2] << NV50_TIC_0_MAPB__SHIFT) |
117
      (swz[3] << NV50_TIC_0_MAPA__SHIFT);
118
 
119
   address = mt->base.address;
120
 
121
   tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
122
 
123
   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
124
      tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
125
 
126
   if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
127
      tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
128
 
129
   /* check for linear storage type */
130
   if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
131
      if (texture->target == PIPE_BUFFER) {
132
         assert(!(tic[2] & NV50_TIC_2_NORMALIZED_COORDS));
133
         address +=
134
            view->pipe.u.buf.first_element * desc->block.bits / 8;
135
         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
136
         tic[3] = 0;
137
         tic[4] = /* width */
138
            view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
139
         tic[5] = 0;
140
      } else {
141
         /* must be 2D texture without mip maps */
142
         tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
143
         tic[3] = mt->level[0].pitch;
144
         tic[4] = mt->base.base.width0;
145
         tic[5] = (1 << 16) | mt->base.base.height0;
146
      }
147
      tic[6] =
148
      tic[7] = 0;
149
      tic[1] = address;
150
      tic[2] |= address >> 32;
151
      return &view->pipe;
152
   }
153
 
154
   tic[2] |=
155
      ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
156
      ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
157
 
158
   depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
159
 
160
   if (mt->base.base.array_size > 1) {
161
      /* there doesn't seem to be a base layer field in TIC */
162
      address += view->pipe.u.tex.first_layer * mt->layer_stride;
163
      depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
164
   }
165
   tic[1] = address;
166
   tic[2] |= address >> 32;
167
 
168
   switch (target) {
169
   case PIPE_TEXTURE_1D:
170
      tic[2] |= NV50_TIC_2_TARGET_1D;
171
      break;
172
   case PIPE_TEXTURE_2D:
173
      tic[2] |= NV50_TIC_2_TARGET_2D;
174
      break;
175
   case PIPE_TEXTURE_RECT:
176
      tic[2] |= NV50_TIC_2_TARGET_RECT;
177
      break;
178
   case PIPE_TEXTURE_3D:
179
      tic[2] |= NV50_TIC_2_TARGET_3D;
180
      break;
181
   case PIPE_TEXTURE_CUBE:
182
      depth /= 6;
183
      tic[2] |= NV50_TIC_2_TARGET_CUBE;
184
      break;
185
   case PIPE_TEXTURE_1D_ARRAY:
186
      tic[2] |= NV50_TIC_2_TARGET_1D_ARRAY;
187
      break;
188
   case PIPE_TEXTURE_2D_ARRAY:
189
      tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY;
190
      break;
191
   case PIPE_TEXTURE_CUBE_ARRAY:
192
      depth /= 6;
193
      tic[2] |= NV50_TIC_2_TARGET_CUBE_ARRAY;
194
      break;
195
   default:
196
      NOUVEAU_ERR("unexpected/invalid texture target: %d\n",
197
                  mt->base.base.target);
198
      return FALSE;
199
   }
200
 
201
   tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
202
 
203
   if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
204
      width = mt->base.base.width0 << mt->ms_x;
205
      height = mt->base.base.height0 << mt->ms_y;
206
   } else {
207
      width = mt->base.base.width0;
208
      height = mt->base.base.height0;
209
   }
210
 
211
   tic[4] = (1 << 31) | width;
212
 
213
   tic[5] = height & 0xffff;
214
   tic[5] |= depth << 16;
215
   tic[5] |= mt->base.base.last_level << 28;
216
 
217
   /* sampling points: (?) */
218
   if (flags & NV50_TEXVIEW_ACCESS_RESOLVE)
219
      tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000;
220
   else
221
      tic[6] = 0x03000000;
222
 
223
   tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
224
   tic[7] |= mt->ms_mode << 12;
225
 
226
   return &view->pipe;
227
}
228
 
229
static boolean
230
nvc0_validate_tic(struct nvc0_context *nvc0, int s)
231
{
232
   uint32_t commands[32];
233
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
234
   struct nouveau_bo *txc = nvc0->screen->txc;
235
   unsigned i;
236
   unsigned n = 0;
237
   boolean need_flush = FALSE;
238
 
239
   for (i = 0; i < nvc0->num_textures[s]; ++i) {
240
      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
241
      struct nv04_resource *res;
242
      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
243
 
244
      if (!tic) {
245
         if (dirty)
246
            commands[n++] = (i << 1) | 0;
247
         continue;
248
      }
249
      res = nv04_resource(tic->pipe.texture);
250
 
251
      if (tic->id < 0) {
252
         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
253
 
254
         PUSH_SPACE(push, 17);
255
         BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
256
         PUSH_DATAh(push, txc->offset + (tic->id * 32));
257
         PUSH_DATA (push, txc->offset + (tic->id * 32));
258
         BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
259
         PUSH_DATA (push, 32);
260
         PUSH_DATA (push, 1);
261
         BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
262
         PUSH_DATA (push, 0x100111);
263
         BEGIN_NIC0(push, NVC0_M2MF(DATA), 8);
264
         PUSH_DATAp(push, &tic->tic[0], 8);
265
 
266
         need_flush = TRUE;
267
      } else
268
      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
269
         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
270
         PUSH_DATA (push, (tic->id << 4) | 1);
271
         NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1);
272
      }
273
      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
274
 
275
      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
276
      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
277
 
278
      if (!dirty)
279
         continue;
280
      commands[n++] = (tic->id << 9) | (i << 1) | 1;
281
 
282
      BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
283
   }
284
   for (; i < nvc0->state.num_textures[s]; ++i)
285
      commands[n++] = (i << 1) | 0;
286
 
287
   nvc0->state.num_textures[s] = nvc0->num_textures[s];
288
 
289
   if (n) {
290
      BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
291
      PUSH_DATAp(push, commands, n);
292
   }
293
   nvc0->textures_dirty[s] = 0;
294
 
295
   return need_flush;
296
}
297
 
298
static boolean
299
nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
300
{
301
   struct nouveau_bo *txc = nvc0->screen->txc;
302
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
303
   unsigned i;
304
   boolean need_flush = FALSE;
305
 
306
   for (i = 0; i < nvc0->num_textures[s]; ++i) {
307
      struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
308
      struct nv04_resource *res;
309
      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
310
 
311
      if (!tic) {
312
         nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
313
         continue;
314
      }
315
      res = nv04_resource(tic->pipe.texture);
316
 
317
      if (tic->id < 0) {
318
         tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
319
 
320
         PUSH_SPACE(push, 16);
321
         BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
322
         PUSH_DATAh(push, txc->offset + (tic->id * 32));
323
         PUSH_DATA (push, txc->offset + (tic->id * 32));
324
         BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
325
         PUSH_DATA (push, 32);
326
         PUSH_DATA (push, 1);
327
         BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
328
         PUSH_DATA (push, 0x1001);
329
         PUSH_DATAp(push, &tic->tic[0], 8);
330
 
331
         need_flush = TRUE;
332
      } else
333
      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
334
         BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
335
         PUSH_DATA (push, (tic->id << 4) | 1);
336
      }
337
      nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
338
 
339
      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
340
      res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
341
 
342
      nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
343
      nvc0->tex_handles[s][i] |= tic->id;
344
      if (dirty)
345
         BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
346
   }
347
   for (; i < nvc0->state.num_textures[s]; ++i) {
348
      nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
349
      nvc0->textures_dirty[s] |= 1 << i;
350
   }
351
 
352
   nvc0->state.num_textures[s] = nvc0->num_textures[s];
353
 
354
   return need_flush;
355
}
356
 
357
void nvc0_validate_textures(struct nvc0_context *nvc0)
358
{
359
   boolean need_flush;
360
 
361
   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
362
      need_flush  = nve4_validate_tic(nvc0, 0);
363
      need_flush |= nve4_validate_tic(nvc0, 3);
364
      need_flush |= nve4_validate_tic(nvc0, 4);
365
   } else {
366
      need_flush  = nvc0_validate_tic(nvc0, 0);
367
      need_flush |= nvc0_validate_tic(nvc0, 3);
368
      need_flush |= nvc0_validate_tic(nvc0, 4);
369
   }
370
 
371
   if (need_flush) {
372
      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
373
      PUSH_DATA (nvc0->base.pushbuf, 0);
374
   }
375
}
376
 
377
static boolean
378
nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
379
{
380
   uint32_t commands[16];
381
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
382
   unsigned i;
383
   unsigned n = 0;
384
   boolean need_flush = FALSE;
385
 
386
   for (i = 0; i < nvc0->num_samplers[s]; ++i) {
387
      struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
388
 
389
      if (!(nvc0->samplers_dirty[s] & (1 << i)))
390
         continue;
391
      if (!tsc) {
392
         commands[n++] = (i << 4) | 0;
393
         continue;
394
      }
395
      if (tsc->id < 0) {
396
         tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
397
 
398
         nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc,
399
                               65536 + tsc->id * 32, NOUVEAU_BO_VRAM,
400
                               32, tsc->tsc);
401
         need_flush = TRUE;
402
      }
403
      nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
404
 
405
      commands[n++] = (tsc->id << 12) | (i << 4) | 1;
406
   }
407
   for (; i < nvc0->state.num_samplers[s]; ++i)
408
      commands[n++] = (i << 4) | 0;
409
 
410
   nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
411
 
412
   if (n) {
413
      BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n);
414
      PUSH_DATAp(push, commands, n);
415
   }
416
   nvc0->samplers_dirty[s] = 0;
417
 
418
   return need_flush;
419
}
420
 
421
boolean
422
nve4_validate_tsc(struct nvc0_context *nvc0, int s)
423
{
424
   struct nouveau_bo *txc = nvc0->screen->txc;
425
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
426
   unsigned i;
427
   boolean need_flush = FALSE;
428
 
429
   for (i = 0; i < nvc0->num_samplers[s]; ++i) {
430
      struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
431
 
432
      if (!tsc) {
433
         nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
434
         continue;
435
      }
436
      if (tsc->id < 0) {
437
         tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
438
 
439
         PUSH_SPACE(push, 16);
440
         BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
441
         PUSH_DATAh(push, txc->offset + 65536 + (tsc->id * 32));
442
         PUSH_DATA (push, txc->offset + 65536 + (tsc->id * 32));
443
         BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
444
         PUSH_DATA (push, 32);
445
         PUSH_DATA (push, 1);
446
         BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
447
         PUSH_DATA (push, 0x1001);
448
         PUSH_DATAp(push, &tsc->tsc[0], 8);
449
 
450
         need_flush = TRUE;
451
      }
452
      nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
453
 
454
      nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID;
455
      nvc0->tex_handles[s][i] |= tsc->id << 20;
456
   }
457
   for (; i < nvc0->state.num_samplers[s]; ++i) {
458
      nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
459
      nvc0->samplers_dirty[s] |= 1 << i;
460
   }
461
 
462
   nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
463
 
464
   return need_flush;
465
}
466
 
467
void nvc0_validate_samplers(struct nvc0_context *nvc0)
468
{
469
   boolean need_flush;
470
 
471
   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
472
      need_flush  = nve4_validate_tsc(nvc0, 0);
473
      need_flush |= nve4_validate_tsc(nvc0, 3);
474
      need_flush |= nve4_validate_tsc(nvc0, 4);
475
   } else {
476
      need_flush  = nvc0_validate_tsc(nvc0, 0);
477
      need_flush |= nvc0_validate_tsc(nvc0, 3);
478
      need_flush |= nvc0_validate_tsc(nvc0, 4);
479
   }
480
 
481
   if (need_flush) {
482
      BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
483
      PUSH_DATA (nvc0->base.pushbuf, 0);
484
   }
485
}
486
 
487
/* Upload the "diagonal" entries for the possible texture sources ($t == $s).
488
 * At some point we might want to get a list of the combinations used by a
489
 * shader and fill in those entries instead of having it extract the handles.
490
 */
491
void
492
nve4_set_tex_handles(struct nvc0_context *nvc0)
493
{
494
   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
495
   uint64_t address;
496
   unsigned s;
497
 
498
   if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)
499
      return;
500
   address = nvc0->screen->uniform_bo->offset + (5 << 16);
501
 
502
   for (s = 0; s < 5; ++s, address += (1 << 9)) {
503
      uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s];
504
      if (!dirty)
505
         continue;
506
      BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
507
      PUSH_DATA (push, 512);
508
      PUSH_DATAh(push, address);
509
      PUSH_DATA (push, address);
510
      do {
511
         int i = ffs(dirty) - 1;
512
         dirty &= ~(1 << i);
513
 
514
         BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
515
         PUSH_DATA (push, (8 + i) * 4);
516
         PUSH_DATA (push, nvc0->tex_handles[s][i]);
517
      } while (dirty);
518
 
519
      nvc0->textures_dirty[s] = 0;
520
      nvc0->samplers_dirty[s] = 0;
521
   }
522
}
523
 
524
 
525
static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT];
526
static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT];
527
static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
528
 
529
void
530
nve4_set_surface_info(struct nouveau_pushbuf *push,
531
                      struct pipe_surface *psf,
532
                      struct nvc0_screen *screen)
533
{
534
   struct nv50_surface *sf = nv50_surface(psf);
535
   struct nv04_resource *res;
536
   uint64_t address;
537
   uint32_t *const info = push->cur;
538
   uint8_t log2cpp;
539
 
540
   if (psf && !nve4_su_format_map[psf->format])
541
      NOUVEAU_ERR("unsupported surface format, try is_format_supported() !\n");
542
 
543
   push->cur += 16;
544
 
545
   if (!psf || !nve4_su_format_map[psf->format]) {
546
      memset(info, 0, 16 * sizeof(*info));
547
 
548
      info[0] = 0xbadf0000;
549
      info[1] = 0x80004000;
550
      info[12] = nve4_suldp_lib_offset[PIPE_FORMAT_R32G32B32A32_UINT] +
551
         screen->lib_code->start;
552
      return;
553
   }
554
   res = nv04_resource(sf->base.texture);
555
 
556
   address = res->address + sf->offset;
557
 
558
   info[8] = sf->width;
559
   info[9] = sf->height;
560
   info[10] = sf->depth;
561
   switch (res->base.target) {
562
   case PIPE_TEXTURE_1D_ARRAY:
563
      info[11] = 1;
564
      break;
565
   case PIPE_TEXTURE_2D:
566
   case PIPE_TEXTURE_RECT:
567
      info[11] = 2;
568
      break;
569
   case PIPE_TEXTURE_3D:
570
      info[11] = 3;
571
      break;
572
   case PIPE_TEXTURE_2D_ARRAY:
573
   case PIPE_TEXTURE_CUBE:
574
   case PIPE_TEXTURE_CUBE_ARRAY:
575
      info[11] = 4;
576
      break;
577
   default:
578
      info[11] = 0;
579
      break;
580
   }
581
   log2cpp = (0xf000 & nve4_su_format_aux_map[sf->base.format]) >> 12;
582
 
583
   info[12] = nve4_suldp_lib_offset[sf->base.format] + screen->lib_code->start;
584
 
585
   /* limit in bytes for raw access */
586
   info[13] = (0x06 << 22) | ((sf->width << log2cpp) - 1);
587
 
588
   info[1] = nve4_su_format_map[sf->base.format];
589
 
590
#if 0
591
   switch (util_format_get_blocksizebits(sf->base.format)) {
592
   case  16: info[1] |= 1 << 16; break;
593
   case  32: info[1] |= 2 << 16; break;
594
   case  64: info[1] |= 3 << 16; break;
595
   case 128: info[1] |= 4 << 16; break;
596
   default:
597
      break;
598
   }
599
#else
600
   info[1] |= log2cpp << 16;
601
   info[1] |=  0x4000;
602
   info[1] |= (0x0f00 & nve4_su_format_aux_map[sf->base.format]);
603
#endif
604
 
605
   if (res->base.target == PIPE_BUFFER) {
606
      info[0]  = address >> 8;
607
      info[2]  = sf->width - 1;
608
      info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
609
      info[3]  = 0;
610
      info[4]  = 0;
611
      info[5]  = 0;
612
      info[6]  = 0;
613
      info[7]  = 0;
614
      info[14] = 0;
615
      info[15] = 0;
616
   } else {
617
      struct nv50_miptree *mt = nv50_miptree(&res->base);
618
      struct nv50_miptree_level *lvl = &mt->level[sf->base.u.tex.level];
619
      const unsigned z = sf->base.u.tex.first_layer;
620
 
621
      if (z) {
622
         if (mt->layout_3d) {
623
            address += nvc0_mt_zslice_offset(mt, psf->u.tex.level, z);
624
            /* doesn't work if z passes z-tile boundary */
625
            assert(sf->depth == 1);
626
         } else {
627
            address += mt->layer_stride * z;
628
         }
629
      }
630
      info[0]  = address >> 8;
631
      info[2]  = sf->width - 1;
632
      /* NOTE: this is really important: */
633
      info[2] |= (0xff & nve4_su_format_aux_map[sf->base.format]) << 22;
634
      info[3]  = (0x88 << 24) | (lvl->pitch / 64);
635
      info[4]  = sf->height - 1;
636
      info[4] |= (lvl->tile_mode & 0x0f0) << 25;
637
      info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22;
638
      info[5]  = mt->layer_stride >> 8;
639
      info[6]  = sf->depth - 1;
640
      info[6] |= (lvl->tile_mode & 0xf00) << 21;
641
      info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22;
642
      info[7]  = 0;
643
      info[14] = mt->ms_x;
644
      info[15] = mt->ms_y;
645
   }
646
}
647
 
648
static INLINE void
649
nvc0_update_surface_bindings(struct nvc0_context *nvc0)
650
{
651
   /* TODO */
652
}
653
 
654
static INLINE void
655
nve4_update_surface_bindings(struct nvc0_context *nvc0)
656
{
657
   /* TODO */
658
}
659
 
660
void
661
nvc0_validate_surfaces(struct nvc0_context *nvc0)
662
{
663
   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
664
      nve4_update_surface_bindings(nvc0);
665
   } else {
666
      nvc0_update_surface_bindings(nvc0);
667
   }
668
}
669
 
670
 
671
static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT] =
672
{
673
   [PIPE_FORMAT_R32G32B32A32_FLOAT] = NVE4_IMAGE_FORMAT_RGBA32_FLOAT,
674
   [PIPE_FORMAT_R32G32B32A32_SINT] = NVE4_IMAGE_FORMAT_RGBA32_SINT,
675
   [PIPE_FORMAT_R32G32B32A32_UINT] = NVE4_IMAGE_FORMAT_RGBA32_UINT,
676
   [PIPE_FORMAT_R16G16B16A16_FLOAT] = NVE4_IMAGE_FORMAT_RGBA16_FLOAT,
677
   [PIPE_FORMAT_R16G16B16A16_UNORM] = NVE4_IMAGE_FORMAT_RGBA16_UNORM,
678
   [PIPE_FORMAT_R16G16B16A16_SNORM] = NVE4_IMAGE_FORMAT_RGBA16_SNORM,
679
   [PIPE_FORMAT_R16G16B16A16_SINT] = NVE4_IMAGE_FORMAT_RGBA16_SINT,
680
   [PIPE_FORMAT_R16G16B16A16_UINT] = NVE4_IMAGE_FORMAT_RGBA16_UINT,
681
   [PIPE_FORMAT_R8G8B8A8_UNORM] = NVE4_IMAGE_FORMAT_RGBA8_UNORM,
682
   [PIPE_FORMAT_R8G8B8A8_SNORM] = NVE4_IMAGE_FORMAT_RGBA8_SNORM,
683
   [PIPE_FORMAT_R8G8B8A8_SINT] = NVE4_IMAGE_FORMAT_RGBA8_SINT,
684
   [PIPE_FORMAT_R8G8B8A8_UINT] = NVE4_IMAGE_FORMAT_RGBA8_UINT,
685
   [PIPE_FORMAT_R11G11B10_FLOAT] = NVE4_IMAGE_FORMAT_R11G11B10_FLOAT,
686
   [PIPE_FORMAT_R10G10B10A2_UNORM] = NVE4_IMAGE_FORMAT_RGB10_A2_UNORM,
687
/* [PIPE_FORMAT_R10G10B10A2_UINT] = NVE4_IMAGE_FORMAT_RGB10_A2_UINT, */
688
   [PIPE_FORMAT_R32G32_FLOAT] = NVE4_IMAGE_FORMAT_RG32_FLOAT,
689
   [PIPE_FORMAT_R32G32_SINT] = NVE4_IMAGE_FORMAT_RG32_SINT,
690
   [PIPE_FORMAT_R32G32_UINT] = NVE4_IMAGE_FORMAT_RG32_UINT,
691
   [PIPE_FORMAT_R16G16_FLOAT] = NVE4_IMAGE_FORMAT_RG16_FLOAT,
692
   [PIPE_FORMAT_R16G16_UNORM] = NVE4_IMAGE_FORMAT_RG16_UNORM,
693
   [PIPE_FORMAT_R16G16_SNORM] = NVE4_IMAGE_FORMAT_RG16_SNORM,
694
   [PIPE_FORMAT_R16G16_SINT] = NVE4_IMAGE_FORMAT_RG16_SINT,
695
   [PIPE_FORMAT_R16G16_UINT] = NVE4_IMAGE_FORMAT_RG16_UINT,
696
   [PIPE_FORMAT_R8G8_UNORM] = NVE4_IMAGE_FORMAT_RG8_UNORM,
697
   [PIPE_FORMAT_R8G8_SNORM] = NVE4_IMAGE_FORMAT_RG8_SNORM,
698
   [PIPE_FORMAT_R8G8_SINT] = NVE4_IMAGE_FORMAT_RG8_SINT,
699
   [PIPE_FORMAT_R8G8_UINT] = NVE4_IMAGE_FORMAT_RG8_UINT,
700
   [PIPE_FORMAT_R32_FLOAT] = NVE4_IMAGE_FORMAT_R32_FLOAT,
701
   [PIPE_FORMAT_R32_SINT] = NVE4_IMAGE_FORMAT_R32_SINT,
702
   [PIPE_FORMAT_R32_UINT] = NVE4_IMAGE_FORMAT_R32_UINT,
703
   [PIPE_FORMAT_R16_FLOAT] = NVE4_IMAGE_FORMAT_R16_FLOAT,
704
   [PIPE_FORMAT_R16_UNORM] = NVE4_IMAGE_FORMAT_R16_UNORM,
705
   [PIPE_FORMAT_R16_SNORM] = NVE4_IMAGE_FORMAT_R16_SNORM,
706
   [PIPE_FORMAT_R16_SINT] = NVE4_IMAGE_FORMAT_R16_SINT,
707
   [PIPE_FORMAT_R16_UINT] = NVE4_IMAGE_FORMAT_R16_UINT,
708
   [PIPE_FORMAT_R8_UNORM] = NVE4_IMAGE_FORMAT_R8_UNORM,
709
   [PIPE_FORMAT_R8_SNORM] = NVE4_IMAGE_FORMAT_R8_SNORM,
710
   [PIPE_FORMAT_R8_SINT] = NVE4_IMAGE_FORMAT_R8_SINT,
711
   [PIPE_FORMAT_R8_UINT] = NVE4_IMAGE_FORMAT_R8_UINT,
712
};
713
 
714
/* Auxiliary format description values for surface instructions.
715
 * (log2(bytes per pixel) << 12) | (unk8 << 8) | unk22
716
 */
717
static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT] =
718
{
719
   [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x4842,
720
   [PIPE_FORMAT_R32G32B32A32_SINT] = 0x4842,
721
   [PIPE_FORMAT_R32G32B32A32_UINT] = 0x4842,
722
 
723
   [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x3933,
724
   [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x3933,
725
   [PIPE_FORMAT_R16G16B16A16_SINT] = 0x3933,
726
   [PIPE_FORMAT_R16G16B16A16_UINT] = 0x3933,
727
   [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3933,
728
 
729
   [PIPE_FORMAT_R32G32_FLOAT] = 0x3433,
730
   [PIPE_FORMAT_R32G32_SINT] = 0x3433,
731
   [PIPE_FORMAT_R32G32_UINT] = 0x3433,
732
 
733
   [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x2a24,
734
/* [PIPE_FORMAT_R10G10B10A2_UINT] = 0x2a24, */
735
   [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x2a24,
736
   [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x2a24,
737
   [PIPE_FORMAT_R8G8B8A8_SINT] = 0x2a24,
738
   [PIPE_FORMAT_R8G8B8A8_UINT] = 0x2a24,
739
   [PIPE_FORMAT_R11G11B10_FLOAT] = 0x2a24,
740
 
741
   [PIPE_FORMAT_R16G16_UNORM] = 0x2524,
742
   [PIPE_FORMAT_R16G16_SNORM] = 0x2524,
743
   [PIPE_FORMAT_R16G16_SINT] = 0x2524,
744
   [PIPE_FORMAT_R16G16_UINT] = 0x2524,
745
   [PIPE_FORMAT_R16G16_FLOAT] = 0x2524,
746
 
747
   [PIPE_FORMAT_R32_SINT] = 0x2024,
748
   [PIPE_FORMAT_R32_UINT] = 0x2024,
749
   [PIPE_FORMAT_R32_FLOAT] = 0x2024,
750
 
751
   [PIPE_FORMAT_R8G8_UNORM] = 0x1615,
752
   [PIPE_FORMAT_R8G8_SNORM] = 0x1615,
753
   [PIPE_FORMAT_R8G8_SINT] = 0x1615,
754
   [PIPE_FORMAT_R8G8_UINT] = 0x1615,
755
 
756
   [PIPE_FORMAT_R16_UNORM] = 0x1115,
757
   [PIPE_FORMAT_R16_SNORM] = 0x1115,
758
   [PIPE_FORMAT_R16_SINT] = 0x1115,
759
   [PIPE_FORMAT_R16_UINT] = 0x1115,
760
   [PIPE_FORMAT_R16_FLOAT] = 0x1115,
761
 
762
   [PIPE_FORMAT_R8_UNORM] = 0x0206,
763
   [PIPE_FORMAT_R8_SNORM] = 0x0206,
764
   [PIPE_FORMAT_R8_SINT] = 0x0206,
765
   [PIPE_FORMAT_R8_UINT] = 0x0206
766
};
767
 
768
/* NOTE: These are hardcoded offsets for the shader library.
769
 * TODO: Automate them.
770
 */
771
static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT] =
772
{
773
   [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x218,
774
   [PIPE_FORMAT_R32G32B32A32_SINT]  = 0x218,
775
   [PIPE_FORMAT_R32G32B32A32_UINT]  = 0x218,
776
   [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x248,
777
   [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x2b8,
778
   [PIPE_FORMAT_R16G16B16A16_SINT]  = 0x330,
779
   [PIPE_FORMAT_R16G16B16A16_UINT]  = 0x388,
780
   [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3d8,
781
   [PIPE_FORMAT_R32G32_FLOAT]       = 0x428,
782
   [PIPE_FORMAT_R32G32_SINT]        = 0x468,
783
   [PIPE_FORMAT_R32G32_UINT]        = 0x468,
784
   [PIPE_FORMAT_R10G10B10A2_UNORM]  = 0x4a8,
785
/* [PIPE_FORMAT_R10G10B10A2_UINT]   = 0x530, */
786
   [PIPE_FORMAT_R8G8B8A8_UNORM]     = 0x588,
787
   [PIPE_FORMAT_R8G8B8A8_SNORM]     = 0x5f8,
788
   [PIPE_FORMAT_R8G8B8A8_SINT]      = 0x670,
789
   [PIPE_FORMAT_R8G8B8A8_UINT]      = 0x6c8,
790
   [PIPE_FORMAT_B5G6R5_UNORM]       = 0x718,
791
   [PIPE_FORMAT_B5G5R5X1_UNORM]     = 0x7a0,
792
   [PIPE_FORMAT_R16G16_UNORM]       = 0x828,
793
   [PIPE_FORMAT_R16G16_SNORM]       = 0x890,
794
   [PIPE_FORMAT_R16G16_SINT]        = 0x8f0,
795
   [PIPE_FORMAT_R16G16_UINT]        = 0x948,
796
   [PIPE_FORMAT_R16G16_FLOAT]       = 0x998,
797
   [PIPE_FORMAT_R32_FLOAT]          = 0x9e8,
798
   [PIPE_FORMAT_R32_SINT]           = 0xa30,
799
   [PIPE_FORMAT_R32_UINT]           = 0xa30,
800
   [PIPE_FORMAT_R8G8_UNORM]         = 0xa78,
801
   [PIPE_FORMAT_R8G8_SNORM]         = 0xae0,
802
   [PIPE_FORMAT_R8G8_UINT]          = 0xb48,
803
   [PIPE_FORMAT_R8G8_SINT]          = 0xb98,
804
   [PIPE_FORMAT_R16_UNORM]          = 0xbe8,
805
   [PIPE_FORMAT_R16_SNORM]          = 0xc48,
806
   [PIPE_FORMAT_R16_SINT]           = 0xca0,
807
   [PIPE_FORMAT_R16_UINT]           = 0xce8,
808
   [PIPE_FORMAT_R16_FLOAT]          = 0xd30,
809
   [PIPE_FORMAT_R8_UNORM]           = 0xd88,
810
   [PIPE_FORMAT_R8_SNORM]           = 0xde0,
811
   [PIPE_FORMAT_R8_SINT]            = 0xe38,
812
   [PIPE_FORMAT_R8_UINT]            = 0xe88,
813
   [PIPE_FORMAT_R11G11B10_FLOAT]    = 0xed0
814
};