diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-08-06 02:54:05 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-08-09 20:46:47 -0400 |
commit | 1729dd33d20bddf1b3f371f3090f0cfd6be50b7a (patch) | |
tree | e5f6ac18c7b0771a23ff377ec21584406e7db332 /drivers/gpu/drm/radeon/r600_cs.c | |
parent | 43861f713c17223cd0fa87dcb57308b7cde7c10a (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.c | 27 |
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); |