aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-03-21 19:18:21 -0400
committerDave Airlie <airlied@redhat.com>2012-03-26 04:53:22 -0400
commit88f50c80748bf5238c88e70ee26c68ac48b94e68 (patch)
tree2b4df17fdb6c690bfdeee9dd7e5b4ed30bbf1836 /drivers/gpu
parent017d213f649c6775e4a4349e50a5631a4e4c7308 (diff)
drm/radeon/kms: add htile support to the cs checker v3
For 6xx+. Required for mesa to use htile support for HiZ/HiS. Userspace will check radeon version 2.14 with is bumped either by tiling patch or stream out patch. This patch only add support for htile relocation which should be enough for any userspace to implement the hyperz (using htile buffer) feature. v2: Jerome: Fix size checking for htile buffer. v3: Jerome: Adapt on top of r600/evergreen cs checker changes, also check htile surface in case only stencil is present. Signed-off-by: Pierre-Eric Pelloux-Prayer <pelloux@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c98
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h8
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c391
-rw-r--r--drivers/gpu/drm/radeon/r600d.h8
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/cayman1
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen1
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r6001
7 files changed, 385 insertions, 123 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index a58b37a2e65a..70089d32b80f 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -80,6 +80,9 @@ struct evergreen_cs_track {
80 bool cb_dirty; 80 bool cb_dirty;
81 bool db_dirty; 81 bool db_dirty;
82 bool streamout_dirty; 82 bool streamout_dirty;
83 u32 htile_offset;
84 u32 htile_surface;
85 struct radeon_bo *htile_bo;
83}; 86};
84 87
85static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) 88static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
@@ -144,6 +147,9 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
144 track->db_s_read_bo = NULL; 147 track->db_s_read_bo = NULL;
145 track->db_s_write_bo = NULL; 148 track->db_s_write_bo = NULL;
146 track->db_dirty = true; 149 track->db_dirty = true;
150 track->htile_bo = NULL;
151 track->htile_offset = 0xFFFFFFFF;
152 track->htile_surface = 0;
147 153
148 for (i = 0; i < 4; i++) { 154 for (i = 0; i < 4; i++) {
149 track->vgt_strmout_size[i] = 0; 155 track->vgt_strmout_size[i] = 0;
@@ -444,6 +450,62 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
444 return 0; 450 return 0;
445} 451}
446 452
453static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
454 unsigned nbx, unsigned nby)
455{
456 struct evergreen_cs_track *track = p->track;
457 unsigned long size;
458
459 if (track->htile_bo == NULL) {
460 dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
461 __func__, __LINE__, track->db_z_info);
462 return -EINVAL;
463 }
464
465 if (G_028ABC_LINEAR(track->htile_surface)) {
466 /* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */
467 nbx = round_up(nbx, 16 * 8);
468 /* height is npipes htiles aligned == npipes * 8 pixel aligned */
469 nby = round_up(nby, track->npipes * 8);
470 } else {
471 switch (track->npipes) {
472 case 8:
473 nbx = round_up(nbx, 64 * 8);
474 nby = round_up(nby, 64 * 8);
475 break;
476 case 4:
477 nbx = round_up(nbx, 64 * 8);
478 nby = round_up(nby, 32 * 8);
479 break;
480 case 2:
481 nbx = round_up(nbx, 32 * 8);
482 nby = round_up(nby, 32 * 8);
483 break;
484 case 1:
485 nbx = round_up(nbx, 32 * 8);
486 nby = round_up(nby, 16 * 8);
487 break;
488 default:
489 dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
490 __func__, __LINE__, track->npipes);
491 return -EINVAL;
492 }
493 }
494 /* compute number of htile */
495 nbx = nbx / 8;
496 nby = nby / 8;
497 size = nbx * nby * 4;
498 size += track->htile_offset;
499
500 if (size > radeon_bo_size(track->htile_bo)) {
501 dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
502 __func__, __LINE__, radeon_bo_size(track->htile_bo),
503 size, nbx, nby);
504 return -EINVAL;
505 }
506 return 0;
507}
508
447static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) 509static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
448{ 510{
449 struct evergreen_cs_track *track = p->track; 511 struct evergreen_cs_track *track = p->track;
@@ -530,6 +592,14 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
530 return -EINVAL; 592 return -EINVAL;
531 } 593 }
532 594
595 /* hyperz */
596 if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
597 r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
598 if (r) {
599 return r;
600 }
601 }
602
533 return 0; 603 return 0;
534} 604}
535 605
@@ -617,6 +687,14 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
617 return -EINVAL; 687 return -EINVAL;
618 } 688 }
619 689
690 /* hyperz */
691 if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
692 r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
693 if (r) {
694 return r;
695 }
696 }
697
620 return 0; 698 return 0;
621} 699}
622 700
@@ -850,7 +928,7 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
850 return r; 928 return r;
851 } 929 }
852 /* Check depth buffer */ 930 /* Check depth buffer */
853 if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) { 931 if (G_028800_Z_ENABLE(track->db_depth_control)) {
854 r = evergreen_cs_track_validate_depth(p); 932 r = evergreen_cs_track_validate_depth(p);
855 if (r) 933 if (r)
856 return r; 934 return r;
@@ -1616,6 +1694,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1616 track->cb_color_bo[tmp] = reloc->robj; 1694 track->cb_color_bo[tmp] = reloc->robj;
1617 track->cb_dirty = true; 1695 track->cb_dirty = true;
1618 break; 1696 break;
1697 case DB_HTILE_DATA_BASE:
1698 r = evergreen_cs_packet_next_reloc(p, &reloc);
1699 if (r) {
1700 dev_warn(p->dev, "bad SET_CONTEXT_REG "
1701 "0x%04X\n", reg);
1702 return -EINVAL;
1703 }
1704 track->htile_offset = radeon_get_ib_value(p, idx);
1705 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1706 track->htile_bo = reloc->robj;
1707 track->db_dirty = true;
1708 break;
1709 case DB_HTILE_SURFACE:
1710 /* 8x8 only */
1711 track->htile_surface = radeon_get_ib_value(p, idx);
1712 track->db_dirty = true;
1713 break;
1619 case CB_IMMED0_BASE: 1714 case CB_IMMED0_BASE:
1620 case CB_IMMED1_BASE: 1715 case CB_IMMED1_BASE:
1621 case CB_IMMED2_BASE: 1716 case CB_IMMED2_BASE:
@@ -1628,7 +1723,6 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1628 case CB_IMMED9_BASE: 1723 case CB_IMMED9_BASE:
1629 case CB_IMMED10_BASE: 1724 case CB_IMMED10_BASE:
1630 case CB_IMMED11_BASE: 1725 case CB_IMMED11_BASE:
1631 case DB_HTILE_DATA_BASE:
1632 case SQ_PGM_START_FS: 1726 case SQ_PGM_START_FS:
1633 case SQ_PGM_START_ES: 1727 case SQ_PGM_START_ES:
1634 case SQ_PGM_START_VS: 1728 case SQ_PGM_START_VS:
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index eb5708c7159d..b4eefc355f16 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -991,6 +991,14 @@
991#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF) 991#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
992#define C_028008_SLICE_MAX 0xFF001FFF 992#define C_028008_SLICE_MAX 0xFF001FFF
993#define DB_HTILE_DATA_BASE 0x28014 993#define DB_HTILE_DATA_BASE 0x28014
994#define DB_HTILE_SURFACE 0x28abc
995#define S_028ABC_HTILE_WIDTH(x) (((x) & 0x1) << 0)
996#define G_028ABC_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
997#define C_028ABC_HTILE_WIDTH 0xFFFFFFFE
998#define S_028ABC_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
999#define G_028ABC_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
1000#define C_028ABC_HTILE_HEIGHT 0xFFFFFFFD
1001#define G_028ABC_LINEAR(x) (((x) >> 2) & 0x1)
994#define DB_Z_INFO 0x28040 1002#define DB_Z_INFO 0x28040
995# define Z_ARRAY_MODE(x) ((x) << 4) 1003# define Z_ARRAY_MODE(x) ((x) << 4)
996# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8) 1004# define DB_TILE_SPLIT(x) (((x) & 0x7) << 8)
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 0ec3f205f9c4..b8e12af304a9 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -78,6 +78,9 @@ struct r600_cs_track {
78 bool cb_dirty; 78 bool cb_dirty;
79 bool db_dirty; 79 bool db_dirty;
80 bool streamout_dirty; 80 bool streamout_dirty;
81 struct radeon_bo *htile_bo;
82 u64 htile_offset;
83 u32 htile_surface;
81}; 84};
82 85
83#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } 86#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
@@ -321,6 +324,9 @@ static void r600_cs_track_init(struct r600_cs_track *track)
321 track->db_depth_size_idx = 0; 324 track->db_depth_size_idx = 0;
322 track->db_depth_control = 0xFFFFFFFF; 325 track->db_depth_control = 0xFFFFFFFF;
323 track->db_dirty = true; 326 track->db_dirty = true;
327 track->htile_bo = NULL;
328 track->htile_offset = 0xFFFFFFFF;
329 track->htile_surface = 0;
324 330
325 for (i = 0; i < 4; i++) { 331 for (i = 0; i < 4; i++) {
326 track->vgt_strmout_size[i] = 0; 332 track->vgt_strmout_size[i] = 0;
@@ -455,12 +461,256 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
455 return 0; 461 return 0;
456} 462}
457 463
464static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
465{
466 struct r600_cs_track *track = p->track;
467 u32 nviews, bpe, ntiles, size, slice_tile_max, tmp;
468 u32 height_align, pitch_align, depth_align;
469 u32 pitch = 8192;
470 u32 height = 8192;
471 u64 base_offset, base_align;
472 struct array_mode_checker array_check;
473 int array_mode;
474 volatile u32 *ib = p->ib->ptr;
475
476
477 if (track->db_bo == NULL) {
478 dev_warn(p->dev, "z/stencil with no depth buffer\n");
479 return -EINVAL;
480 }
481 switch (G_028010_FORMAT(track->db_depth_info)) {
482 case V_028010_DEPTH_16:
483 bpe = 2;
484 break;
485 case V_028010_DEPTH_X8_24:
486 case V_028010_DEPTH_8_24:
487 case V_028010_DEPTH_X8_24_FLOAT:
488 case V_028010_DEPTH_8_24_FLOAT:
489 case V_028010_DEPTH_32_FLOAT:
490 bpe = 4;
491 break;
492 case V_028010_DEPTH_X24_8_32_FLOAT:
493 bpe = 8;
494 break;
495 default:
496 dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
497 return -EINVAL;
498 }
499 if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
500 if (!track->db_depth_size_idx) {
501 dev_warn(p->dev, "z/stencil buffer size not set\n");
502 return -EINVAL;
503 }
504 tmp = radeon_bo_size(track->db_bo) - track->db_offset;
505 tmp = (tmp / bpe) >> 6;
506 if (!tmp) {
507 dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
508 track->db_depth_size, bpe, track->db_offset,
509 radeon_bo_size(track->db_bo));
510 return -EINVAL;
511 }
512 ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
513 } else {
514 size = radeon_bo_size(track->db_bo);
515 /* pitch in pixels */
516 pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
517 slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
518 slice_tile_max *= 64;
519 height = slice_tile_max / pitch;
520 if (height > 8192)
521 height = 8192;
522 base_offset = track->db_bo_mc + track->db_offset;
523 array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
524 array_check.array_mode = array_mode;
525 array_check.group_size = track->group_size;
526 array_check.nbanks = track->nbanks;
527 array_check.npipes = track->npipes;
528 array_check.nsamples = track->nsamples;
529 array_check.blocksize = bpe;
530 if (r600_get_array_mode_alignment(&array_check,
531 &pitch_align, &height_align, &depth_align, &base_align)) {
532 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
533 G_028010_ARRAY_MODE(track->db_depth_info),
534 track->db_depth_info);
535 return -EINVAL;
536 }
537 switch (array_mode) {
538 case V_028010_ARRAY_1D_TILED_THIN1:
539 /* don't break userspace */
540 height &= ~0x7;
541 break;
542 case V_028010_ARRAY_2D_TILED_THIN1:
543 break;
544 default:
545 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
546 G_028010_ARRAY_MODE(track->db_depth_info),
547 track->db_depth_info);
548 return -EINVAL;
549 }
550
551 if (!IS_ALIGNED(pitch, pitch_align)) {
552 dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
553 __func__, __LINE__, pitch, pitch_align, array_mode);
554 return -EINVAL;
555 }
556 if (!IS_ALIGNED(height, height_align)) {
557 dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
558 __func__, __LINE__, height, height_align, array_mode);
559 return -EINVAL;
560 }
561 if (!IS_ALIGNED(base_offset, base_align)) {
562 dev_warn(p->dev, "%s offset 0x%llx, 0x%llx, %d not aligned\n", __func__,
563 base_offset, base_align, array_mode);
564 return -EINVAL;
565 }
566
567 ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
568 nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
569 tmp = ntiles * bpe * 64 * nviews;
570 if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
571 dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
572 array_mode,
573 track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
574 radeon_bo_size(track->db_bo));
575 return -EINVAL;
576 }
577 }
578
579 /* hyperz */
580 if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
581 unsigned long size;
582 unsigned nbx, nby;
583
584 if (track->htile_bo == NULL) {
585 dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
586 __func__, __LINE__, track->db_depth_info);
587 return -EINVAL;
588 }
589 if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
590 dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n",
591 __func__, __LINE__, track->db_depth_size);
592 return -EINVAL;
593 }
594
595 nbx = pitch;
596 nby = height;
597 if (G_028D24_LINEAR(track->htile_surface)) {
598 /* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */
599 nbx = round_up(nbx, 16 * 8);
600 /* nby is npipes htiles aligned == npipes * 8 pixel aligned */
601 nby = round_up(nby, track->npipes * 8);
602 } else {
603 /* htile widht & nby (8 or 4) make 2 bits number */
604 tmp = track->htile_surface & 3;
605 /* align is htile align * 8, htile align vary according to
606 * number of pipe and tile width and nby
607 */
608 switch (track->npipes) {
609 case 8:
610 switch (tmp) {
611 case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
612 nbx = round_up(nbx, 64 * 8);
613 nby = round_up(nby, 64 * 8);
614 break;
615 case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
616 case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
617 nbx = round_up(nbx, 64 * 8);
618 nby = round_up(nby, 32 * 8);
619 break;
620 case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
621 nbx = round_up(nbx, 32 * 8);
622 nby = round_up(nby, 32 * 8);
623 break;
624 default:
625 return -EINVAL;
626 }
627 break;
628 case 4:
629 switch (tmp) {
630 case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
631 nbx = round_up(nbx, 64 * 8);
632 nby = round_up(nby, 32 * 8);
633 break;
634 case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
635 case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
636 nbx = round_up(nbx, 32 * 8);
637 nby = round_up(nby, 32 * 8);
638 break;
639 case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
640 nbx = round_up(nbx, 32 * 8);
641 nby = round_up(nby, 16 * 8);
642 break;
643 default:
644 return -EINVAL;
645 }
646 break;
647 case 2:
648 switch (tmp) {
649 case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
650 nbx = round_up(nbx, 32 * 8);
651 nby = round_up(nby, 32 * 8);
652 break;
653 case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
654 case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
655 nbx = round_up(nbx, 32 * 8);
656 nby = round_up(nby, 16 * 8);
657 break;
658 case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
659 nbx = round_up(nbx, 16 * 8);
660 nby = round_up(nby, 16 * 8);
661 break;
662 default:
663 return -EINVAL;
664 }
665 break;
666 case 1:
667 switch (tmp) {
668 case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
669 nbx = round_up(nbx, 32 * 8);
670 nby = round_up(nby, 16 * 8);
671 break;
672 case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
673 case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
674 nbx = round_up(nbx, 16 * 8);
675 nby = round_up(nby, 16 * 8);
676 break;
677 case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
678 nbx = round_up(nbx, 16 * 8);
679 nby = round_up(nby, 8 * 8);
680 break;
681 default:
682 return -EINVAL;
683 }
684 break;
685 default:
686 dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
687 __func__, __LINE__, track->npipes);
688 return -EINVAL;
689 }
690 }
691 /* compute number of htile */
692 nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4;
693 nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4;
694 size = nbx * nby * 4;
695 size += track->htile_offset;
696
697 if (size > radeon_bo_size(track->htile_bo)) {
698 dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
699 __func__, __LINE__, radeon_bo_size(track->htile_bo),
700 size, nbx, nby);
701 return -EINVAL;
702 }
703 }
704
705 track->db_dirty = false;
706 return 0;
707}
708
458static int r600_cs_track_check(struct radeon_cs_parser *p) 709static int r600_cs_track_check(struct radeon_cs_parser *p)
459{ 710{
460 struct r600_cs_track *track = p->track; 711 struct r600_cs_track *track = p->track;
461 u32 tmp; 712 u32 tmp;
462 int r, i; 713 int r, i;
463 volatile u32 *ib = p->ib->ptr;
464 714
465 /* on legacy kernel we don't perform advanced check */ 715 /* on legacy kernel we don't perform advanced check */
466 if (p->rdev == NULL) 716 if (p->rdev == NULL)
@@ -513,124 +763,14 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
513 track->cb_dirty = false; 763 track->cb_dirty = false;
514 } 764 }
515 765
516 if (track->db_dirty) { 766 /* Check depth buffer */
517 /* Check depth buffer */ 767 if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) ||
518 if (G_028800_STENCIL_ENABLE(track->db_depth_control) || 768 G_028800_Z_ENABLE(track->db_depth_control))) {
519 G_028800_Z_ENABLE(track->db_depth_control)) { 769 r = r600_cs_track_validate_db(p);
520 u32 nviews, bpe, ntiles, size, slice_tile_max; 770 if (r)
521 u32 height, height_align, pitch, pitch_align, depth_align; 771 return r;
522 u64 base_offset, base_align;
523 struct array_mode_checker array_check;
524 int array_mode;
525
526 if (track->db_bo == NULL) {
527 dev_warn(p->dev, "z/stencil with no depth buffer\n");
528 return -EINVAL;
529 }
530 if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) {
531 dev_warn(p->dev, "this kernel doesn't support z/stencil htile\n");
532 return -EINVAL;
533 }
534 switch (G_028010_FORMAT(track->db_depth_info)) {
535 case V_028010_DEPTH_16:
536 bpe = 2;
537 break;
538 case V_028010_DEPTH_X8_24:
539 case V_028010_DEPTH_8_24:
540 case V_028010_DEPTH_X8_24_FLOAT:
541 case V_028010_DEPTH_8_24_FLOAT:
542 case V_028010_DEPTH_32_FLOAT:
543 bpe = 4;
544 break;
545 case V_028010_DEPTH_X24_8_32_FLOAT:
546 bpe = 8;
547 break;
548 default:
549 dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info));
550 return -EINVAL;
551 }
552 if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) {
553 if (!track->db_depth_size_idx) {
554 dev_warn(p->dev, "z/stencil buffer size not set\n");
555 return -EINVAL;
556 }
557 tmp = radeon_bo_size(track->db_bo) - track->db_offset;
558 tmp = (tmp / bpe) >> 6;
559 if (!tmp) {
560 dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n",
561 track->db_depth_size, bpe, track->db_offset,
562 radeon_bo_size(track->db_bo));
563 return -EINVAL;
564 }
565 ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF);
566 } else {
567 size = radeon_bo_size(track->db_bo);
568 /* pitch in pixels */
569 pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8;
570 slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
571 slice_tile_max *= 64;
572 height = slice_tile_max / pitch;
573 if (height > 8192)
574 height = 8192;
575 base_offset = track->db_bo_mc + track->db_offset;
576 array_mode = G_028010_ARRAY_MODE(track->db_depth_info);
577 array_check.array_mode = array_mode;
578 array_check.group_size = track->group_size;
579 array_check.nbanks = track->nbanks;
580 array_check.npipes = track->npipes;
581 array_check.nsamples = track->nsamples;
582 array_check.blocksize = bpe;
583 if (r600_get_array_mode_alignment(&array_check,
584 &pitch_align, &height_align, &depth_align, &base_align)) {
585 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
586 G_028010_ARRAY_MODE(track->db_depth_info),
587 track->db_depth_info);
588 return -EINVAL;
589 }
590 switch (array_mode) {
591 case V_028010_ARRAY_1D_TILED_THIN1:
592 /* don't break userspace */
593 height &= ~0x7;
594 break;
595 case V_028010_ARRAY_2D_TILED_THIN1:
596 break;
597 default:
598 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__,
599 G_028010_ARRAY_MODE(track->db_depth_info),
600 track->db_depth_info);
601 return -EINVAL;
602 }
603
604 if (!IS_ALIGNED(pitch, pitch_align)) {
605 dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n",
606 __func__, __LINE__, pitch, pitch_align, array_mode);
607 return -EINVAL;
608 }
609 if (!IS_ALIGNED(height, height_align)) {
610 dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n",
611 __func__, __LINE__, height, height_align, array_mode);
612 return -EINVAL;
613 }
614 if (!IS_ALIGNED(base_offset, base_align)) {
615 dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i,
616 base_offset, base_align, array_mode);
617 return -EINVAL;
618 }
619
620 ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;
621 nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1;
622 tmp = ntiles * bpe * 64 * nviews;
623 if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {
624 dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",
625 array_mode,
626 track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset,
627 radeon_bo_size(track->db_bo));
628 return -EINVAL;
629 }
630 }
631 }
632 track->db_dirty = false;
633 } 772 }
773
634 return 0; 774 return 0;
635} 775}
636 776
@@ -1244,6 +1384,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
1244 track->db_dirty = true; 1384 track->db_dirty = true;
1245 break; 1385 break;
1246 case DB_HTILE_DATA_BASE: 1386 case DB_HTILE_DATA_BASE:
1387 r = r600_cs_packet_next_reloc(p, &reloc);
1388 if (r) {
1389 dev_warn(p->dev, "bad SET_CONTEXT_REG "
1390 "0x%04X\n", reg);
1391 return -EINVAL;
1392 }
1393 track->htile_offset = radeon_get_ib_value(p, idx) << 8;
1394 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1395 track->htile_bo = reloc->robj;
1396 track->db_dirty = true;
1397 break;
1398 case DB_HTILE_SURFACE:
1399 track->htile_surface = radeon_get_ib_value(p, idx);
1400 track->db_dirty = true;
1401 break;
1247 case SQ_PGM_START_FS: 1402 case SQ_PGM_START_FS:
1248 case SQ_PGM_START_ES: 1403 case SQ_PGM_START_ES:
1249 case SQ_PGM_START_VS: 1404 case SQ_PGM_START_VS:
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 3568a2e345fa..59f9c993cc31 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -195,6 +195,14 @@
195#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) 195#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
196#define DB_DEPTH_BASE 0x2800C 196#define DB_DEPTH_BASE 0x2800C
197#define DB_HTILE_DATA_BASE 0x28014 197#define DB_HTILE_DATA_BASE 0x28014
198#define DB_HTILE_SURFACE 0x28D24
199#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
200#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
201#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
202#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
203#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
204#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
205#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
198#define DB_WATERMARKS 0x9838 206#define DB_WATERMARKS 0x9838
199#define DEPTH_FREE(x) ((x) << 0) 207#define DEPTH_FREE(x) ((x) << 0)
200#define DEPTH_FLUSH(x) ((x) << 5) 208#define DEPTH_FLUSH(x) ((x) << 5)
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman
index aea63c415852..0f656b111c15 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/cayman
+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman
@@ -509,7 +509,6 @@ cayman 0x9400
5090x00028AA8 IA_MULTI_VGT_PARAM 5090x00028AA8 IA_MULTI_VGT_PARAM
5100x00028AB4 VGT_REUSE_OFF 5100x00028AB4 VGT_REUSE_OFF
5110x00028AB8 VGT_VTX_CNT_EN 5110x00028AB8 VGT_VTX_CNT_EN
5120x00028ABC DB_HTILE_SURFACE
5130x00028AC0 DB_SRESULTS_COMPARE_STATE0 5120x00028AC0 DB_SRESULTS_COMPARE_STATE0
5140x00028AC4 DB_SRESULTS_COMPARE_STATE1 5130x00028AC4 DB_SRESULTS_COMPARE_STATE1
5150x00028AC8 DB_PRELOAD_CONTROL 5140x00028AC8 DB_PRELOAD_CONTROL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index 77c37202376f..b912a37689bf 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -519,7 +519,6 @@ evergreen 0x9400
5190x00028AA4 VGT_INSTANCE_STEP_RATE_1 5190x00028AA4 VGT_INSTANCE_STEP_RATE_1
5200x00028AB4 VGT_REUSE_OFF 5200x00028AB4 VGT_REUSE_OFF
5210x00028AB8 VGT_VTX_CNT_EN 5210x00028AB8 VGT_VTX_CNT_EN
5220x00028ABC DB_HTILE_SURFACE
5230x00028AC0 DB_SRESULTS_COMPARE_STATE0 5220x00028AC0 DB_SRESULTS_COMPARE_STATE0
5240x00028AC4 DB_SRESULTS_COMPARE_STATE1 5230x00028AC4 DB_SRESULTS_COMPARE_STATE1
5250x00028AC8 DB_PRELOAD_CONTROL 5240x00028AC8 DB_PRELOAD_CONTROL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index 626c24ea0b56..5e659b034d9a 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -713,7 +713,6 @@ r600 0x9400
7130x0000A710 TD_VS_SAMPLER17_BORDER_RED 7130x0000A710 TD_VS_SAMPLER17_BORDER_RED
7140x00009508 TA_CNTL_AUX 7140x00009508 TA_CNTL_AUX
7150x0002802C DB_DEPTH_CLEAR 7150x0002802C DB_DEPTH_CLEAR
7160x00028D24 DB_HTILE_SURFACE
7170x00028D34 DB_PREFETCH_LIMIT 7160x00028D34 DB_PREFETCH_LIMIT
7180x00028D30 DB_PRELOAD_CONTROL 7170x00028D30 DB_PRELOAD_CONTROL
7190x00028D0C DB_RENDER_CONTROL 7180x00028D0C DB_RENDER_CONTROL