History

drm/radeon/kms: add a CS ioctl flag not to rewrite tiling flags in the CS

This adds a new optional chunk to the CS ioctl that specifies optional flags to the CS parser. Why this is useful is explained below. Note that some regs no longer need the NOP relocation packet if this feature is enabled. Tested on r300g and r600g with this flag disabled and enabled. Assume there are two contexts sharing the same mipmapped tiled texture. One context wants to render into the first mipmap and the other one wants to render into the last mipmap. As you probably know, the hardware has a MACRO_SWITCH feature, which turns off macro tiling for small mipmaps, but that only applies to samplers. (at least on r300-r500, though later hardware likely behaves the same) So we want to just re-set the tiling flags before rendering (writing packets), right? ... No. The contexts run in parallel, so they may set the tiling flags simultaneously and then fire their command streams also simultaneously. The last one setting the flags wins, the other one loses. Another problem is when one context wants to render into the first and the last mipmap in one CS. Impossible. It must flush before changing tiling flags and do the rendering into the smaller mipmaps in another CS. Yet another problem is that writing copy_blit in userspace would be a mess involving re-setting tiling flags to please the kernel, and causing races with other contexts at the same time. The only way out of this is to send tiling flags with each CS, ideally with each relocation. But we already do that through the registers. So let's just use what we have in the registers.

Marek Olšák committed 15 years ago

Commit e70f2241 parent 6991b8f7 files · +135 −98Browse files

Unified · Split

7 files
  1. drivers/gpu/drm/radeon/evergreen_cs.c +50 −42
  2. drivers/gpu/drm/radeon/r300.c +51 −43
  3. drivers/gpu/drm/radeon/r600_cs.c +16 −10
  4. drivers/gpu/drm/radeon/radeon.h +2 −1
  5. drivers/gpu/drm/radeon/radeon_cs.c +10 −1
  6. drivers/gpu/drm/radeon/radeon_drv.c +2 −1
  7. include/drm/radeon_drm.h +4 −0
