summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nvc0/nvc0_tex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_tex.c')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c165
1 files changed, 159 insertions, 6 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index f6c4ab39bd9..8dd7185bcdf 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -26,6 +26,9 @@
26 26
27#include "util/u_format.h" 27#include "util/u_format.h"
28 28
29#define NVE4_TIC_ENTRY_INVALID 0x000fffff
30#define NVE4_TSC_ENTRY_INVALID 0xfff00000
31
29#define NV50_TIC_0_SWIZZLE__MASK \ 32#define NV50_TIC_0_SWIZZLE__MASK \
30 (NV50_TIC_0_MAPA__MASK | NV50_TIC_0_MAPB__MASK | \ 33 (NV50_TIC_0_MAPA__MASK | NV50_TIC_0_MAPB__MASK | \
31 NV50_TIC_0_MAPG__MASK | NV50_TIC_0_MAPR__MASK) 34 NV50_TIC_0_MAPG__MASK | NV50_TIC_0_MAPR__MASK)
@@ -271,13 +274,76 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
271 return need_flush; 274 return need_flush;
272} 275}
273 276
277static boolean
278nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
279{
280 struct nouveau_bo *txc = nvc0->screen->txc;
281 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
282 unsigned i;
283 boolean need_flush = FALSE;
284
285 for (i = 0; i < nvc0->num_textures[s]; ++i) {
286 struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
287 struct nv04_resource *res;
288 const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
289
290 if (!tic) {
291 nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
292 continue;
293 }
294 res = nv04_resource(tic->pipe.texture);
295
296 if (tic->id < 0) {
297 tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
298
299 PUSH_SPACE(push, 16);
300 BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
301 PUSH_DATAh(push, txc->offset + (tic->id * 32));
302 PUSH_DATA (push, txc->offset + (tic->id * 32));
303 BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
304 PUSH_DATA (push, 32);
305 PUSH_DATA (push, 1);
306 BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
307 PUSH_DATA (push, 0x1001);
308 PUSH_DATAp(push, &tic->tic[0], 8);
309
310 need_flush = TRUE;
311 } else
312 if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
313 BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
314 PUSH_DATA (push, (tic->id << 4) | 1);
315 }
316 nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
317
318 res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
319 res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
320
321 nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
322 nvc0->tex_handles[s][i] |= tic->id;
323 if (dirty)
324 BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
325 }
326 for (; i < nvc0->state.num_textures[s]; ++i)
327 nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
328
329 nvc0->state.num_textures[s] = nvc0->num_textures[s];
330
331 return need_flush;
332}
333
274void nvc0_validate_textures(struct nvc0_context *nvc0) 334void nvc0_validate_textures(struct nvc0_context *nvc0)
275{ 335{
276 boolean need_flush; 336 boolean need_flush;
277 337
278 need_flush = nvc0_validate_tic(nvc0, 0); 338 if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
279 need_flush |= nvc0_validate_tic(nvc0, 3); 339 need_flush = nve4_validate_tic(nvc0, 0);
280 need_flush |= nvc0_validate_tic(nvc0, 4); 340 need_flush |= nve4_validate_tic(nvc0, 3);
341 need_flush |= nve4_validate_tic(nvc0, 4);
342 } else {
343 need_flush = nvc0_validate_tic(nvc0, 0);
344 need_flush |= nvc0_validate_tic(nvc0, 3);
345 need_flush |= nvc0_validate_tic(nvc0, 4);
346 }
281 347
282 if (need_flush) { 348 if (need_flush) {
283 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1); 349 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
@@ -329,16 +395,103 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
329 return need_flush; 395 return need_flush;
330} 396}
331 397
398static boolean
399nve4_validate_tsc(struct nvc0_context *nvc0, int s)
400{
401 struct nouveau_bo *txc = nvc0->screen->txc;
402 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
403 unsigned i;
404 boolean need_flush = FALSE;
405
406 for (i = 0; i < nvc0->num_samplers[s]; ++i) {
407 struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
408
409 if (!tsc) {
410 nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
411 continue;
412 }
413 if (tsc->id < 0) {
414 tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
415
416 PUSH_SPACE(push, 16);
417 BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
418 PUSH_DATAh(push, txc->offset + 65536 + (tsc->id * 32));
419 PUSH_DATA (push, txc->offset + 65536 + (tsc->id * 32));
420 BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
421 PUSH_DATA (push, 32);
422 PUSH_DATA (push, 1);
423 BEGIN_1IC0(push, NVE4_P2MF(EXEC), 9);
424 PUSH_DATA (push, 0x1001);
425 PUSH_DATAp(push, &tsc->tsc[0], 8);
426
427 need_flush = TRUE;
428 }
429 nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
430
431 nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID;
432 nvc0->tex_handles[s][i] |= tsc->id << 20;
433 }
434 for (; i < nvc0->state.num_samplers[s]; ++i)
435 nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
436
437 nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
438
439 return need_flush;
440}
441
332void nvc0_validate_samplers(struct nvc0_context *nvc0) 442void nvc0_validate_samplers(struct nvc0_context *nvc0)
333{ 443{
334 boolean need_flush; 444 boolean need_flush;
335 445
336 need_flush = nvc0_validate_tsc(nvc0, 0); 446 if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
337 need_flush |= nvc0_validate_tsc(nvc0, 3); 447 need_flush = nve4_validate_tsc(nvc0, 0);
338 need_flush |= nvc0_validate_tsc(nvc0, 4); 448 need_flush |= nve4_validate_tsc(nvc0, 3);
449 need_flush |= nve4_validate_tsc(nvc0, 4);
450 } else {
451 need_flush = nvc0_validate_tsc(nvc0, 0);
452 need_flush |= nvc0_validate_tsc(nvc0, 3);
453 need_flush |= nvc0_validate_tsc(nvc0, 4);
454 }
339 455
340 if (need_flush) { 456 if (need_flush) {
341 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1); 457 BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
342 PUSH_DATA (nvc0->base.pushbuf, 0); 458 PUSH_DATA (nvc0->base.pushbuf, 0);
343 } 459 }
344} 460}
461
462/* Upload the "diagonal" entries for the possible texture sources ($t == $s).
463 * At some point we might want to get a list of the combinations used by a
464 * shader and fill in those entries instead of having it extract the handles.
465 */
466void
467nve4_set_tex_handles(struct nvc0_context *nvc0)
468{
469 struct nouveau_pushbuf *push = nvc0->base.pushbuf;
470 uint64_t address;
471 unsigned s;
472
473 if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)
474 return;
475 address = nvc0->screen->uniform_bo->offset + (5 << 16);
476
477 for (s = 0; s < 5; ++s, address += (1 << 9)) {
478 uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s];
479 if (!dirty)
480 continue;
481 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
482 PUSH_DATA (push, 512);
483 PUSH_DATAh(push, address);
484 PUSH_DATA (push, address);
485 do {
486 int i = ffs(dirty) - 1;
487 dirty &= ~(1 << i);
488
489 BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
490 PUSH_DATA (push, (8 + i) * 4);
491 PUSH_DATA (push, nvc0->tex_handles[s][i]);
492 } while (dirty);
493
494 nvc0->textures_dirty[s] = 0;
495 nvc0->samplers_dirty[s] = 0;
496 }
497}