600{
601 unsigned int bpp, src_height, src_width, dst_height, dst_width, row_byte_count;
606 unsigned int src_fmt_attrs, dst_fmt_attrs;
608 unsigned int x, sx, xinc,
y, sy, yinc;
611 unsigned int texture_level;
613 BOOL same_sub_resource;
619
620 TRACE(
"dst_texture %p, dst_sub_resource_idx %u, dst_box %s, src_texture %p, "
621 "src_sub_resource_idx %u, src_box %s, flags %#x, fx %p, filter %s.\n",
622 dst_texture, dst_sub_resource_idx,
debug_box(dst_box), src_texture,
624
626
627 src_format = src_texture->
resource.format;
629
634
635 src_height = src_box->
bottom - src_box->
top;
636 src_width = src_box->
right - src_box->
left;
637 dst_height = dst_box->
bottom - dst_box->
top;
638 dst_width = dst_box->
right - dst_box->
left;
639
640 dst_range.offset = 0;
641 dst_range.size = dst_texture->
sub_resources[dst_sub_resource_idx].size;
642 if (src_texture == dst_texture && src_sub_resource_idx == dst_sub_resource_idx)
643 {
644 same_sub_resource =
TRUE;
645
646 map_binding = dst_texture->
resource.map_binding;
647 texture_level = dst_sub_resource_idx % dst_texture->
level_count;
655
656 src_map = dst_map;
657 }
658 else
659 {
660 same_sub_resource =
FALSE;
662 && (dst_width != src_width || dst_height != src_height);
663
664 if (upload)
665 {
668 }
669
671 {
673 {
678 }
679 src_texture = converted_texture;
680 src_sub_resource_idx = 0;
681 src_format = src_texture->
resource.format;
682 }
683
684 map_binding = src_texture->
resource.map_binding;
685 texture_level = src_sub_resource_idx % src_texture->
level_count;
692
693 if (upload)
694 {
696 &dst_map.row_pitch, &dst_map.slice_pitch);
697 dst_map.data =
malloc(dst_map.slice_pitch);
698 }
699 else
700 {
701 map_binding = dst_texture->
resource.map_binding;
702 texture_level = dst_sub_resource_idx % dst_texture->
level_count;
705
711 }
712 }
713 src_fmt_attrs = src_format->
attrs;
715 flags &= ~WINED3D_BLT_RAW;
716
718 row_byte_count = dst_width *
bpp;
719
720 sbase = (
BYTE *)src_map.data
723 dbuf = (
BYTE *)dst_map.data
724 + ((dst_box->
top /
dst_format->block_height) * dst_map.row_pitch)
726
728 {
730
731 if (same_sub_resource)
732 {
733 FIXME(
"Only plain blits supported on compressed surfaces.\n");
735 goto release;
736 }
737
739 src_map.row_pitch, dst_map.row_pitch, dst_width, dst_height,
741 goto release;
742 }
743
745 {
746 FIXME(
"Unsupported blit between height-scaled formats (src %s, dst %s).\n",
749 goto release;
750 }
751
753 && (src_width != dst_width || src_height != dst_height))
754 {
755
757 }
758
759 xinc = (src_width << 16) / dst_width;
760 yinc = (src_height << 16) / dst_height;
761
763 {
764
765 if (dst_width == src_width)
766 {
767 if (dst_height == src_height)
768 {
769
770
771 sbuf = sbase;
772
773
774 if (!same_sub_resource || dst_box->
top < src_box->
top
776 {
777
778 for (
y = 0;
y < dst_height; ++
y)
779 {
780 memcpy(dbuf, sbuf, row_byte_count);
781 sbuf += src_map.row_pitch;
782 dbuf += dst_map.row_pitch;
783 }
784 }
785 else if (dst_box->
top > src_box->
top)
786 {
787
788 sbuf += src_map.row_pitch * dst_height;
789 dbuf += dst_map.row_pitch * dst_height;
790 for (
y = 0;
y < dst_height; ++
y)
791 {
792 sbuf -= src_map.row_pitch;
793 dbuf -= dst_map.row_pitch;
794 memcpy(dbuf, sbuf, row_byte_count);
795 }
796 }
797 else
798 {
799
800 for (
y = 0;
y < dst_height; ++
y)
801 {
802 memmove(dbuf, sbuf, row_byte_count);
803 sbuf += src_map.row_pitch;
804 dbuf += dst_map.row_pitch;
805 }
806 }
807 }
808 else
809 {
810
811 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
812 {
813 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
814 memcpy(dbuf, sbuf, row_byte_count);
815 dbuf += dst_map.row_pitch;
816 }
817 }
818 }
819 else
820 {
821
822 unsigned int last_sy = ~0
u;
823 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
824 {
825 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
826
827 if ((sy >> 16) == (last_sy >> 16))
828 {
829
830
831 memcpy(dbuf, dbuf - dst_map.row_pitch, row_byte_count);
832 }
833 else
834 {
835#define STRETCH_ROW(type) \
836do { \
837 const type *s = (const type *)sbuf; \
838 type *d = (type *)dbuf; \
839 for (x = sx = 0; x < dst_width; ++x, sx += xinc) \
840 d[x] = s[sx >> 16]; \
841} while(0)
842
844 {
845 case 1:
847 break;
848 case 2:
850 break;
851 case 4:
853 break;
854 case 3:
855 {
858 for (
x = sx = 0;
x < dst_width;
x++, sx+= xinc)
859 {
861
862 s = sbuf + 3 * (sx >> 16);
863 pixel =
s[0] | (
s[1] << 8) | (
s[2] << 16);
864 d[0] = (pixel ) & 0xff;
865 d[1] = (pixel >> 8) & 0xff;
866 d[2] = (pixel >> 16) & 0xff;
868 }
869 break;
870 }
871 default:
872 FIXME(
"Stretched blit not implemented for bpp %u.\n",
bpp * 8);
875 }
876#undef STRETCH_ROW
877 }
878 dbuf += dst_map.row_pitch;
879 last_sy = sy;
880 }
881 }
882 }
883 else
884 {
885 LONG dstyinc = dst_map.row_pitch, dstxinc =
bpp;
886 DWORD keylow = 0xffffffff, keyhigh = 0, keymask = 0xffffffff;
887 DWORD destkeylow = 0x0, destkeyhigh = 0xffffffff, destkeymask = 0xffffffff;
890 {
891
893 {
894 keylow = src_texture->
async.src_blt_color_key.color_space_low_value;
895 keyhigh = src_texture->
async.src_blt_color_key.color_space_high_value;
896 }
898 {
899 keylow =
fx->src_color_key.color_space_low_value;
900 keyhigh =
fx->src_color_key.color_space_high_value;
901 }
902
904 {
905
906 destkeylow = src_texture->
async.dst_blt_color_key.color_space_low_value;
907 destkeyhigh = src_texture->
async.dst_blt_color_key.color_space_high_value;
908 }
910 {
911 destkeylow =
fx->dst_color_key.color_space_low_value;
912 destkeyhigh =
fx->dst_color_key.color_space_high_value;
913 }
914
916 {
917 keymask = 0xff;
918 }
919 else
920 {
924 }
927 }
928
930 {
931 BYTE *dTopLeft, *dTopRight, *dBottomLeft, *dBottomRight, *tmp;
933 dTopLeft = dbuf;
934 dTopRight = dbuf + ((dst_width - 1) *
bpp);
935 dBottomLeft = dTopLeft + ((dst_height - 1) * dst_map.row_pitch);
936 dBottomRight = dBottomLeft + ((dst_width - 1) *
bpp);
937
939 {
940
941 WARN(
"Nothing done for WINEDDBLTFX_ARITHSTRETCHY.\n");
942 }
944 {
945 tmp = dTopRight;
946 dTopRight = dTopLeft;
947 dTopLeft = tmp;
948 tmp = dBottomRight;
949 dBottomRight = dBottomLeft;
950 dBottomLeft = tmp;
951 dstxinc = dstxinc * -1;
952 }
954 {
955 tmp = dTopLeft;
956 dTopLeft = dBottomLeft;
957 dBottomLeft = tmp;
958 tmp = dTopRight;
959 dTopRight = dBottomRight;
960 dBottomRight = tmp;
961 dstyinc = dstyinc * -1;
962 }
964 {
965
966 WARN(
"Nothing done for WINEDDBLTFX_NOTEARING.\n");
967 }
969 {
970 tmp = dBottomRight;
971 dBottomRight = dTopLeft;
972 dTopLeft = tmp;
973 tmp = dBottomLeft;
974 dBottomLeft = dTopRight;
975 dTopRight = tmp;
976 dstxinc = dstxinc * -1;
977 dstyinc = dstyinc * -1;
978 }
980 {
981 tmp = dTopLeft;
982 dTopLeft = dBottomLeft;
983 dBottomLeft = dBottomRight;
984 dBottomRight = dTopRight;
985 dTopRight = tmp;
986 tmpxy = dstxinc;
987 dstxinc = dstyinc;
988 dstyinc = tmpxy;
989 dstxinc = dstxinc * -1;
990 }
992 {
993 tmp = dTopLeft;
994 dTopLeft = dTopRight;
995 dTopRight = dBottomRight;
996 dBottomRight = dBottomLeft;
997 dBottomLeft = tmp;
998 tmpxy = dstxinc;
999 dstxinc = dstyinc;
1000 dstyinc = tmpxy;
1001 dstyinc = dstyinc * -1;
1002 }
1004 {
1005
1006 WARN(
"Nothing done for WINEDDBLTFX_ZBUFFERBASEDEST.\n");
1007 }
1008 dbuf = dTopLeft;
1010 }
1011
1012#define COPY_COLORKEY_FX(type) \
1013do { \
1014 const type *s; \
1015 type *d = (type *)dbuf, *dx, tmp; \
1016 for (y = sy = 0; y < dst_height; ++y, sy += yinc) \
1017 { \
1018 s = (const type *)(sbase + (sy >> 16) * src_map.row_pitch); \
1019 dx = d; \
1020 for (x = sx = 0; x < dst_width; ++x, sx += xinc) \
1021 { \
1022 tmp = s[sx >> 16]; \
1023 if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) \
1024 && ((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) \
1025 { \
1026 dx[0] = tmp; \
1027 } \
1028 dx = (type *)(((BYTE *)dx) + dstxinc); \
1029 } \
1030 d = (type *)(((BYTE *)d) + dstyinc); \
1031 } \
1032} while(0)
1033
1035 {
1036 case 1:
1038 break;
1039 case 2:
1041 break;
1042 case 4:
1044 break;
1045 case 3:
1046 {
1049 for (
y = sy = 0;
y < dst_height; ++
y, sy += yinc)
1050 {
1051 sbuf = sbase + (sy >> 16) * src_map.row_pitch;
1053 for (
x = sx = 0;
x < dst_width; ++
x, sx+= xinc)
1054 {
1055 DWORD pixel, dpixel = 0;
1056 s = sbuf + 3 * (sx>>16);
1057 pixel =
s[0] | (
s[1] << 8) | (
s[2] << 16);
1058 dpixel =
dx[0] | (
dx[1] << 8 ) | (
dx[2] << 16);
1059 if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh)
1060 && ((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh))
1061 {
1062 dx[0] = (pixel ) & 0xff;
1063 dx[1] = (pixel >> 8) & 0xff;
1064 dx[2] = (pixel >> 16) & 0xff;
1065 }
1067 }
1069 }
1070 break;
1071 }
1072 default:
1073 FIXME(
"%s color-keyed blit not implemented for bpp %u.\n",
1077#undef COPY_COLORKEY_FX
1078 }
1079 }
1080
1084
1085release:
1087 {
1089
1091 data.addr = dst_map.data;
1092
1093 texture_level = dst_sub_resource_idx % dst_texture->
level_count;
1094
1097 dst_box, dst_map.row_pitch, dst_map.slice_pitch, dst_texture, texture_level,
1099
1102 }
1103
1104 if (upload)
1105 {
1107 }
1108 else
1109 {
1111 }
1112
1113 if (!same_sub_resource)
1116 {
1119 dst_texture->
swapchain->swapchain_ops->swapchain_frontbuffer_updated(dst_texture->
swapchain);
1120 }
1121 if (converted_texture)
1124
1126}
#define STRETCH_ROW(type)
static HRESULT surface_cpu_blt_compressed(const BYTE *src_data, BYTE *dst_data, UINT src_pitch, UINT dst_pitch, UINT update_w, UINT update_h, const struct wined3d_format *format, uint32_t flags, const struct wined3d_blt_fx *fx)
static struct wined3d_texture * surface_convert_format(struct wined3d_texture *src_texture, unsigned int sub_resource_idx, const struct wined3d_format *dst_format)
#define COPY_COLORKEY_FX(type)
static void get_color_masks(const struct wined3d_format *format, uint32_t *masks)
ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
const struct wined3d_format * wined3d_get_format(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id, unsigned int bind_flags)
const char * debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch)
#define memcpy(s1, s2, n)
#define memmove(s1, s2, n)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
struct wined3d_bo * buffer_object
struct wined3d_swapchain * swapchain
struct wined3d_texture::wined3d_texture_async async
#define WINEDDBLTFX_ROTATE270
#define WINED3D_BLT_DST_CKEY
#define WINED3D_BLT_SRC_CKEY
#define WINEDDBLTFX_NOTEARING
#define WINEDDBLTFX_MIRRORUPDOWN
#define WINEDDBLTFX_ROTATE90
#define WINED3DERR_NOTAVAILABLE
#define WINED3D_BLT_DST_CKEY_OVERRIDE
@ WINED3DFMT_B8G8R8A8_UNORM
#define WINEDDBLTFX_ZBUFFERBASEDEST
#define WINEDDBLTFX_ARITHSTRETCHY
#define WINEDDBLTFX_ROTATE180
#define WINEDDBLTFX_MIRRORLEFTRIGHT
static BOOL wined3d_format_is_typeless(const struct wined3d_format *format)
#define WINED3D_FORMAT_ATTR_HEIGHT_SCALE