diff options
author | Ilija Hadzic <ihadzic@research.bell-labs.com> | 2011-10-12 23:29:40 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-10-18 05:06:24 -0400 |
commit | 8eec9d6f74271fb69770b9fa3fa7d3659128720b (patch) | |
tree | a1f4a28a619c3ef20ac769c5b2f826ebe13a7fbe | |
parent | 638dd7db599de8c49cfaf9aca9d64d9a0649ff46 (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.c | 94 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 21 |
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 */ |
50 | static void | 49 | static 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 | 631 | static unsigned r600_blit_create_rect(unsigned num_pages, |
612 | that it different predefined constants; consider commonizing */ | 632 | int *width, int *height, int max_dim) |
613 | static 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 | ||
525 | struct 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 | |||
525 | struct r600_blit { | 542 | struct 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; |