aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlija Hadzic <ihadzic@research.bell-labs.com>2011-10-12 23:29:40 -0400
committerDave Airlie <airlied@redhat.com>2011-10-18 05:06:24 -0400
commit8eec9d6f74271fb69770b9fa3fa7d3659128720b (patch)
treea1f4a28a619c3ef20ac769c5b2f826ebe13a7fbe
parent638dd7db599de8c49cfaf9aca9d64d9a0649ff46 (diff)
drm/radeon/kms: cleanup r600 blit code
reorganize the code such that only the primitives (i.e., the functions that load the CP ring) are hardware specific; dynamically link the primitives in a (new) pointer structure inside r600_blit at blit initialization time so that the functions that control the blit operations can be made common for r600 and evergreen parts Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c94
-rw-r--r--drivers/gpu/drm/radeon/radeon.h21
2 files changed, 70 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index d4e215f15062..433115b3a75a 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -44,7 +44,6 @@
44 44
45#define RECT_UNIT_H 32 45#define RECT_UNIT_H 32
46#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) 46#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
47#define MAX_RECT_DIM 8192
48 47
49/* emits 21 on rv770+, 23 on r600 */ 48/* emits 21 on rv770+, 23 on r600 */
50static void 49static void
@@ -491,6 +490,27 @@ int r600_blit_init(struct radeon_device *rdev)
491 u32 packet2s[16]; 490 u32 packet2s[16];
492 int num_packet2s = 0; 491 int num_packet2s = 0;
493 492
493 rdev->r600_blit.primitives.set_render_target = set_render_target;
494 rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync;
495 rdev->r600_blit.primitives.set_shaders = set_shaders;
496 rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource;
497 rdev->r600_blit.primitives.set_tex_resource = set_tex_resource;
498 rdev->r600_blit.primitives.set_scissors = set_scissors;
499 rdev->r600_blit.primitives.draw_auto = draw_auto;
500 rdev->r600_blit.primitives.set_default_state = set_default_state;
501
502 rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
503 rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
504 rdev->r600_blit.ring_size_common += 5; /* done copy */
505 rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
506
507 rdev->r600_blit.ring_size_per_loop = 76;
508 /* set_render_target emits 2 extra dwords on rv6xx */
509 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
510 rdev->r600_blit.ring_size_per_loop += 2;
511
512 rdev->r600_blit.max_dim = 8192;
513
494 /* pin copy shader into vram if already initialized */ 514 /* pin copy shader into vram if already initialized */
495 if (rdev->r600_blit.shader_obj) 515 if (rdev->r600_blit.shader_obj)
496 goto done; 516 goto done;
@@ -608,9 +628,8 @@ static void r600_vb_ib_put(struct radeon_device *rdev)
608 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); 628 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
609} 629}
610 630
611/* FIXME: the function is very similar to evergreen_blit_create_rect, except 631static unsigned r600_blit_create_rect(unsigned num_pages,
612 that it different predefined constants; consider commonizing */ 632 int *width, int *height, int max_dim)
613static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *height)
614{ 633{
615 unsigned max_pages; 634 unsigned max_pages;
616 unsigned pages = num_pages; 635 unsigned pages = num_pages;
@@ -628,12 +647,12 @@ static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *heigh
628 while (num_pages / rect_order) { 647 while (num_pages / rect_order) {
629 h *= 2; 648 h *= 2;
630 rect_order *= 4; 649 rect_order *= 4;
631 if (h >= MAX_RECT_DIM) { 650 if (h >= max_dim) {
632 h = MAX_RECT_DIM; 651 h = max_dim;
633 break; 652 break;
634 } 653 }
635 } 654 }
636 max_pages = (MAX_RECT_DIM * h) / (RECT_UNIT_W * RECT_UNIT_H); 655 max_pages = (max_dim * h) / (RECT_UNIT_W * RECT_UNIT_H);
637 if (pages > max_pages) 656 if (pages > max_pages)
638 pages = max_pages; 657 pages = max_pages;
639 w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h; 658 w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
@@ -659,36 +678,29 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages)
659{ 678{
660 int r; 679 int r;
661 int ring_size; 680 int ring_size;
662 /* loops of emits 64 + fence emit possible */ 681 int num_loops = 0;
663 int dwords_per_loop = 76, num_loops = 0; 682 int dwords_per_loop = rdev->r600_blit.ring_size_per_loop;
664 683
665 r = r600_vb_ib_get(rdev); 684 r = r600_vb_ib_get(rdev);
666 if (r) 685 if (r)
667 return r; 686 return r;
668 687
669 /* set_render_target emits 2 extra dwords on rv6xx */
670 if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
671 dwords_per_loop += 2;
672
673 /* num loops */ 688 /* num loops */
674 while (num_pages) { 689 while (num_pages) {
675 num_pages -= r600_blit_create_rect(num_pages, NULL, NULL); 690 num_pages -= r600_blit_create_rect(num_pages, NULL, NULL,
691 rdev->r600_blit.max_dim);
676 num_loops++; 692 num_loops++;
677 } 693 }
678 694
679 /* calculate number of loops correctly */ 695 /* calculate number of loops correctly */
680 ring_size = num_loops * dwords_per_loop; 696 ring_size = num_loops * dwords_per_loop;
681 /* set default + shaders */ 697 ring_size += rdev->r600_blit.ring_size_common;
682 ring_size += 40; /* shaders + def state */
683 ring_size += 10; /* fence emit for VB IB */
684 ring_size += 5; /* done copy */
685 ring_size += 10; /* fence emit for done copy */
686 r = radeon_ring_lock(rdev, ring_size); 698 r = radeon_ring_lock(rdev, ring_size);
687 if (r) 699 if (r)
688 return r; 700 return r;
689 701
690 set_default_state(rdev); /* 14 */ 702 rdev->r600_blit.primitives.set_default_state(rdev);
691 set_shaders(rdev); /* 26 */ 703 rdev->r600_blit.primitives.set_shaders(rdev);
692 return 0; 704 return 0;
693} 705}
694 706
@@ -712,14 +724,17 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
712 u64 vb_gpu_addr; 724 u64 vb_gpu_addr;
713 u32 *vb; 725 u32 *vb;
714 726
715 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, 727 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n",
728 src_gpu_addr, dst_gpu_addr,
716 num_pages, rdev->r600_blit.vb_used); 729 num_pages, rdev->r600_blit.vb_used);
717 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); 730 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
718 731
719 while (num_pages) { 732 while (num_pages) {
720 int w, h; 733 int w, h;
721 unsigned size_in_bytes; 734 unsigned size_in_bytes;
722 unsigned pages_per_loop = r600_blit_create_rect(num_pages, &w, &h); 735 unsigned pages_per_loop =
736 r600_blit_create_rect(num_pages, &w, &h,
737 rdev->r600_blit.max_dim);
723 738
724 size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE; 739 size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;
725 DRM_DEBUG("rectangle w=%d h=%d\n", w, h); 740 DRM_DEBUG("rectangle w=%d h=%d\n", w, h);
@@ -743,32 +758,21 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
743 vb[10] = i2f(w); 758 vb[10] = i2f(w);
744 vb[11] = i2f(h); 759 vb[11] = i2f(h);
745 760
746 /* src 9 */ 761 rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
747 set_tex_resource(rdev, FMT_8_8_8_8, w, h, w, src_gpu_addr); 762 w, h, w, src_gpu_addr);
748 763 rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
749 /* 5 */ 764 PACKET3_TC_ACTION_ENA,
750 cp_set_surface_sync(rdev, 765 size_in_bytes, src_gpu_addr);
751 PACKET3_TC_ACTION_ENA, size_in_bytes, src_gpu_addr); 766 rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8,
752 767 w, h, dst_gpu_addr);
753 /* dst 23 */ 768 rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);
754 set_render_target(rdev, COLOR_8_8_8_8, w, h, dst_gpu_addr);
755
756 /* scissors 12 */
757 set_scissors(rdev, 0, 0, w, h);
758
759 /* Vertex buffer setup 14 */
760 vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; 769 vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
761 set_vtx_resource(rdev, vb_gpu_addr); 770 rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr);
762 771 rdev->r600_blit.primitives.draw_auto(rdev);
763 /* draw 10 */ 772 rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
764 draw_auto(rdev);
765
766 /* 5 */
767 cp_set_surface_sync(rdev,
768 PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, 773 PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
769 size_in_bytes, dst_gpu_addr); 774 size_in_bytes, dst_gpu_addr);
770 775
771 /* 78 ring dwords per loop */
772 vb += 12; 776 vb += 12;
773 rdev->r600_blit.vb_used += 4*12; 777 rdev->r600_blit.vb_used += 4*12;
774 src_gpu_addr += size_in_bytes; 778 src_gpu_addr += size_in_bytes;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9f6d206104df..6b1d09904e1f 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -522,9 +522,30 @@ struct r600_ih {
522 bool enabled; 522 bool enabled;
523}; 523};
524 524
525struct r600_blit_cp_primitives {
526 void (*set_render_target)(struct radeon_device *rdev, int format,
527 int w, int h, u64 gpu_addr);
528 void (*cp_set_surface_sync)(struct radeon_device *rdev,
529 u32 sync_type, u32 size,
530 u64 mc_addr);
531 void (*set_shaders)(struct radeon_device *rdev);
532 void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr);
533 void (*set_tex_resource)(struct radeon_device *rdev,
534 int format, int w, int h, int pitch,
535 u64 gpu_addr);
536 void (*set_scissors)(struct radeon_device *rdev, int x1, int y1,
537 int x2, int y2);
538 void (*draw_auto)(struct radeon_device *rdev);
539 void (*set_default_state)(struct radeon_device *rdev);
540};
541
525struct r600_blit { 542struct r600_blit {
526 struct mutex mutex; 543 struct mutex mutex;
527 struct radeon_bo *shader_obj; 544 struct radeon_bo *shader_obj;
545 struct r600_blit_cp_primitives primitives;
546 int max_dim;
547 int ring_size_common;
548 int ring_size_per_loop;
528 u64 shader_gpu_addr; 549 u64 shader_gpu_addr;
529 u32 vs_offset, ps_offset; 550 u32 vs_offset, ps_offset;
530 u32 state_offset; 551 u32 state_offset;