diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-27 10:13:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-27 10:13:33 -0400 |
commit | e372dc6c62bf0246a07f3291a26c562cc8659fbd (patch) | |
tree | c7039c1d1005b80e427761ba768d7697ae4a0b72 /drivers/gpu/drm/radeon/r600_cs.c | |
parent | 5d4121c04b3577e37e389b3553d442f44bb346d7 (diff) | |
parent | fea7a08acb13524b47711625eebea40a0ede69a0 (diff) |
Merge 3.6-rc3 into tty-next
This picks up all of the different fixes in Linus's tree that we also need here.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 170 |
1 files changed, 124 insertions, 46 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..ab74e6b149e7 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -47,13 +47,17 @@ struct r600_cs_track { | |||
47 | u32 npipes; | 47 | u32 npipes; |
48 | /* value we track */ | 48 | /* value we track */ |
49 | u32 sq_config; | 49 | u32 sq_config; |
50 | u32 log_nsamples; | ||
50 | u32 nsamples; | 51 | u32 nsamples; |
51 | u32 cb_color_base_last[8]; | 52 | u32 cb_color_base_last[8]; |
52 | struct radeon_bo *cb_color_bo[8]; | 53 | struct radeon_bo *cb_color_bo[8]; |
53 | u64 cb_color_bo_mc[8]; | 54 | u64 cb_color_bo_mc[8]; |
54 | u32 cb_color_bo_offset[8]; | 55 | u64 cb_color_bo_offset[8]; |
55 | struct radeon_bo *cb_color_frag_bo[8]; /* unused */ | 56 | struct radeon_bo *cb_color_frag_bo[8]; |
56 | struct radeon_bo *cb_color_tile_bo[8]; /* unused */ | 57 | u64 cb_color_frag_offset[8]; |
58 | struct radeon_bo *cb_color_tile_bo[8]; | ||
59 | u64 cb_color_tile_offset[8]; | ||
60 | u32 cb_color_mask[8]; | ||
57 | u32 cb_color_info[8]; | 61 | u32 cb_color_info[8]; |
58 | u32 cb_color_view[8]; | 62 | u32 cb_color_view[8]; |
59 | u32 cb_color_size_idx[8]; /* unused */ | 63 | u32 cb_color_size_idx[8]; /* unused */ |
@@ -349,10 +353,6 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
349 | unsigned array_mode; | 353 | unsigned array_mode; |
350 | u32 format; | 354 | u32 format; |
351 | 355 | ||
352 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
353 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
358 | if (!r600_fmt_is_valid_color(format)) { | 358 | if (!r600_fmt_is_valid_color(format)) { |
@@ -420,7 +420,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
420 | } | 420 | } |
421 | 421 | ||
422 | /* check offset */ | 422 | /* check offset */ |
423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); | 423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
424 | r600_fmt_get_blocksize(format) * track->nsamples; | ||
424 | switch (array_mode) { | 425 | switch (array_mode) { |
425 | default: | 426 | default: |
426 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 427 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
@@ -441,7 +442,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
441 | * broken userspace. | 442 | * broken userspace. |
442 | */ | 443 | */ |
443 | } else { | 444 | } else { |
444 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", | 445 | dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n", |
445 | __func__, i, array_mode, | 446 | __func__, i, array_mode, |
446 | track->cb_color_bo_offset[i], tmp, | 447 | track->cb_color_bo_offset[i], tmp, |
447 | radeon_bo_size(track->cb_color_bo[i]), | 448 | radeon_bo_size(track->cb_color_bo[i]), |
@@ -458,6 +459,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
458 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | | 459 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | |
459 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); | 460 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); |
460 | ib[track->cb_color_size_idx[i]] = tmp; | 461 | ib[track->cb_color_size_idx[i]] = tmp; |
462 | |||
463 | /* FMASK/CMASK */ | ||
464 | switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
465 | case V_0280A0_TILE_DISABLE: | ||
466 | break; | ||
467 | case V_0280A0_FRAG_ENABLE: | ||
468 | if (track->nsamples > 1) { | ||
469 | uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); | ||
470 | /* the tile size is 8x8, but the size is in units of bits. | ||
471 | * for bytes, do just * 8. */ | ||
472 | uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); | ||
473 | |||
474 | if (bytes + track->cb_color_frag_offset[i] > | ||
475 | radeon_bo_size(track->cb_color_frag_bo[i])) { | ||
476 | dev_warn(p->dev, "%s FMASK_TILE_MAX too large " | ||
477 | "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
478 | __func__, tile_max, bytes, | ||
479 | track->cb_color_frag_offset[i], | ||
480 | radeon_bo_size(track->cb_color_frag_bo[i])); | ||
481 | return -EINVAL; | ||
482 | } | ||
483 | } | ||
484 | /* fall through */ | ||
485 | case V_0280A0_CLEAR_ENABLE: | ||
486 | { | ||
487 | uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); | ||
488 | /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. | ||
489 | * (128*128) / (8*8) / 2 = 128 bytes per block. */ | ||
490 | uint32_t bytes = (block_max + 1) * 128; | ||
491 | |||
492 | if (bytes + track->cb_color_tile_offset[i] > | ||
493 | radeon_bo_size(track->cb_color_tile_bo[i])) { | ||
494 | dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " | ||
495 | "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
496 | __func__, block_max, bytes, | ||
497 | track->cb_color_tile_offset[i], | ||
498 | radeon_bo_size(track->cb_color_tile_bo[i])); | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | break; | ||
502 | } | ||
503 | default: | ||
504 | dev_warn(p->dev, "%s invalid tile mode\n", __func__); | ||
505 | return -EINVAL; | ||
506 | } | ||
461 | return 0; | 507 | return 0; |
462 | } | 508 | } |
463 | 509 | ||
@@ -566,7 +612,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) | |||
566 | 612 | ||
567 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | 613 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; |
568 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 614 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
569 | tmp = ntiles * bpe * 64 * nviews; | 615 | tmp = ntiles * bpe * 64 * nviews * track->nsamples; |
570 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | 616 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { |
571 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", | 617 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", |
572 | array_mode, | 618 | array_mode, |
@@ -764,8 +810,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
764 | } | 810 | } |
765 | 811 | ||
766 | /* Check depth buffer */ | 812 | /* Check depth buffer */ |
767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 813 | if (track->db_dirty && |
768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 814 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
815 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
816 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
769 | r = r600_cs_track_validate_db(p); | 817 | r = r600_cs_track_validate_db(p); |
770 | if (r) | 818 | if (r) |
771 | return r; | 819 | return r; |
@@ -1229,6 +1277,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1229 | break; | 1277 | break; |
1230 | case R_028C04_PA_SC_AA_CONFIG: | 1278 | case R_028C04_PA_SC_AA_CONFIG: |
1231 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); | 1279 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); |
1280 | track->log_nsamples = tmp; | ||
1232 | track->nsamples = 1 << tmp; | 1281 | track->nsamples = 1 << tmp; |
1233 | track->cb_dirty = true; | 1282 | track->cb_dirty = true; |
1234 | break; | 1283 | break; |
@@ -1310,16 +1359,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1310 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1359 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1311 | return -EINVAL; | 1360 | return -EINVAL; |
1312 | } | 1361 | } |
1313 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1314 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; | 1362 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; |
1363 | track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1364 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1315 | } else { | 1365 | } else { |
1316 | r = r600_cs_packet_next_reloc(p, &reloc); | 1366 | r = r600_cs_packet_next_reloc(p, &reloc); |
1317 | if (r) { | 1367 | if (r) { |
1318 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1368 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1319 | return -EINVAL; | 1369 | return -EINVAL; |
1320 | } | 1370 | } |
1321 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1322 | track->cb_color_frag_bo[tmp] = reloc->robj; | 1371 | track->cb_color_frag_bo[tmp] = reloc->robj; |
1372 | track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; | ||
1373 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1374 | } | ||
1375 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1376 | track->cb_dirty = true; | ||
1323 | } | 1377 | } |
1324 | break; | 1378 | break; |
1325 | case R_0280C0_CB_COLOR0_TILE: | 1379 | case R_0280C0_CB_COLOR0_TILE: |
@@ -1336,16 +1390,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1336 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1390 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1337 | return -EINVAL; | 1391 | return -EINVAL; |
1338 | } | 1392 | } |
1339 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1340 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; | 1393 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; |
1394 | track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1395 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1341 | } else { | 1396 | } else { |
1342 | r = r600_cs_packet_next_reloc(p, &reloc); | 1397 | r = r600_cs_packet_next_reloc(p, &reloc); |
1343 | if (r) { | 1398 | if (r) { |
1344 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1399 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1345 | return -EINVAL; | 1400 | return -EINVAL; |
1346 | } | 1401 | } |
1347 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1348 | track->cb_color_tile_bo[tmp] = reloc->robj; | 1402 | track->cb_color_tile_bo[tmp] = reloc->robj; |
1403 | track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; | ||
1404 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1405 | } | ||
1406 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1407 | track->cb_dirty = true; | ||
1408 | } | ||
1409 | break; | ||
1410 | case R_028100_CB_COLOR0_MASK: | ||
1411 | case R_028104_CB_COLOR1_MASK: | ||
1412 | case R_028108_CB_COLOR2_MASK: | ||
1413 | case R_02810C_CB_COLOR3_MASK: | ||
1414 | case R_028110_CB_COLOR4_MASK: | ||
1415 | case R_028114_CB_COLOR5_MASK: | ||
1416 | case R_028118_CB_COLOR6_MASK: | ||
1417 | case R_02811C_CB_COLOR7_MASK: | ||
1418 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | ||
1419 | track->cb_color_mask[tmp] = ib[idx]; | ||
1420 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1421 | track->cb_dirty = true; | ||
1349 | } | 1422 | } |
1350 | break; | 1423 | break; |
1351 | case CB_COLOR0_BASE: | 1424 | case CB_COLOR0_BASE: |
@@ -1490,7 +1563,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level) | |||
1490 | } | 1563 | } |
1491 | 1564 | ||
1492 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | 1565 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, |
1493 | unsigned w0, unsigned h0, unsigned d0, unsigned format, | 1566 | unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, |
1494 | unsigned block_align, unsigned height_align, unsigned base_align, | 1567 | unsigned block_align, unsigned height_align, unsigned base_align, |
1495 | unsigned *l0_size, unsigned *mipmap_size) | 1568 | unsigned *l0_size, unsigned *mipmap_size) |
1496 | { | 1569 | { |
@@ -1518,7 +1591,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | |||
1518 | 1591 | ||
1519 | depth = r600_mip_minify(d0, i); | 1592 | depth = r600_mip_minify(d0, i); |
1520 | 1593 | ||
1521 | size = nbx * nby * blocksize; | 1594 | size = nbx * nby * blocksize * nsamples; |
1522 | if (nfaces) | 1595 | if (nfaces) |
1523 | size *= nfaces; | 1596 | size *= nfaces; |
1524 | else | 1597 | else |
@@ -1557,13 +1630,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1557 | u32 tiling_flags) | 1630 | u32 tiling_flags) |
1558 | { | 1631 | { |
1559 | struct r600_cs_track *track = p->track; | 1632 | struct r600_cs_track *track = p->track; |
1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1633 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1634 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
1562 | u32 height_align, pitch, pitch_align, depth_align; | 1635 | u32 height_align, pitch, pitch_align, depth_align; |
1563 | u32 array, barray, larray; | 1636 | u32 barray, larray; |
1564 | u64 base_align; | 1637 | u64 base_align; |
1565 | struct array_mode_checker array_check; | 1638 | struct array_mode_checker array_check; |
1566 | u32 format; | 1639 | u32 format; |
1640 | bool is_array; | ||
1567 | 1641 | ||
1568 | /* on legacy kernel we don't perform advanced check */ | 1642 | /* on legacy kernel we don't perform advanced check */ |
1569 | if (p->rdev == NULL) | 1643 | if (p->rdev == NULL) |
@@ -1581,12 +1655,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1655 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
1582 | } | 1656 | } |
1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1657 | word1 = radeon_get_ib_value(p, idx + 1); |
1658 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1659 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1660 | word4 = radeon_get_ib_value(p, idx + 4); | ||
1661 | word5 = radeon_get_ib_value(p, idx + 5); | ||
1662 | dim = G_038000_DIM(word0); | ||
1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1663 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1664 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1665 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1586 | d0 = G_038004_TEX_DEPTH(word1); | 1666 | d0 = G_038004_TEX_DEPTH(word1); |
1667 | format = G_038004_DATA_FORMAT(word1); | ||
1668 | blevel = G_038010_BASE_LEVEL(word4); | ||
1669 | llevel = G_038014_LAST_LEVEL(word5); | ||
1670 | /* pitch in texels */ | ||
1671 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1672 | array_check.group_size = track->group_size; | ||
1673 | array_check.nbanks = track->nbanks; | ||
1674 | array_check.npipes = track->npipes; | ||
1675 | array_check.nsamples = 1; | ||
1676 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1587 | nfaces = 1; | 1677 | nfaces = 1; |
1588 | array = 0; | 1678 | is_array = false; |
1589 | switch (G_038000_DIM(word0)) { | 1679 | switch (dim) { |
1590 | case V_038000_SQ_TEX_DIM_1D: | 1680 | case V_038000_SQ_TEX_DIM_1D: |
1591 | case V_038000_SQ_TEX_DIM_2D: | 1681 | case V_038000_SQ_TEX_DIM_2D: |
1592 | case V_038000_SQ_TEX_DIM_3D: | 1682 | case V_038000_SQ_TEX_DIM_3D: |
@@ -1599,29 +1689,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1599 | break; | 1689 | break; |
1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1690 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1691 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
1602 | array = 1; | 1692 | is_array = true; |
1603 | break; | 1693 | break; |
1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1694 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
1695 | is_array = true; | ||
1696 | /* fall through */ | ||
1697 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1698 | array_check.nsamples = 1 << llevel; | ||
1699 | llevel = 0; | ||
1700 | break; | ||
1606 | default: | 1701 | default: |
1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1702 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
1608 | return -EINVAL; | 1703 | return -EINVAL; |
1609 | } | 1704 | } |
1610 | format = G_038004_DATA_FORMAT(word1); | ||
1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1705 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1706 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
1613 | __func__, __LINE__, format); | 1707 | __func__, __LINE__, format); |
1614 | return -EINVAL; | 1708 | return -EINVAL; |
1615 | } | 1709 | } |
1616 | 1710 | ||
1617 | /* pitch in texels */ | ||
1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1620 | array_check.group_size = track->group_size; | ||
1621 | array_check.nbanks = track->nbanks; | ||
1622 | array_check.npipes = track->npipes; | ||
1623 | array_check.nsamples = 1; | ||
1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1625 | if (r600_get_array_mode_alignment(&array_check, | 1711 | if (r600_get_array_mode_alignment(&array_check, |
1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1712 | &pitch_align, &height_align, &depth_align, &base_align)) { |
1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1713 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
@@ -1647,24 +1733,17 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1647 | return -EINVAL; | 1733 | return -EINVAL; |
1648 | } | 1734 | } |
1649 | 1735 | ||
1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1652 | |||
1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
1657 | if (blevel > llevel) { | 1736 | if (blevel > llevel) { |
1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1737 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
1659 | blevel, llevel); | 1738 | blevel, llevel); |
1660 | } | 1739 | } |
1661 | if (array == 1) { | 1740 | if (is_array) { |
1662 | barray = G_038014_BASE_ARRAY(word1); | 1741 | barray = G_038014_BASE_ARRAY(word5); |
1663 | larray = G_038014_LAST_ARRAY(word1); | 1742 | larray = G_038014_LAST_ARRAY(word5); |
1664 | 1743 | ||
1665 | nfaces = larray - barray + 1; | 1744 | nfaces = larray - barray + 1; |
1666 | } | 1745 | } |
1667 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, | 1746 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, |
1668 | pitch_align, height_align, base_align, | 1747 | pitch_align, height_align, base_align, |
1669 | &l0_size, &mipmap_size); | 1748 | &l0_size, &mipmap_size); |
1670 | /* using get ib will give us the offset into the texture bo */ | 1749 | /* using get ib will give us the offset into the texture bo */ |
@@ -1677,7 +1756,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1677 | return -EINVAL; | 1756 | return -EINVAL; |
1678 | } | 1757 | } |
1679 | /* using get ib will give us the offset into the mipmap bo */ | 1758 | /* using get ib will give us the offset into the mipmap bo */ |
1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1759 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1760 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1761 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |