diff options
author | Laurent Pinchart | 2012-07-20 07:50:41 -0500 |
---|---|---|
committer | Rob Clark | 2012-07-20 10:30:46 -0500 |
commit | 3fdc1777ee156ebfa4281b49d8783adbbcae3ee1 (patch) | |
tree | 1c8a948602e8fa2b3d2b8c915d6f05bab7654175 | |
parent | faf26b689d4a2a6d1e851a1ea2fd657406eebfff (diff) | |
download | libdrm-3fdc1777ee156ebfa4281b49d8783adbbcae3ee1.tar.gz libdrm-3fdc1777ee156ebfa4281b49d8783adbbcae3ee1.tar.xz libdrm-3fdc1777ee156ebfa4281b49d8783adbbcae3ee1.zip |
modetest: Unify buffer allocation
Merge the create_test_buffer() and create_grey_buffer() functions into a
single buffer allocation function that takes the pixel format and fill
pattern as parameters.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r-- | tests/modetest/modetest.c | 383 |
1 files changed, 192 insertions, 191 deletions
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index ec3121e1..496aac57 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c | |||
@@ -657,112 +657,39 @@ make_pwetty(void *data, int width, int height, int stride) | |||
657 | #endif | 657 | #endif |
658 | } | 658 | } |
659 | 659 | ||
660 | static int | 660 | /* ----------------------------------------------------------------------------- |
661 | create_test_buffer(struct kms_driver *kms, | 661 | * Buffers management |
662 | int width, int height, int *stride_out, | 662 | */ |
663 | struct kms_bo **bo_out) | ||
664 | { | ||
665 | struct kms_bo *bo; | ||
666 | int ret, i, j, stride; | ||
667 | void *virtual; | ||
668 | |||
669 | bo = allocate_buffer(kms, width, height, &stride); | ||
670 | if (!bo) | ||
671 | return -1; | ||
672 | |||
673 | ret = kms_bo_map(bo, &virtual); | ||
674 | if (ret) { | ||
675 | fprintf(stderr, "failed to map buffer: %s\n", | ||
676 | strerror(-ret)); | ||
677 | kms_bo_destroy(&bo); | ||
678 | return -1; | ||
679 | } | ||
680 | |||
681 | /* paint the buffer with colored tiles */ | ||
682 | for (j = 0; j < height; j++) { | ||
683 | uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride); | ||
684 | for (i = 0; i < width; i++) { | ||
685 | div_t d = div(i, width); | ||
686 | fb_ptr[i] = | ||
687 | 0x00130502 * (d.quot >> 6) + | ||
688 | 0x000a1120 * (d.rem >> 6); | ||
689 | } | ||
690 | } | ||
691 | 663 | ||
692 | make_pwetty(virtual, width, height, stride); | 664 | /* swap these for big endian.. */ |
665 | #define RED 2 | ||
666 | #define GREEN 1 | ||
667 | #define BLUE 0 | ||
693 | 668 | ||
694 | kms_bo_unmap(bo); | 669 | struct format_name { |
670 | unsigned int format; | ||
671 | const char *name; | ||
672 | }; | ||
695 | 673 | ||
696 | *bo_out = bo; | 674 | static const struct format_name format_names[] = { |
697 | *stride_out = stride; | 675 | { DRM_FORMAT_YUYV, "YUYV" }, |
698 | return 0; | 676 | { DRM_FORMAT_NV12, "NV12" }, |
699 | } | 677 | { DRM_FORMAT_YVU420, "YV12" }, |
678 | { DRM_FORMAT_XRGB1555, "XR15" }, | ||
679 | { DRM_FORMAT_XRGB8888, "XR24" }, | ||
680 | { DRM_FORMAT_ARGB1555, "AR15" }, | ||
681 | }; | ||
700 | 682 | ||
701 | static int | 683 | unsigned int format_fourcc(const char *name) |
702 | create_grey_buffer(struct kms_driver *kms, | ||
703 | int width, int height, int *stride_out, | ||
704 | struct kms_bo **bo_out) | ||
705 | { | 684 | { |
706 | struct kms_bo *bo; | 685 | unsigned int i; |
707 | int size, ret, stride; | 686 | for (i = 0; i < ARRAY_SIZE(format_names); i++) { |
708 | void *virtual; | 687 | if (!strcmp(format_names[i].name, name)) |
709 | 688 | return format_names[i].format; | |
710 | bo = allocate_buffer(kms, width, height, &stride); | ||
711 | if (!bo) | ||
712 | return -1; | ||
713 | |||
714 | ret = kms_bo_map(bo, &virtual); | ||
715 | if (ret) { | ||
716 | fprintf(stderr, "failed to map buffer: %s\n", | ||
717 | strerror(-ret)); | ||
718 | kms_bo_destroy(&bo); | ||
719 | return -1; | ||
720 | } | 689 | } |
721 | |||
722 | size = stride * height; | ||
723 | memset(virtual, 0x77, size); | ||
724 | kms_bo_unmap(bo); | ||
725 | |||
726 | *bo_out = bo; | ||
727 | *stride_out = stride; | ||
728 | |||
729 | return 0; | 690 | return 0; |
730 | } | 691 | } |
731 | 692 | ||
732 | void | ||
733 | page_flip_handler(int fd, unsigned int frame, | ||
734 | unsigned int sec, unsigned int usec, void *data) | ||
735 | { | ||
736 | struct connector *c; | ||
737 | unsigned int new_fb_id; | ||
738 | struct timeval end; | ||
739 | double t; | ||
740 | |||
741 | c = data; | ||
742 | if (c->current_fb_id == c->fb_id[0]) | ||
743 | new_fb_id = c->fb_id[1]; | ||
744 | else | ||
745 | new_fb_id = c->fb_id[0]; | ||
746 | |||
747 | drmModePageFlip(fd, c->crtc, new_fb_id, | ||
748 | DRM_MODE_PAGE_FLIP_EVENT, c); | ||
749 | c->current_fb_id = new_fb_id; | ||
750 | c->swap_count++; | ||
751 | if (c->swap_count == 60) { | ||
752 | gettimeofday(&end, NULL); | ||
753 | t = end.tv_sec + end.tv_usec * 1e-6 - | ||
754 | (c->start.tv_sec + c->start.tv_usec * 1e-6); | ||
755 | fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); | ||
756 | c->swap_count = 0; | ||
757 | c->start = end; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | /* swap these for big endian.. */ | ||
762 | #define RED 2 | ||
763 | #define GREEN 1 | ||
764 | #define BLUE 0 | ||
765 | |||
766 | static void | 693 | static void |
767 | fill420(unsigned char *y, unsigned char *u, unsigned char *v, | 694 | fill420(unsigned char *y, unsigned char *u, unsigned char *v, |
768 | int cs /*chroma pixel stride */, | 695 | int cs /*chroma pixel stride */, |
@@ -835,6 +762,154 @@ fill1555(unsigned char *virtual, int n, int width, int height, int stride) | |||
835 | } | 762 | } |
836 | } | 763 | } |
837 | 764 | ||
765 | static void | ||
766 | fill8888(unsigned char *virtual, int width, int height, int stride) | ||
767 | { | ||
768 | int i, j; | ||
769 | /* paint the buffer with colored tiles */ | ||
770 | for (j = 0; j < height; j++) { | ||
771 | uint32_t *ptr = (uint32_t*)((char*)virtual + j * stride); | ||
772 | for (i = 0; i < width; i++) { | ||
773 | div_t d = div(i, width); | ||
774 | ptr[i] = | ||
775 | 0x00130502 * (d.quot >> 6) + | ||
776 | 0x000a1120 * (d.rem >> 6); | ||
777 | } | ||
778 | } | ||
779 | |||
780 | make_pwetty(virtual, width, height, stride); | ||
781 | } | ||
782 | |||
783 | static void | ||
784 | fill_grey(unsigned char *virtual, int width, int height, int stride) | ||
785 | { | ||
786 | memset(virtual, 0x77, stride * height); | ||
787 | } | ||
788 | |||
789 | static struct kms_bo * | ||
790 | create_test_buffer(struct kms_driver *kms, unsigned int format, | ||
791 | int width, int height, int handles[4], | ||
792 | int pitches[4], int offsets[4], int grey) | ||
793 | { | ||
794 | struct kms_bo *bo; | ||
795 | int ret, stride; | ||
796 | void *virtual; | ||
797 | |||
798 | bo = allocate_buffer(kms, width, height, &pitches[0]); | ||
799 | if (!bo) | ||
800 | return NULL; | ||
801 | |||
802 | ret = kms_bo_map(bo, &virtual); | ||
803 | if (ret) { | ||
804 | fprintf(stderr, "failed to map buffer: %s\n", | ||
805 | strerror(-ret)); | ||
806 | kms_bo_destroy(&bo); | ||
807 | return NULL; | ||
808 | } | ||
809 | |||
810 | /* just testing a limited # of formats to test single | ||
811 | * and multi-planar path.. would be nice to add more.. | ||
812 | */ | ||
813 | switch (format) { | ||
814 | case DRM_FORMAT_YUYV: | ||
815 | pitches[0] = width * 2; | ||
816 | offsets[0] = 0; | ||
817 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
818 | |||
819 | fill422(virtual, 0, width, height, pitches[0]); | ||
820 | break; | ||
821 | |||
822 | case DRM_FORMAT_NV12: | ||
823 | pitches[0] = width; | ||
824 | offsets[0] = 0; | ||
825 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
826 | pitches[1] = width; | ||
827 | offsets[1] = width * height; | ||
828 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]); | ||
829 | |||
830 | fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1, | ||
831 | 2, 0, width, height, pitches[0]); | ||
832 | break; | ||
833 | |||
834 | case DRM_FORMAT_YVU420: | ||
835 | pitches[0] = width; | ||
836 | offsets[0] = 0; | ||
837 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
838 | pitches[1] = width / 2; | ||
839 | offsets[1] = width * height; | ||
840 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]); | ||
841 | pitches[2] = width / 2; | ||
842 | offsets[2] = offsets[1] + (width * height) / 4; | ||
843 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[2]); | ||
844 | |||
845 | fill420(virtual, virtual+offsets[1], virtual+offsets[2], | ||
846 | 1, 0, width, height, pitches[0]); | ||
847 | break; | ||
848 | |||
849 | case DRM_FORMAT_XRGB1555: | ||
850 | pitches[0] = width * 2; | ||
851 | offsets[0] = 0; | ||
852 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
853 | |||
854 | fill1555(virtual, 0, width, height, pitches[0]); | ||
855 | break; | ||
856 | |||
857 | case DRM_FORMAT_XRGB8888: | ||
858 | pitches[0] = width * 4; | ||
859 | offsets[0] = 0; | ||
860 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
861 | |||
862 | if (grey) | ||
863 | fill_grey(virtual, width, height, pitches[0]); | ||
864 | else | ||
865 | fill8888(virtual, width, height, pitches[0]); | ||
866 | break; | ||
867 | |||
868 | case DRM_FORMAT_ARGB1555: | ||
869 | pitches[0] = width * 2; | ||
870 | offsets[0] = 0; | ||
871 | kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); | ||
872 | |||
873 | fill1555(virtual, 0, width, height, pitches[0]); | ||
874 | break; | ||
875 | } | ||
876 | |||
877 | kms_bo_unmap(bo); | ||
878 | |||
879 | return bo; | ||
880 | } | ||
881 | |||
882 | /* -------------------------------------------------------------------------- */ | ||
883 | |||
884 | void | ||
885 | page_flip_handler(int fd, unsigned int frame, | ||
886 | unsigned int sec, unsigned int usec, void *data) | ||
887 | { | ||
888 | struct connector *c; | ||
889 | unsigned int new_fb_id; | ||
890 | struct timeval end; | ||
891 | double t; | ||
892 | |||
893 | c = data; | ||
894 | if (c->current_fb_id == c->fb_id[0]) | ||
895 | new_fb_id = c->fb_id[1]; | ||
896 | else | ||
897 | new_fb_id = c->fb_id[0]; | ||
898 | |||
899 | drmModePageFlip(fd, c->crtc, new_fb_id, | ||
900 | DRM_MODE_PAGE_FLIP_EVENT, c); | ||
901 | c->current_fb_id = new_fb_id; | ||
902 | c->swap_count++; | ||
903 | if (c->swap_count == 60) { | ||
904 | gettimeofday(&end, NULL); | ||
905 | t = end.tv_sec + end.tv_usec * 1e-6 - | ||
906 | (c->start.tv_sec + c->start.tv_usec * 1e-6); | ||
907 | fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); | ||
908 | c->swap_count = 0; | ||
909 | c->start = end; | ||
910 | } | ||
911 | } | ||
912 | |||
838 | static int | 913 | static int |
839 | set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) | 914 | set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) |
840 | { | 915 | { |
@@ -847,6 +922,12 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) | |||
847 | int ret, crtc_x, crtc_y, crtc_w, crtc_h; | 922 | int ret, crtc_x, crtc_y, crtc_w, crtc_h; |
848 | unsigned int i; | 923 | unsigned int i; |
849 | 924 | ||
925 | format = format_fourcc(p->format_str); | ||
926 | if (format == 0) { | ||
927 | fprintf(stderr, "Unknown format: %s\n", p->format_str); | ||
928 | return -1; | ||
929 | } | ||
930 | |||
850 | /* find an unused plane which can be connected to our crtc */ | 931 | /* find an unused plane which can be connected to our crtc */ |
851 | plane_resources = drmModeGetPlaneResources(fd); | 932 | plane_resources = drmModeGetPlaneResources(fd); |
852 | if (!plane_resources) { | 933 | if (!plane_resources) { |
@@ -877,92 +958,10 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) | |||
877 | return -1; | 958 | return -1; |
878 | } | 959 | } |
879 | 960 | ||
880 | if (!strcmp(p->format_str, "XR24")) { | 961 | plane_bo = create_test_buffer(kms, format, p->w, p->h, handles, |
881 | if (create_test_buffer(kms, p->w, p->h, &pitches[0], &plane_bo)) | 962 | pitches, offsets, 0); |
882 | return -1; | 963 | if (plane_bo == NULL) |
883 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | 964 | return -1; |
884 | format = DRM_FORMAT_XRGB8888; | ||
885 | } else { | ||
886 | void *virtual; | ||
887 | |||
888 | /* TODO: this always allocates a buffer for 32bpp RGB.. but for | ||
889 | * YUV formats, we don't use all of it.. since 4bytes/pixel is | ||
890 | * worst case, so live with it for now and just don't use all | ||
891 | * the buffer: | ||
892 | */ | ||
893 | plane_bo = allocate_buffer(kms, p->w, p->h, &pitches[0]); | ||
894 | if (!plane_bo) | ||
895 | return -1; | ||
896 | |||
897 | ret = kms_bo_map(plane_bo, &virtual); | ||
898 | if (ret) { | ||
899 | fprintf(stderr, "failed to map buffer: %s\n", | ||
900 | strerror(-ret)); | ||
901 | kms_bo_destroy(&plane_bo); | ||
902 | return -1; | ||
903 | } | ||
904 | |||
905 | /* just testing a limited # of formats to test single | ||
906 | * and multi-planar path.. would be nice to add more.. | ||
907 | */ | ||
908 | if (!strcmp(p->format_str, "YUYV")) { | ||
909 | pitches[0] = p->w * 2; | ||
910 | offsets[0] = 0; | ||
911 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | ||
912 | |||
913 | fill422(virtual, 0, p->w, p->h, pitches[0]); | ||
914 | |||
915 | format = DRM_FORMAT_YUYV; | ||
916 | } else if (!strcmp(p->format_str, "NV12")) { | ||
917 | pitches[0] = p->w; | ||
918 | offsets[0] = 0; | ||
919 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | ||
920 | pitches[1] = p->w; | ||
921 | offsets[1] = p->w * p->h; | ||
922 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]); | ||
923 | |||
924 | fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1, | ||
925 | 2, 0, p->w, p->h, pitches[0]); | ||
926 | |||
927 | format = DRM_FORMAT_NV12; | ||
928 | } else if (!strcmp(p->format_str, "YV12")) { | ||
929 | pitches[0] = p->w; | ||
930 | offsets[0] = 0; | ||
931 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | ||
932 | pitches[1] = p->w / 2; | ||
933 | offsets[1] = p->w * p->h; | ||
934 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]); | ||
935 | pitches[2] = p->w / 2; | ||
936 | offsets[2] = offsets[1] + (p->w * p->h) / 4; | ||
937 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[2]); | ||
938 | |||
939 | fill420(virtual, virtual+offsets[1], virtual+offsets[2], | ||
940 | 1, 0, p->w, p->h, pitches[0]); | ||
941 | |||
942 | format = DRM_FORMAT_YVU420; | ||
943 | } else if (!strcmp(p->format_str, "XR15")) { | ||
944 | pitches[0] = p->w * 2; | ||
945 | offsets[0] = 0; | ||
946 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | ||
947 | |||
948 | fill1555(virtual, 0, p->w, p->h, pitches[0]); | ||
949 | |||
950 | format = DRM_FORMAT_XRGB1555; | ||
951 | } else if (!strcmp(p->format_str, "AR15")) { | ||
952 | pitches[0] = p->w * 2; | ||
953 | offsets[0] = 0; | ||
954 | kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); | ||
955 | |||
956 | fill1555(virtual, 0, p->w, p->h, pitches[0]); | ||
957 | |||
958 | format = DRM_FORMAT_ARGB1555; | ||
959 | } else { | ||
960 | fprintf(stderr, "Unknown format: %s\n", p->format_str); | ||
961 | return -1; | ||
962 | } | ||
963 | |||
964 | kms_bo_unmap(plane_bo); | ||
965 | } | ||
966 | 965 | ||
967 | /* just use single plane format for now.. */ | 966 | /* just use single plane format for now.. */ |
968 | if (drmModeAddFB2(fd, p->w, p->h, format, | 967 | if (drmModeAddFB2(fd, p->w, p->h, format, |
@@ -996,8 +995,8 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, | |||
996 | struct kms_driver *kms; | 995 | struct kms_driver *kms; |
997 | struct kms_bo *bo, *other_bo; | 996 | struct kms_bo *bo, *other_bo; |
998 | unsigned int fb_id, other_fb_id; | 997 | unsigned int fb_id, other_fb_id; |
999 | int i, j, ret, width, height, x, stride; | 998 | int i, j, ret, width, height, x; |
1000 | unsigned handle; | 999 | uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ |
1001 | drmEventContext evctx; | 1000 | drmEventContext evctx; |
1002 | 1001 | ||
1003 | width = 0; | 1002 | width = 0; |
@@ -1018,11 +1017,12 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, | |||
1018 | return; | 1017 | return; |
1019 | } | 1018 | } |
1020 | 1019 | ||
1021 | if (create_test_buffer(kms, width, height, &stride, &bo)) | 1020 | bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles, |
1021 | pitches, offsets, 0); | ||
1022 | if (bo == NULL) | ||
1022 | return; | 1023 | return; |
1023 | 1024 | ||
1024 | kms_bo_get_prop(bo, KMS_HANDLE, &handle); | 1025 | ret = drmModeAddFB(fd, width, height, 24, 32, pitches[0], handles[0], &fb_id); |
1025 | ret = drmModeAddFB(fd, width, height, 24, 32, stride, handle, &fb_id); | ||
1026 | if (ret) { | 1026 | if (ret) { |
1027 | fprintf(stderr, "failed to add fb (%ux%u): %s\n", | 1027 | fprintf(stderr, "failed to add fb (%ux%u): %s\n", |
1028 | width, height, strerror(errno)); | 1028 | width, height, strerror(errno)); |
@@ -1060,11 +1060,12 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, | |||
1060 | if (!page_flip) | 1060 | if (!page_flip) |
1061 | return; | 1061 | return; |
1062 | 1062 | ||
1063 | if (create_grey_buffer(kms, width, height, &stride, &other_bo)) | 1063 | other_bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles, |
1064 | pitches, offsets, 1); | ||
1065 | if (other_bo == NULL) | ||
1064 | return; | 1066 | return; |
1065 | 1067 | ||
1066 | kms_bo_get_prop(other_bo, KMS_HANDLE, &handle); | 1068 | ret = drmModeAddFB(fd, width, height, 32, 32, pitches[0], handles[0], |
1067 | ret = drmModeAddFB(fd, width, height, 32, 32, stride, handle, | ||
1068 | &other_fb_id); | 1069 | &other_fb_id); |
1069 | if (ret) { | 1070 | if (ret) { |
1070 | fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); | 1071 | fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); |