diff options
Diffstat (limited to 'src/gallium/drivers/nvc0/nvc0_tex.c')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_tex.c | 165 |
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 | ||
277 | static boolean | ||
278 | nve4_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 | |||
274 | void nvc0_validate_textures(struct nvc0_context *nvc0) | 334 | void 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 | ||
398 | static boolean | ||
399 | nve4_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 | |||
332 | void nvc0_validate_samplers(struct nvc0_context *nvc0) | 442 | void 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 | */ | ||
466 | void | ||
467 | nve4_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 | } | ||