aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_cs.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-08-06 02:54:05 -0400
committerDave Airlie <airlied@redhat.com>2010-08-09 20:46:47 -0400
commit1729dd33d20bddf1b3f371f3090f0cfd6be50b7a (patch)
treee5f6ac18c7b0771a23ff377ec21584406e7db332 /drivers/gpu/drm/radeon/r600_cs.c
parent43861f713c17223cd0fa87dcb57308b7cde7c10a (diff)
drm/radeon/kms: r600 CS parser fixes
- buffer offsets in the base regs are 256b aligned so shift properly when comparing, fixed by Andre Maasikas - mipmap size was calculated wrong when nlevel=0 - texture bo offsets were used after the bo base address was added - vertex resource size register is size - 1, not size Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Cc: Andre Maasikas <amaasikas@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index c3ea212e0c3c..52b52529ff31 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -174,7 +174,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"); 174 dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
175 return -EINVAL; 175 return -EINVAL;
176 } 176 }
177 size = radeon_bo_size(track->cb_color_bo[i]); 177 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]))) { 178 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", 179 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]), 180 __func__, __LINE__, G_0280A0_FORMAT(track->cb_color_info[i]),
@@ -938,7 +938,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
938 return -EINVAL; 938 return -EINVAL;
939 } 939 }
940 tmp = (reg - CB_COLOR0_BASE) / 4; 940 tmp = (reg - CB_COLOR0_BASE) / 4;
941 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx); 941 track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
942 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 942 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
943 track->cb_color_base_last[tmp] = ib[idx]; 943 track->cb_color_base_last[tmp] = ib[idx];
944 track->cb_color_bo[tmp] = reloc->robj; 944 track->cb_color_bo[tmp] = reloc->robj;
@@ -950,7 +950,7 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
950 "0x%04X\n", reg); 950 "0x%04X\n", reg);
951 return -EINVAL; 951 return -EINVAL;
952 } 952 }
953 track->db_offset = radeon_get_ib_value(p, idx); 953 track->db_offset = radeon_get_ib_value(p, idx) << 8;
954 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 954 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
955 track->db_bo = reloc->robj; 955 track->db_bo = reloc->robj;
956 break; 956 break;
@@ -1055,10 +1055,10 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned nlevels
1055 } 1055 }
1056 *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0; 1056 *l0_size = ALIGN((w0 * bpe), pitch_align) * h0 * d0;
1057 *mipmap_size = offset; 1057 *mipmap_size = offset;
1058 if (!blevel)
1059 *mipmap_size -= *l0_size;
1060 if (!nlevels) 1058 if (!nlevels)
1061 *mipmap_size = *l0_size; 1059 *mipmap_size = *l0_size;
1060 if (!blevel)
1061 *mipmap_size -= *l0_size;
1062} 1062}
1063 1063
1064/** 1064/**
@@ -1165,14 +1165,14 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
1165 (pitch_align * bpe), 1165 (pitch_align * bpe),
1166 &l0_size, &mipmap_size); 1166 &l0_size, &mipmap_size);
1167 /* using get ib will give us the offset into the texture bo */ 1167 /* using get ib will give us the offset into the texture bo */
1168 word0 = radeon_get_ib_value(p, idx + 2); 1168 word0 = radeon_get_ib_value(p, idx + 2) << 8;
1169 if ((l0_size + word0) > radeon_bo_size(texture)) { 1169 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", 1170 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)); 1171 w0, h0, bpe, word0, l0_size, radeon_bo_size(texture));
1172 return -EINVAL; 1172 return -EINVAL;
1173 } 1173 }
1174 /* using get ib will give us the offset into the mipmap bo */ 1174 /* using get ib will give us the offset into the mipmap bo */
1175 word0 = radeon_get_ib_value(p, idx + 3); 1175 word0 = radeon_get_ib_value(p, idx + 3) << 8;
1176 if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { 1176 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", 1177 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)); 1178 w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));
@@ -1366,7 +1366,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1366 } 1366 }
1367 for (i = 0; i < (pkt->count / 7); i++) { 1367 for (i = 0; i < (pkt->count / 7); i++) {
1368 struct radeon_bo *texture, *mipmap; 1368 struct radeon_bo *texture, *mipmap;
1369 u32 size, offset; 1369 u32 size, offset, base_offset, mip_offset;
1370 1370
1371 switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { 1371 switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
1372 case SQ_TEX_VTX_VALID_TEXTURE: 1372 case SQ_TEX_VTX_VALID_TEXTURE:
@@ -1376,7 +1376,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1376 DRM_ERROR("bad SET_RESOURCE\n"); 1376 DRM_ERROR("bad SET_RESOURCE\n");
1377 return -EINVAL; 1377 return -EINVAL;
1378 } 1378 }
1379 ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1379 base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1380 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) 1380 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); 1381 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) 1382 else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
@@ -1388,12 +1388,14 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1388 DRM_ERROR("bad SET_RESOURCE\n"); 1388 DRM_ERROR("bad SET_RESOURCE\n");
1389 return -EINVAL; 1389 return -EINVAL;
1390 } 1390 }
1391 ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1391 mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1392 mipmap = reloc->robj; 1392 mipmap = reloc->robj;
1393 r = r600_check_texture_resource(p, idx+(i*7)+1, 1393 r = r600_check_texture_resource(p, idx+(i*7)+1,
1394 texture, mipmap, reloc->lobj.tiling_flags); 1394 texture, mipmap, reloc->lobj.tiling_flags);
1395 if (r) 1395 if (r)
1396 return r; 1396 return r;
1397 ib[idx+1+(i*7)+2] += base_offset;
1398 ib[idx+1+(i*7)+3] += mip_offset;
1397 break; 1399 break;
1398 case SQ_TEX_VTX_VALID_BUFFER: 1400 case SQ_TEX_VTX_VALID_BUFFER:
1399 /* vtx base */ 1401 /* vtx base */
@@ -1403,10 +1405,11 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
1403 return -EINVAL; 1405 return -EINVAL;
1404 } 1406 }
1405 offset = radeon_get_ib_value(p, idx+1+(i*7)+0); 1407 offset = radeon_get_ib_value(p, idx+1+(i*7)+0);
1406 size = radeon_get_ib_value(p, idx+1+(i*7)+1); 1408 size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1;
1407 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { 1409 if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
1408 /* force size to size of the buffer */ 1410 /* force size to size of the buffer */
1409 dev_warn(p->dev, "vbo resource seems too big for the bo\n"); 1411 dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n",
1412 size + offset, radeon_bo_size(reloc->robj));
1410 ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj); 1413 ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj);
1411 } 1414 }
1412 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); 1415 ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);