drivers/gpu/drm/radeon/evergreen_cs.c+50−42
@@ -480,21 +480,23 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) · 479 unmodified lines
480480 }
481481 break;
482482 case DB_Z_INFO:
483− r = evergreen_cs_packet_next_reloc(p, &reloc);
484− if (r) {
485− dev_warn(p->dev, "bad SET_CONTEXT_REG "
486− "0x%04X\n", reg);
487− return -EINVAL;
488− }
489483 track->db_z_info = radeon_get_ib_value(p, idx);
490− ib[idx] &= ~Z_ARRAY_MODE(0xf);
491− track->db_z_info &= ~Z_ARRAY_MODE(0xf);
492− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
493− ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
494− track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
495− } else {
496− ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
497− track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
484+ if (!p->keep_tiling_flags) {
485+ r = evergreen_cs_packet_next_reloc(p, &reloc);
486+ if (r) {
487+ dev_warn(p->dev, "bad SET_CONTEXT_REG "
488+ "0x%04X\n", reg);
489+ return -EINVAL;
490+ }
491+ ib[idx] &= ~Z_ARRAY_MODE(0xf);
492+ track->db_z_info &= ~Z_ARRAY_MODE(0xf);
493+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
494+ ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
495+ track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
496+ } else {
497+ ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
498+ track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
499+ }
498500 }
499501 break;
500502 case DB_STENCIL_INFO:
@@ -607,40 +609,44 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) · 106 unmodified lines
607609 case CB_COLOR5_INFO:
608610 case CB_COLOR6_INFO:
609611 case CB_COLOR7_INFO:
610− r = evergreen_cs_packet_next_reloc(p, &reloc);
611− if (r) {
612− dev_warn(p->dev, "bad SET_CONTEXT_REG "
613− "0x%04X\n", reg);
614− return -EINVAL;
615− }
616612 tmp = (reg - CB_COLOR0_INFO) / 0x3c;
617613 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
618− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
619− ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
620− track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
621− } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
622− ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
623− track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
614+ if (!p->keep_tiling_flags) {
615+ r = evergreen_cs_packet_next_reloc(p, &reloc);
616+ if (r) {
617+ dev_warn(p->dev, "bad SET_CONTEXT_REG "
618+ "0x%04X\n", reg);
619+ return -EINVAL;
620+ }
621+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
622+ ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
623+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
624+ } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
625+ ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
626+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
627+ }
624628 }
625629 break;
626630 case CB_COLOR8_INFO:
627631 case CB_COLOR9_INFO:
628632 case CB_COLOR10_INFO:
629633 case CB_COLOR11_INFO:
630− r = evergreen_cs_packet_next_reloc(p, &reloc);
631− if (r) {
632− dev_warn(p->dev, "bad SET_CONTEXT_REG "
633− "0x%04X\n", reg);
634− return -EINVAL;
635− }
636634 tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
637635 track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
638− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
639− ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
640− track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
641− } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
642− ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
643− track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
636+ if (!p->keep_tiling_flags) {
637+ r = evergreen_cs_packet_next_reloc(p, &reloc);
638+ if (r) {
639+ dev_warn(p->dev, "bad SET_CONTEXT_REG "
640+ "0x%04X\n", reg);
641+ return -EINVAL;
642+ }
643+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
644+ ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
645+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
646+ } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
647+ ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
648+ track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
649+ }
644650 }
645651 break;
646652 case CB_COLOR0_PITCH:
@@ -1311,10 +1317,12 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, · 664 unmodified lines
13111317 return -EINVAL;
13121318 }
13131319 ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1314− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1315− ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
1316− else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1317− ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
1320+ if (!p->keep_tiling_flags) {
1321+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1322+ ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
1323+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1324+ ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
1325+ }
13181326 texture = reloc->robj;
13191327 /* tex mip base */
13201328 r = evergreen_cs_packet_next_reloc(p, &reloc);
drivers/gpu/drm/radeon/r300.c+51−43
@@ -701,16 +701,21 @@ static int r300_packet0_check(struct radeon_cs_parser *p, · 700 unmodified lines
701701 return r;
702702 }
703703
704− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
705− tile_flags |= R300_TXO_MACRO_TILE;
706− if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
707− tile_flags |= R300_TXO_MICRO_TILE;
708− else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
709− tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
710−
711− tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
712− tmp |= tile_flags;
713− ib[idx] = tmp;
704+ if (p->keep_tiling_flags) {
705+ ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */
706+ ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset);
707+ } else {
708+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
709+ tile_flags |= R300_TXO_MACRO_TILE;
710+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
711+ tile_flags |= R300_TXO_MICRO_TILE;
712+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
713+ tile_flags |= R300_TXO_MICRO_TILE_SQUARE;
714+
715+ tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
716+ tmp |= tile_flags;
717+ ib[idx] = tmp;
718+ }
714719 track->textures[i].robj = reloc->robj;
715720 track->tex_dirty = true;
716721 break;
@@ -760,24 +765,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, · 43 unmodified lines
760765 /* RB3D_COLORPITCH1 */
761766 /* RB3D_COLORPITCH2 */
762767 /* RB3D_COLORPITCH3 */
763− r = r100_cs_packet_next_reloc(p, &reloc);
764− if (r) {
765− DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
766− idx, reg);
767− r100_cs_dump_packet(p, pkt);
768− return r;
769− }
768+ if (!p->keep_tiling_flags) {
769+ r = r100_cs_packet_next_reloc(p, &reloc);
770+ if (r) {
771+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
772+ idx, reg);
773+ r100_cs_dump_packet(p, pkt);
774+ return r;
775+ }
770776
771− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
772− tile_flags |= R300_COLOR_TILE_ENABLE;
773− if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
774− tile_flags |= R300_COLOR_MICROTILE_ENABLE;
775− else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
776− tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
777+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
778+ tile_flags |= R300_COLOR_TILE_ENABLE;
779+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
780+ tile_flags |= R300_COLOR_MICROTILE_ENABLE;
781+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
782+ tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE;
777783
778− tmp = idx_value & ~(0x7 << 16);
779− tmp |= tile_flags;
780− ib[idx] = tmp;
784+ tmp = idx_value & ~(0x7 << 16);
785+ tmp |= tile_flags;
786+ ib[idx] = tmp;
787+ }
781788 i = (reg - 0x4E38) >> 2;
782789 track->cb[i].pitch = idx_value & 0x3FFE;
783790 switch (((idx_value >> 21) & 0xF)) {
@@ -843,25 +850,26 @@ static int r300_packet0_check(struct radeon_cs_parser *p, · 59 unmodified lines
843850 break;
844851 case 0x4F24:
845852 /* ZB_DEPTHPITCH */
846− r = r100_cs_packet_next_reloc(p, &reloc);
847− if (r) {
848− DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
849− idx, reg);
850− r100_cs_dump_packet(p, pkt);
851− return r;
852− }
853−
854− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
855− tile_flags |= R300_DEPTHMACROTILE_ENABLE;
856− if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
857− tile_flags |= R300_DEPTHMICROTILE_TILED;
858− else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
859− tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
853+ if (!p->keep_tiling_flags) {
854+ r = r100_cs_packet_next_reloc(p, &reloc);
855+ if (r) {
856+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
857+ idx, reg);
858+ r100_cs_dump_packet(p, pkt);
859+ return r;
860+ }
860861
861− tmp = idx_value & ~(0x7 << 16);
862− tmp |= tile_flags;
863− ib[idx] = tmp;
862+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
863+ tile_flags |= R300_DEPTHMACROTILE_ENABLE;
864+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
865+ tile_flags |= R300_DEPTHMICROTILE_TILED;
866+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE)
867+ tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE;
864868
869+ tmp = idx_value & ~(0x7 << 16);
870+ tmp |= tile_flags;
871+ ib[idx] = tmp;
872+ }
865873 track->zb.pitch = idx_value & 0x3FFC;
866874 track->zb_dirty = true;
867875 break;
drivers/gpu/drm/radeon/r600_cs.c+16−10
@@ -941,7 +941,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) · 940 unmodified lines
941941 track->db_depth_control = radeon_get_ib_value(p, idx);
942942 break;
943943 case R_028010_DB_DEPTH_INFO:
944− if (r600_cs_packet_next_is_pkt3_nop(p)) {
944+ if (!p->keep_tiling_flags &&
945+ r600_cs_packet_next_is_pkt3_nop(p)) {
945946 r = r600_cs_packet_next_reloc(p, &reloc);
946947 if (r) {
947948 dev_warn(p->dev, "bad SET_CONTEXT_REG "
@@ -992,7 +993,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) · 44 unmodified lines
992993 case R_0280B4_CB_COLOR5_INFO:
993994 case R_0280B8_CB_COLOR6_INFO:
994995 case R_0280BC_CB_COLOR7_INFO:
995− if (r600_cs_packet_next_is_pkt3_nop(p)) {
996+ if (!p->keep_tiling_flags &&
997+ r600_cs_packet_next_is_pkt3_nop(p)) {
996998 r = r600_cs_packet_next_reloc(p, &reloc);
997999 if (r) {
9981000 dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
@@ -1291,10 +1293,12 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, · 292 unmodified lines
12911293 mip_offset <<= 8;
12921294
12931295 word0 = radeon_get_ib_value(p, idx + 0);
1294− if (tiling_flags & RADEON_TILING_MACRO)
1295− word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1296− else if (tiling_flags & RADEON_TILING_MICRO)
1297− word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1296+ if (!p->keep_tiling_flags) {
1297+ if (tiling_flags & RADEON_TILING_MACRO)
1298+ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1299+ else if (tiling_flags & RADEON_TILING_MICRO)
1300+ word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1301+ }
12981302 word1 = radeon_get_ib_value(p, idx + 1);
12991303 w0 = G_038000_TEX_WIDTH(word0) + 1;
13001304 h0 = G_038004_TEX_HEIGHT(word1) + 1;
@@ -1621,10 +1625,12 @@ static int r600_packet3_check(struct radeon_cs_parser *p, · 320 unmodified lines
16211625 return -EINVAL;
16221626 }
16231627 base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1624− if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1625− ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1626− else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1627− ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1628+ if (!p->keep_tiling_flags) {
1629+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1630+ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1631+ else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1632+ ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
1633+ }
16281634 texture = reloc->robj;
16291635 /* tex mip base */
16301636 r = r600_cs_packet_next_reloc(p, &reloc);
drivers/gpu/drm/radeon/radeon.h+2−1
@@ -611,7 +611,8 @@ struct radeon_cs_parser { · 610 unmodified lines
611611 struct radeon_ib *ib;
612612 void *track;
613613 unsigned family;
614− int parser_error;
614+ int parser_error;
615+ bool keep_tiling_flags;
615616 };
616617
617618 extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
drivers/gpu/drm/radeon/radeon_cs.c+10−1
@@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) · 92 unmodified lines
9393 {
9494 struct drm_radeon_cs *cs = data;
9595 uint64_t *chunk_array_ptr;
96− unsigned size, i;
96+ unsigned size, i, flags = 0;
9797
9898 if (!cs->num_chunks) {
9999 return 0;
@@ -140,6 +140,10 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) · 40 unmodified lines
140140 if (p->chunks[i].length_dw == 0)
141141 return -EINVAL;
142142 }
143+ if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS &&
144+ !p->chunks[i].length_dw) {
145+ return -EINVAL;
146+ }
143147
144148 p->chunks[i].length_dw = user_chunk.length_dw;
145149 p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
@@ -155,6 +159,9 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) · 9 unmodified lines
155159 p->chunks[i].user_ptr, size)) {
156160 return -EFAULT;
157161 }
162+ if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) {
163+ flags = p->chunks[i].kdata[0];
164+ }
158165 } else {
159166 p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
160167 p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -174,6 +181,8 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) · 13 unmodified lines
174181 p->chunks[p->chunk_ib_idx].length_dw);
175182 return -EINVAL;
176183 }
184+
185+ p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0;
177186 return 0;
178187 }
179188
drivers/gpu/drm/radeon/radeon_drv.c+2−1
@@ -53,9 +53,10 @@ · 52 unmodified lines
5353 * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
5454 * 2.10.0 - fusion 2D tiling
5555 * 2.11.0 - backend map, initial compute support for the CS checker
56+ * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
5657 */
5758 #define KMS_DRIVER_MAJOR 2
58−#define KMS_DRIVER_MINOR 11
59+#define KMS_DRIVER_MINOR 12
5960 #define KMS_DRIVER_PATCHLEVEL 0
6061 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
6162 int radeon_driver_unload_kms(struct drm_device *dev);
include/drm/radeon_drm.h+4−0
@@ -874,6 +874,10 @@ struct drm_radeon_gem_pwrite { · 873 unmodified lines
874874
875875 #define RADEON_CHUNK_ID_RELOCS 0x01
876876 #define RADEON_CHUNK_ID_IB 0x02
877+#define RADEON_CHUNK_ID_FLAGS 0x03
878+
879+/* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */
880+#define RADEON_CS_KEEP_TILING_FLAGS 0x01
877881
878882 struct drm_radeon_cs_chunk {
879883 uint32_t chunk_id;