diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 33 |
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); |