aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index c3ea212e0c3c..d8864949e387 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -133,6 +133,7 @@ static inline int r600_bpe_from_format(u32 *bpe, u32 format)
133 case V_038004_FMT_GB_GR: 133 case V_038004_FMT_GB_GR:
134 case V_038004_FMT_BG_RG: 134 case V_038004_FMT_BG_RG:
135 case V_038004_COLOR_INVALID: 135 case V_038004_COLOR_INVALID:
136 default:
136 *bpe = 16; 137 *bpe = 16;
137 return -EINVAL; 138 return -EINVAL;
138 } 139 }
@@ -174,7 +175,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
174 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); 175 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
175 return -EINVAL; 176 return -EINVAL;
176 } 177 }
177 size = radeon_bo_size(track->cb_color_bo[i]); 178 size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
178 if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) { 179 if (r600_bpe_from_format(&bpe, G_0280A0_FORMAT(track->cb_color_info[i]))) {
179 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", 180 dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
180 __func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]), 181 __func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]),
@@ -327,7 +328,6 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
327 dev_warn(p->dev, "z/stencil buffer size not set\n"); 328 dev_warn(p->dev, "z/stencil buffer size not set\n");
328 return -EINVAL; 329 return -EINVAL;
329 } 330 }
330 printk_once(KERN_WARNING "You have old & broken userspace please consider updating mesa\n");
331 tmp = radeon_bo_size(track->db_bo) - track->db_offset; 331 tmp = radeon_bo_size(track->db_bo) - track->db_offset;
332 tmp = (tmp / bpe) >> 6; 332 tmp = (tmp / bpe) >> 6;
333 if (!tmp) { 333 if (!tmp) {
@@ -882,8 +882,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
882 return -EINVAL; 882 return -EINVAL;
883 } 883 }
884 ib[idx] = track->cb_color_base_last[tmp]; 884 ib[idx] = track->cb_color_base_last[tmp];
885 printk_once(KERN_WARNING "You have old & broken userspace "
886 "please consider updating mesa & xf86-video-ati\n");
887 track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; 885 track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp];
888 } else { 886 } else {
889 r = r600_cs_packet_next_reloc(p, &reloc); 887 r = r600_cs_packet_next_reloc(p, &reloc);
@@ -910,8 +908,6 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
910 return -EINVAL; 908 return -EINVAL;
911 } 909 }
912 ib[idx] = track->cb_color_base_last[tmp]; 910 ib[idx] = track->cb_color_base_last[tmp];
913 printk_once(KERN_WARNING "You have old & broken userspace "
914 "please consider updating mesa & xf86-video-ati\n");
915 track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; 911 track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp];
916 } else { 912 } else {
917 r = r600_cs_packet_next_reloc(p, &reloc); 913 r = r600_cs_packet_next_reloc(p, &reloc);
@@ -938,7 +934,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
938 return -EINVAL; 934 return -EINVAL;
939 } 935 }
940 tmp = (reg - CB_COLOR0_BASE) / 4; 936 tmp = (reg - CB_COLOR0_BASE) / 4;
941 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); 937 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
942 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 938 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
943 track->cb_color_base_last[tmp] = ib[idx]; 939 track->cb_color_base_last[tmp] = ib[idx];
944 track->cb_color_bo[tmp] = reloc->robj; 940 track->cb_color_bo[tmp] = reloc->robj;
@@ -950,7 +946,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
950 "0x%04X\n", reg); 946 "0x%04X\n", reg);
951 return -EINVAL; 947 return -EINVAL;
952 } 948 }
953 track->db_offset = radeon_get_ib_value(p, idx); 949 track->db_offset = radeon_get_ib_value(p, idx) << 8;
954 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 950 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
955 track->db_bo = reloc->robj; 951 track->db_bo = reloc->robj;
956 break; 952 break;
@@ -1055,10 +1051,10 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
1055 } 1051 }
1056 *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; 1052 *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0;
1057 *mipmap_size = offset; 1053 *mipmap_size = offset;
1058 if (!blevel)
1059 *mipmap_size -= *l0_size;
1060 if (!nlevels) 1054 if (!nlevels)
1061 *mipmap_size = *l0_size; 1055 *mipmap_size = *l0_size;
1056 if (!blevel)
1057 *mipmap_size -= *l0_size;
1062} 1058}
1063 1059
1064/** 1060/**
@@ -1165,14 +1161,14 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
1165 (pitch_align * bpe), 1161 (pitch_align * bpe),
1166 &l0_size, &mipmap_size); 1162 &l0_size, &mipmap_size);
1167 /* using get ib will give us the offset into the texture bo */ 1163 /* using get ib will give us the offset into the texture bo */
1168 word0 = radeon_get_ib_value(p, idx + 2); 1164 word0 = radeon_get_ib_value(p, idx + 2) << 8;
1169 if ((l0_size + word0) > radeon_bo_size(texture)) { 1165 if ((l0_size + word0) > radeon_bo_size(texture)) {
1170 dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n", 1166 dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n",
1171 w0, h0, bpe, word0, l0_size, radeon_bo_size(texture)); 1167 w0, h0, bpe, word0, l0_size, radeon_bo_size(texture));
1172 return -EINVAL; 1168 return -EINVAL;
1173 } 1169 }
1174 /* using get ib will give us the offset into the mipmap bo */ 1170 /* using get ib will give us the offset into the mipmap bo */
1175 word0 = radeon_get_ib_value(p, idx + 3); 1171 word0 = radeon_get_ib_value(p, idx + 3) << 8;
1176 if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { 1172 if ((mipmap_size + word0) > radeon_bo_size(mipmap)) {
1177 dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", 1173 dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
1178 w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); 1174 w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));
@@ -1366,7 +1362,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1366 } 1362 }
1367 for (i = 0; i < (pkt->count / 7); i++) { 1363 for (i = 0; i < (pkt->count / 7); i++) {
1368 struct radeon_bo *texture, *mipmap; 1364 struct radeon_bo *texture, *mipmap;
1369 u32 size, offset; 1365 u32 size, offset, base_offset, mip_offset;
1370 1366
1371 switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { 1367 switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
1372 case SQ_TEX_VTX_VALID_TEXTURE: 1368 case SQ_TEX_VTX_VALID_TEXTURE:
@@ -1376,7 +1372,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1376 DRM_ERROR("bad SET_RESOURCE\n"); 1372 DRM_ERROR("bad SET_RESOURCE\n");
1377 return -EINVAL; 1373 return -EINVAL;
1378 } 1374 }
1379 ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1375 base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1380 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 1376 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1381 ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); 1377 ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1);
1382 else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) 1378 else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
@@ -1388,12 +1384,14 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1388 DRM_ERROR("bad SET_RESOURCE\n"); 1384 DRM_ERROR("bad SET_RESOURCE\n");
1389 return -EINVAL; 1385 return -EINVAL;
1390 } 1386 }
1391 ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1387 mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1392 mipmap = reloc->robj; 1388 mipmap = reloc->robj;
1393 r = r600_check_texture_resource(p, idx+(i*7)+1, 1389 r = r600_check_texture_resource(p, idx+(i*7)+1,
1394 texture, mipmap, reloc->lobj.tiling_flags); 1390 texture, mipmap, reloc->lobj.tiling_flags);
1395 if (r) 1391 if (r)
1396 return r; 1392 return r;
1393 ib[idx+1+(i*7)+2] += base_offset;
1394 ib[idx+1+(i*7)+3] += mip_offset;
1397 break; 1395 break;
1398 case SQ_TEX_VTX_VALID_BUFFER: 1396 case SQ_TEX_VTX_VALID_BUFFER:
1399 /* vtx base */ 1397 /* vtx base */
@@ -1403,10 +1401,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1403 return -EINVAL; 1401 return -EINVAL;
1404 } 1402 }
1405 offset = radeon_get_ib_value(p, idx+1+(i*7)+0); 1403 offset = radeon_get_ib_value(p, idx+1+(i*7)+0);
1406 size = radeon_get_ib_value(p, idx+1+(i*7)+1); 1404 size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1;
1407 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { 1405 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
1408 /* force size to size of the buffer */ 1406 /* force size to size of the buffer */
1409 dev_warn(p->dev, "vbo resource seems too big for the bo\n"); 1407 dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n",
1408 size + offset, radeon_bo_size(reloc->robj));
1410 ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj); 1409 ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj);
1411 } 1410 }
1412 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); 1411 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);