diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_cs.c | 196 |
1 files changed, 148 insertions, 48 deletions
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf2..f37676d7f21 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -47,18 +47,23 @@ 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 */ |
60 | u32 cb_target_mask; | 64 | u32 cb_target_mask; |
61 | u32 cb_shader_mask; /* unused */ | 65 | u32 cb_shader_mask; /* unused */ |
66 | bool is_resolve; | ||
62 | u32 cb_color_size[8]; | 67 | u32 cb_color_size[8]; |
63 | u32 vgt_strmout_en; | 68 | u32 vgt_strmout_en; |
64 | u32 vgt_strmout_buffer_en; | 69 | u32 vgt_strmout_buffer_en; |
@@ -311,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
311 | track->cb_color_bo[i] = NULL; | 316 | track->cb_color_bo[i] = NULL; |
312 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 317 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
313 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 318 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
314 | } | 319 | track->cb_color_frag_bo[i] = NULL; |
320 | track->cb_color_frag_offset[i] = 0xFFFFFFFF; | ||
321 | track->cb_color_tile_bo[i] = NULL; | ||
322 | track->cb_color_tile_offset[i] = 0xFFFFFFFF; | ||
323 | track->cb_color_mask[i] = 0xFFFFFFFF; | ||
324 | } | ||
325 | track->is_resolve = false; | ||
326 | track->nsamples = 16; | ||
327 | track->log_nsamples = 4; | ||
315 | track->cb_target_mask = 0xFFFFFFFF; | 328 | track->cb_target_mask = 0xFFFFFFFF; |
316 | track->cb_shader_mask = 0xFFFFFFFF; | 329 | track->cb_shader_mask = 0xFFFFFFFF; |
317 | track->cb_dirty = true; | 330 | track->cb_dirty = true; |
@@ -348,11 +361,9 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
348 | volatile u32 *ib = p->ib.ptr; | 361 | volatile u32 *ib = p->ib.ptr; |
349 | unsigned array_mode; | 362 | unsigned array_mode; |
350 | u32 format; | 363 | u32 format; |
364 | /* When resolve is used, the second colorbuffer has always 1 sample. */ | ||
365 | unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; | ||
351 | 366 | ||
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]; | 367 | 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]); | 368 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
358 | if (!r600_fmt_is_valid_color(format)) { | 369 | if (!r600_fmt_is_valid_color(format)) { |
@@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
375 | array_check.group_size = track->group_size; | 386 | array_check.group_size = track->group_size; |
376 | array_check.nbanks = track->nbanks; | 387 | array_check.nbanks = track->nbanks; |
377 | array_check.npipes = track->npipes; | 388 | array_check.npipes = track->npipes; |
378 | array_check.nsamples = track->nsamples; | 389 | array_check.nsamples = nsamples; |
379 | array_check.blocksize = r600_fmt_get_blocksize(format); | 390 | array_check.blocksize = r600_fmt_get_blocksize(format); |
380 | if (r600_get_array_mode_alignment(&array_check, | 391 | if (r600_get_array_mode_alignment(&array_check, |
381 | &pitch_align, &height_align, &depth_align, &base_align)) { | 392 | &pitch_align, &height_align, &depth_align, &base_align)) { |
@@ -420,7 +431,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
420 | } | 431 | } |
421 | 432 | ||
422 | /* check offset */ | 433 | /* check offset */ |
423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); | 434 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
435 | r600_fmt_get_blocksize(format) * nsamples; | ||
424 | switch (array_mode) { | 436 | switch (array_mode) { |
425 | default: | 437 | default: |
426 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 438 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
@@ -441,7 +453,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
441 | * broken userspace. | 453 | * broken userspace. |
442 | */ | 454 | */ |
443 | } else { | 455 | } else { |
444 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", | 456 | dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n", |
445 | __func__, i, array_mode, | 457 | __func__, i, array_mode, |
446 | track->cb_color_bo_offset[i], tmp, | 458 | track->cb_color_bo_offset[i], tmp, |
447 | radeon_bo_size(track->cb_color_bo[i]), | 459 | radeon_bo_size(track->cb_color_bo[i]), |
@@ -458,6 +470,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) | | 470 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | |
459 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); | 471 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); |
460 | ib[track->cb_color_size_idx[i]] = tmp; | 472 | ib[track->cb_color_size_idx[i]] = tmp; |
473 | |||
474 | /* FMASK/CMASK */ | ||
475 | switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
476 | case V_0280A0_TILE_DISABLE: | ||
477 | break; | ||
478 | case V_0280A0_FRAG_ENABLE: | ||
479 | if (track->nsamples > 1) { | ||
480 | uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); | ||
481 | /* the tile size is 8x8, but the size is in units of bits. | ||
482 | * for bytes, do just * 8. */ | ||
483 | uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); | ||
484 | |||
485 | if (bytes + track->cb_color_frag_offset[i] > | ||
486 | radeon_bo_size(track->cb_color_frag_bo[i])) { | ||
487 | dev_warn(p->dev, "%s FMASK_TILE_MAX too large " | ||
488 | "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
489 | __func__, tile_max, bytes, | ||
490 | track->cb_color_frag_offset[i], | ||
491 | radeon_bo_size(track->cb_color_frag_bo[i])); | ||
492 | return -EINVAL; | ||
493 | } | ||
494 | } | ||
495 | /* fall through */ | ||
496 | case V_0280A0_CLEAR_ENABLE: | ||
497 | { | ||
498 | uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); | ||
499 | /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. | ||
500 | * (128*128) / (8*8) / 2 = 128 bytes per block. */ | ||
501 | uint32_t bytes = (block_max + 1) * 128; | ||
502 | |||
503 | if (bytes + track->cb_color_tile_offset[i] > | ||
504 | radeon_bo_size(track->cb_color_tile_bo[i])) { | ||
505 | dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " | ||
506 | "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
507 | __func__, block_max, bytes, | ||
508 | track->cb_color_tile_offset[i], | ||
509 | radeon_bo_size(track->cb_color_tile_bo[i])); | ||
510 | return -EINVAL; | ||
511 | } | ||
512 | break; | ||
513 | } | ||
514 | default: | ||
515 | dev_warn(p->dev, "%s invalid tile mode\n", __func__); | ||
516 | return -EINVAL; | ||
517 | } | ||
461 | return 0; | 518 | return 0; |
462 | } | 519 | } |
463 | 520 | ||
@@ -566,7 +623,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) | |||
566 | 623 | ||
567 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | 624 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; |
568 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 625 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
569 | tmp = ntiles * bpe * 64 * nviews; | 626 | tmp = ntiles * bpe * 64 * nviews * track->nsamples; |
570 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | 627 | 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", | 628 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", |
572 | array_mode, | 629 | array_mode, |
@@ -746,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
746 | */ | 803 | */ |
747 | if (track->cb_dirty) { | 804 | if (track->cb_dirty) { |
748 | tmp = track->cb_target_mask; | 805 | tmp = track->cb_target_mask; |
806 | |||
807 | /* We must check both colorbuffers for RESOLVE. */ | ||
808 | if (track->is_resolve) { | ||
809 | tmp |= 0xff; | ||
810 | } | ||
811 | |||
749 | for (i = 0; i < 8; i++) { | 812 | for (i = 0; i < 8; i++) { |
750 | if ((tmp >> (i * 4)) & 0xF) { | 813 | if ((tmp >> (i * 4)) & 0xF) { |
751 | /* at least one component is enabled */ | 814 | /* at least one component is enabled */ |
@@ -764,8 +827,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
764 | } | 827 | } |
765 | 828 | ||
766 | /* Check depth buffer */ | 829 | /* Check depth buffer */ |
767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 830 | if (track->db_dirty && |
768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 831 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
832 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
833 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
769 | r = r600_cs_track_validate_db(p); | 834 | r = r600_cs_track_validate_db(p); |
770 | if (r) | 835 | if (r) |
771 | return r; | 836 | return r; |
@@ -1229,9 +1294,15 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1229 | break; | 1294 | break; |
1230 | case R_028C04_PA_SC_AA_CONFIG: | 1295 | case R_028C04_PA_SC_AA_CONFIG: |
1231 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); | 1296 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); |
1297 | track->log_nsamples = tmp; | ||
1232 | track->nsamples = 1 << tmp; | 1298 | track->nsamples = 1 << tmp; |
1233 | track->cb_dirty = true; | 1299 | track->cb_dirty = true; |
1234 | break; | 1300 | break; |
1301 | case R_028808_CB_COLOR_CONTROL: | ||
1302 | tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); | ||
1303 | track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; | ||
1304 | track->cb_dirty = true; | ||
1305 | break; | ||
1235 | case R_0280A0_CB_COLOR0_INFO: | 1306 | case R_0280A0_CB_COLOR0_INFO: |
1236 | case R_0280A4_CB_COLOR1_INFO: | 1307 | case R_0280A4_CB_COLOR1_INFO: |
1237 | case R_0280A8_CB_COLOR2_INFO: | 1308 | case R_0280A8_CB_COLOR2_INFO: |
@@ -1310,16 +1381,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); | 1381 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1311 | return -EINVAL; | 1382 | return -EINVAL; |
1312 | } | 1383 | } |
1313 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1314 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; | 1384 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; |
1385 | track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1386 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1315 | } else { | 1387 | } else { |
1316 | r = r600_cs_packet_next_reloc(p, &reloc); | 1388 | r = r600_cs_packet_next_reloc(p, &reloc); |
1317 | if (r) { | 1389 | if (r) { |
1318 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1390 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1319 | return -EINVAL; | 1391 | return -EINVAL; |
1320 | } | 1392 | } |
1321 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1322 | track->cb_color_frag_bo[tmp] = reloc->robj; | 1393 | track->cb_color_frag_bo[tmp] = reloc->robj; |
1394 | track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; | ||
1395 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1396 | } | ||
1397 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1398 | track->cb_dirty = true; | ||
1323 | } | 1399 | } |
1324 | break; | 1400 | break; |
1325 | case R_0280C0_CB_COLOR0_TILE: | 1401 | case R_0280C0_CB_COLOR0_TILE: |
@@ -1336,16 +1412,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); | 1412 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1337 | return -EINVAL; | 1413 | return -EINVAL; |
1338 | } | 1414 | } |
1339 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1340 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; | 1415 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; |
1416 | track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1417 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1341 | } else { | 1418 | } else { |
1342 | r = r600_cs_packet_next_reloc(p, &reloc); | 1419 | r = r600_cs_packet_next_reloc(p, &reloc); |
1343 | if (r) { | 1420 | if (r) { |
1344 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1421 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1345 | return -EINVAL; | 1422 | return -EINVAL; |
1346 | } | 1423 | } |
1347 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1348 | track->cb_color_tile_bo[tmp] = reloc->robj; | 1424 | track->cb_color_tile_bo[tmp] = reloc->robj; |
1425 | track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; | ||
1426 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1427 | } | ||
1428 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1429 | track->cb_dirty = true; | ||
1430 | } | ||
1431 | break; | ||
1432 | case R_028100_CB_COLOR0_MASK: | ||
1433 | case R_028104_CB_COLOR1_MASK: | ||
1434 | case R_028108_CB_COLOR2_MASK: | ||
1435 | case R_02810C_CB_COLOR3_MASK: | ||
1436 | case R_028110_CB_COLOR4_MASK: | ||
1437 | case R_028114_CB_COLOR5_MASK: | ||
1438 | case R_028118_CB_COLOR6_MASK: | ||
1439 | case R_02811C_CB_COLOR7_MASK: | ||
1440 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | ||
1441 | track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); | ||
1442 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1443 | track->cb_dirty = true; | ||
1349 | } | 1444 | } |
1350 | break; | 1445 | break; |
1351 | case CB_COLOR0_BASE: | 1446 | case CB_COLOR0_BASE: |
@@ -1490,7 +1585,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level) | |||
1490 | } | 1585 | } |
1491 | 1586 | ||
1492 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | 1587 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, |
1493 | unsigned w0, unsigned h0, unsigned d0, unsigned format, | 1588 | unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, |
1494 | unsigned block_align, unsigned height_align, unsigned base_align, | 1589 | unsigned block_align, unsigned height_align, unsigned base_align, |
1495 | unsigned *l0_size, unsigned *mipmap_size) | 1590 | unsigned *l0_size, unsigned *mipmap_size) |
1496 | { | 1591 | { |
@@ -1518,7 +1613,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | |||
1518 | 1613 | ||
1519 | depth = r600_mip_minify(d0, i); | 1614 | depth = r600_mip_minify(d0, i); |
1520 | 1615 | ||
1521 | size = nbx * nby * blocksize; | 1616 | size = nbx * nby * blocksize * nsamples; |
1522 | if (nfaces) | 1617 | if (nfaces) |
1523 | size *= nfaces; | 1618 | size *= nfaces; |
1524 | else | 1619 | else |
@@ -1557,13 +1652,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1557 | u32 tiling_flags) | 1652 | u32 tiling_flags) |
1558 | { | 1653 | { |
1559 | struct r600_cs_track *track = p->track; | 1654 | struct r600_cs_track *track = p->track; |
1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1655 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1656 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
1562 | u32 height_align, pitch, pitch_align, depth_align; | 1657 | u32 height_align, pitch, pitch_align, depth_align; |
1563 | u32 array, barray, larray; | 1658 | u32 barray, larray; |
1564 | u64 base_align; | 1659 | u64 base_align; |
1565 | struct array_mode_checker array_check; | 1660 | struct array_mode_checker array_check; |
1566 | u32 format; | 1661 | u32 format; |
1662 | bool is_array; | ||
1567 | 1663 | ||
1568 | /* on legacy kernel we don't perform advanced check */ | 1664 | /* on legacy kernel we don't perform advanced check */ |
1569 | if (p->rdev == NULL) | 1665 | if (p->rdev == NULL) |
@@ -1581,12 +1677,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); | 1677 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
1582 | } | 1678 | } |
1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1679 | word1 = radeon_get_ib_value(p, idx + 1); |
1680 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1681 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1682 | word4 = radeon_get_ib_value(p, idx + 4); | ||
1683 | word5 = radeon_get_ib_value(p, idx + 5); | ||
1684 | dim = G_038000_DIM(word0); | ||
1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1685 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1686 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1687 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1586 | d0 = G_038004_TEX_DEPTH(word1); | 1688 | d0 = G_038004_TEX_DEPTH(word1); |
1689 | format = G_038004_DATA_FORMAT(word1); | ||
1690 | blevel = G_038010_BASE_LEVEL(word4); | ||
1691 | llevel = G_038014_LAST_LEVEL(word5); | ||
1692 | /* pitch in texels */ | ||
1693 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1694 | array_check.group_size = track->group_size; | ||
1695 | array_check.nbanks = track->nbanks; | ||
1696 | array_check.npipes = track->npipes; | ||
1697 | array_check.nsamples = 1; | ||
1698 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1587 | nfaces = 1; | 1699 | nfaces = 1; |
1588 | array = 0; | 1700 | is_array = false; |
1589 | switch (G_038000_DIM(word0)) { | 1701 | switch (dim) { |
1590 | case V_038000_SQ_TEX_DIM_1D: | 1702 | case V_038000_SQ_TEX_DIM_1D: |
1591 | case V_038000_SQ_TEX_DIM_2D: | 1703 | case V_038000_SQ_TEX_DIM_2D: |
1592 | case V_038000_SQ_TEX_DIM_3D: | 1704 | case V_038000_SQ_TEX_DIM_3D: |
@@ -1599,29 +1711,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1599 | break; | 1711 | break; |
1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1712 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1713 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
1602 | array = 1; | 1714 | is_array = true; |
1603 | break; | 1715 | break; |
1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1716 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
1717 | is_array = true; | ||
1718 | /* fall through */ | ||
1719 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1720 | array_check.nsamples = 1 << llevel; | ||
1721 | llevel = 0; | ||
1722 | break; | ||
1606 | default: | 1723 | default: |
1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1724 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
1608 | return -EINVAL; | 1725 | return -EINVAL; |
1609 | } | 1726 | } |
1610 | format = G_038004_DATA_FORMAT(word1); | ||
1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1727 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1728 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
1613 | __func__, __LINE__, format); | 1729 | __func__, __LINE__, format); |
1614 | return -EINVAL; | 1730 | return -EINVAL; |
1615 | } | 1731 | } |
1616 | 1732 | ||
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, | 1733 | if (r600_get_array_mode_alignment(&array_check, |
1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1734 | &pitch_align, &height_align, &depth_align, &base_align)) { |
1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1735 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
@@ -1647,24 +1755,17 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1647 | return -EINVAL; | 1755 | return -EINVAL; |
1648 | } | 1756 | } |
1649 | 1757 | ||
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) { | 1758 | if (blevel > llevel) { |
1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1759 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
1659 | blevel, llevel); | 1760 | blevel, llevel); |
1660 | } | 1761 | } |
1661 | if (array == 1) { | 1762 | if (is_array) { |
1662 | barray = G_038014_BASE_ARRAY(word1); | 1763 | barray = G_038014_BASE_ARRAY(word5); |
1663 | larray = G_038014_LAST_ARRAY(word1); | 1764 | larray = G_038014_LAST_ARRAY(word5); |
1664 | 1765 | ||
1665 | nfaces = larray - barray + 1; | 1766 | nfaces = larray - barray + 1; |
1666 | } | 1767 | } |
1667 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, | 1768 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, |
1668 | pitch_align, height_align, base_align, | 1769 | pitch_align, height_align, base_align, |
1669 | &l0_size, &mipmap_size); | 1770 | &l0_size, &mipmap_size); |
1670 | /* using get ib will give us the offset into the texture bo */ | 1771 | /* using get ib will give us the offset into the texture bo */ |
@@ -1677,7 +1778,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1677 | return -EINVAL; | 1778 | return -EINVAL; |
1678 | } | 1779 | } |
1679 | /* using get ib will give us the offset into the mipmap bo */ | 1780 | /* 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)) { | 1781 | 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", | 1782 | /*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));*/ | 1783 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |