After this there is one more set of patches to finish up the file saving functions, I split it into two to hopefully make it easier to review. :)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_24/d3dx9_24.spec | 6 +- dlls/d3dx9_25/d3dx9_25.spec | 6 +- dlls/d3dx9_26/d3dx9_26.spec | 6 +- dlls/d3dx9_27/d3dx9_27.spec | 6 +- dlls/d3dx9_28/d3dx9_28.spec | 6 +- dlls/d3dx9_29/d3dx9_29.spec | 6 +- dlls/d3dx9_30/d3dx9_30.spec | 6 +- dlls/d3dx9_31/d3dx9_31.spec | 6 +- dlls/d3dx9_32/d3dx9_32.spec | 6 +- dlls/d3dx9_33/d3dx9_33.spec | 6 +- dlls/d3dx9_34/d3dx9_34.spec | 6 +- dlls/d3dx9_35/d3dx9_35.spec | 6 +- dlls/d3dx9_36/d3dx9_36.spec | 6 +- dlls/d3dx9_36/tests/d3dx9_test_images.h | 151 +++++++++++++ dlls/d3dx9_36/tests/surface.c | 132 ------------ dlls/d3dx9_36/tests/texture.c | 7 - dlls/d3dx9_36/tests/volume.c | 269 ++++++++++++++++++++++++ dlls/d3dx9_36/volume.c | 25 +++ dlls/d3dx9_37/d3dx9_37.spec | 6 +- dlls/d3dx9_38/d3dx9_38.spec | 6 +- dlls/d3dx9_39/d3dx9_39.spec | 6 +- dlls/d3dx9_40/d3dx9_40.spec | 6 +- dlls/d3dx9_41/d3dx9_41.spec | 6 +- dlls/d3dx9_42/d3dx9_42.spec | 6 +- dlls/d3dx9_43/d3dx9_43.spec | 6 +- include/d3dx9tex.h | 3 + 26 files changed, 508 insertions(+), 199 deletions(-)
diff --git a/dlls/d3dx9_24/d3dx9_24.spec b/dlls/d3dx9_24/d3dx9_24.spec index ead018c7ae0..1c15a450ecf 100644 --- a/dlls/d3dx9_24/d3dx9_24.spec +++ b/dlls/d3dx9_24/d3dx9_24.spec @@ -274,9 +274,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_25/d3dx9_25.spec b/dlls/d3dx9_25/d3dx9_25.spec index d1087a2d4cc..6fa19bf30af 100644 --- a/dlls/d3dx9_25/d3dx9_25.spec +++ b/dlls/d3dx9_25/d3dx9_25.spec @@ -274,9 +274,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_26/d3dx9_26.spec b/dlls/d3dx9_26/d3dx9_26.spec index 0769e250958..3c1eadbe7a5 100644 --- a/dlls/d3dx9_26/d3dx9_26.spec +++ b/dlls/d3dx9_26/d3dx9_26.spec @@ -278,9 +278,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_27/d3dx9_27.spec b/dlls/d3dx9_27/d3dx9_27.spec index 0769e250958..3c1eadbe7a5 100644 --- a/dlls/d3dx9_27/d3dx9_27.spec +++ b/dlls/d3dx9_27/d3dx9_27.spec @@ -278,9 +278,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_28/d3dx9_28.spec b/dlls/d3dx9_28/d3dx9_28.spec index 19871f33abc..48c143b97b0 100644 --- a/dlls/d3dx9_28/d3dx9_28.spec +++ b/dlls/d3dx9_28/d3dx9_28.spec @@ -283,9 +283,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_29/d3dx9_29.spec b/dlls/d3dx9_29/d3dx9_29.spec index 19871f33abc..48c143b97b0 100644 --- a/dlls/d3dx9_29/d3dx9_29.spec +++ b/dlls/d3dx9_29/d3dx9_29.spec @@ -283,9 +283,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_30/d3dx9_30.spec b/dlls/d3dx9_30/d3dx9_30.spec index 19871f33abc..48c143b97b0 100644 --- a/dlls/d3dx9_30/d3dx9_30.spec +++ b/dlls/d3dx9_30/d3dx9_30.spec @@ -283,9 +283,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_31/d3dx9_31.spec b/dlls/d3dx9_31/d3dx9_31.spec index 38714f68127..6bc1471da2d 100644 --- a/dlls/d3dx9_31/d3dx9_31.spec +++ b/dlls/d3dx9_31/d3dx9_31.spec @@ -280,9 +280,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_32/d3dx9_32.spec b/dlls/d3dx9_32/d3dx9_32.spec index ed8efad9c6c..04abf61ee9d 100644 --- a/dlls/d3dx9_32/d3dx9_32.spec +++ b/dlls/d3dx9_32/d3dx9_32.spec @@ -285,9 +285,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_33/d3dx9_33.spec b/dlls/d3dx9_33/d3dx9_33.spec index ed8efad9c6c..04abf61ee9d 100644 --- a/dlls/d3dx9_33/d3dx9_33.spec +++ b/dlls/d3dx9_33/d3dx9_33.spec @@ -285,9 +285,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_34/d3dx9_34.spec b/dlls/d3dx9_34/d3dx9_34.spec index ed8efad9c6c..04abf61ee9d 100644 --- a/dlls/d3dx9_34/d3dx9_34.spec +++ b/dlls/d3dx9_34/d3dx9_34.spec @@ -285,9 +285,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_35/d3dx9_35.spec b/dlls/d3dx9_35/d3dx9_35.spec index ed8efad9c6c..04abf61ee9d 100644 --- a/dlls/d3dx9_35/d3dx9_35.spec +++ b/dlls/d3dx9_35/d3dx9_35.spec @@ -285,9 +285,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_36/d3dx9_36.spec +++ b/dlls/d3dx9_36/d3dx9_36.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_36/tests/d3dx9_test_images.h b/dlls/d3dx9_36/tests/d3dx9_test_images.h index 68d4152d542..f79e9f68894 100644 --- a/dlls/d3dx9_36/tests/d3dx9_test_images.h +++ b/dlls/d3dx9_36/tests/d3dx9_test_images.h @@ -23,6 +23,55 @@ #define COBJMACROS #include "d3dx9tex.h"
+/* + * MAKE_DDHRESULT is first defined in d3dx9.h, with the same definition as the + * one in ddraw.h. + */ +#ifdef MAKE_DDHRESULT +#undef MAKE_DDHRESULT +#endif +#include "ddraw.h" + +/* dds_pixel_format.flags */ +#define DDS_PF_ALPHA 0x00000001 +#define DDS_PF_ALPHA_ONLY 0x00000002 +#define DDS_PF_FOURCC 0x00000004 +#define DDS_PF_INDEXED 0x00000020 +#define DDS_PF_RGB 0x00000040 +#define DDS_PF_LUMINANCE 0x00020000 +#define DDS_PF_BUMPLUMINANCE 0x00040000 +#define DDS_PF_BUMPDUDV 0x00080000 + +struct dds_pixel_format +{ + DWORD size; + DWORD flags; + DWORD fourcc; + DWORD bpp; + DWORD rmask; + DWORD gmask; + DWORD bmask; + DWORD amask; +}; + +struct dds_header +{ + DWORD size; + DWORD flags; + DWORD height; + DWORD width; + DWORD pitch_or_linear_size; + DWORD depth; + DWORD miplevels; + DWORD reserved[11]; + struct dds_pixel_format pixel_format; + DWORD caps; + DWORD caps2; + DWORD caps3; + DWORD caps4; + DWORD reserved2; +}; + static const struct { uint32_t filter; @@ -806,6 +855,82 @@ static inline void check_image_info_(const char *file, uint32_t line, const D3DX image_file_format, info->ImageFileFormat); }
+#define check_dds_pixel_format_struct(pixel_format, expected_pixel_format, wine_todo) \ + check_dds_pixel_format_struct_(__FILE__, __LINE__, pixel_format, expected_pixel_format, wine_todo) +static inline void check_dds_pixel_format_struct_(const char *file, uint32_t line, const struct dds_pixel_format *pixel_format, + const struct dds_pixel_format *expected_pixel_format, BOOL wine_todo) +{ + BOOL matched; + + matched = !memcmp(expected_pixel_format, pixel_format, sizeof(*pixel_format)); + todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds pixel format values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && pixel_format->flags != expected_pixel_format->flags) + ok_(file, line)(pixel_format->flags == expected_pixel_format->flags, "Unexpected DDS pixel format flags %#lx.\n", + pixel_format->flags); + todo_wine_if(wine_todo && pixel_format->fourcc != expected_pixel_format->fourcc) + ok_(file, line)(pixel_format->fourcc == expected_pixel_format->fourcc, "Unexpected DDS pixel format fourcc %#lx.\n", + pixel_format->fourcc); + todo_wine_if(wine_todo && pixel_format->bpp != expected_pixel_format->bpp) + ok_(file, line)(pixel_format->bpp == expected_pixel_format->bpp, "Unexpected DDS pixel format bpp %#lx.\n", + pixel_format->bpp); + todo_wine_if(wine_todo && pixel_format->rmask != expected_pixel_format->rmask) + ok_(file, line)(pixel_format->rmask == expected_pixel_format->rmask, "Unexpected DDS pixel format rmask %#lx.\n", + pixel_format->rmask); + todo_wine_if(wine_todo && pixel_format->gmask != expected_pixel_format->gmask) + ok_(file, line)(pixel_format->gmask == expected_pixel_format->gmask, "Unexpected DDS pixel format gmask %#lx.\n", + pixel_format->gmask); + todo_wine_if(wine_todo && pixel_format->bmask != expected_pixel_format->bmask) + ok_(file, line)(pixel_format->bmask == expected_pixel_format->bmask, "Unexpected DDS pixel format bmask %#lx.\n", + pixel_format->bmask); + todo_wine_if(wine_todo && pixel_format->amask != expected_pixel_format->amask) + ok_(file, line)(pixel_format->amask == expected_pixel_format->amask, "Unexpected DDS pixel format amask %#lx.\n", + pixel_format->amask); +} + +#define check_dds_header(header, flags, height, width, pitch, depth, mip_levels, pixel_format, caps, caps2, wine_todo) \ + check_dds_header_(__FILE__, __LINE__, header, flags, height, width, pitch, depth, mip_levels, pixel_format, \ + caps, caps2, wine_todo) +static inline void check_dds_header_(const char *file, uint32_t line, const struct dds_header *header, uint32_t flags, + uint32_t height, uint32_t width, uint32_t pitch, uint32_t depth, uint32_t mip_levels, + const struct dds_pixel_format *pixel_format, uint32_t caps, uint32_t caps2, BOOL wine_todo) +{ + const struct dds_header expected_header = { sizeof(*header), flags, height, width, pitch, depth, mip_levels, { 0 }, + *pixel_format, caps, caps2, 0, 0, 0 }; + BOOL matched; + + matched = !memcmp(&expected_header, header, sizeof(*header)); + todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds header values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && header->flags != flags) + ok_(file, line)(header->flags == flags, "Unexpected DDS header flags %#lx.\n", header->flags); + todo_wine_if(wine_todo && header->width != width) + ok_(file, line)(header->width == width, "Unexpected DDS header width %#lx.\n", header->width); + todo_wine_if(wine_todo && header->height != height) + ok_(file, line)(header->height == height, "Unexpected DDS header height %#lx.\n", header->height); + todo_wine_if(wine_todo && header->pitch_or_linear_size != pitch) + ok_(file, line)(header->pitch_or_linear_size == pitch, "Unexpected DDS header pitch %#lx.\n", + header->pitch_or_linear_size); + todo_wine_if(wine_todo && header->depth != depth) + ok_(file, line)(header->depth == depth, "Unexpected DDS header depth %#lx.\n", header->depth); + todo_wine_if(wine_todo && header->miplevels != mip_levels) + ok_(file, line)(header->miplevels == mip_levels, "Unexpected DDS header mip levels %#lx.\n", header->miplevels); + ok_(file, line)(!memcmp(header->reserved, expected_header.reserved, sizeof(header->reserved)), + "Unexpected values in DDS header reserved field."); + check_dds_pixel_format_struct(&header->pixel_format, pixel_format, FALSE); + todo_wine_if(wine_todo && header->caps != caps) + ok_(file, line)(header->caps == caps, "Unexpected DDS header caps %#lx.\n", header->caps); + todo_wine_if(wine_todo && header->caps2 != caps2) + ok_(file, line)(header->caps2 == caps2, "Unexpected DDS header caps2 %#lx.\n", header->caps2); + ok_(file, line)(!header->caps3, "Unexpected DDS header caps3 %#lx.\n", header->caps3); + ok_(file, line)(!header->caps4, "Unexpected DDS header caps4 %#lx.\n", header->caps4); + ok_(file, line)(!header->reserved2, "Unexpected DDS header reserved2 %#lx.\n", header->reserved2); +} + struct volume_readback { IDirect3DVolume9 *volume; @@ -897,6 +1022,32 @@ exit: } }
+static inline BOOL compare_uint(uint32_t x, uint32_t y, uint32_t max_diff) +{ + uint32_t diff = x > y ? x - y : y - x; + + return diff <= max_diff; +} + +static inline BOOL compare_color_4bpp(uint32_t c1, uint32_t c2, uint8_t max_diff) +{ + return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) + && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff) + && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff) + && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); +} + +#define check_volume_readback_pixel_4bpp_diff(rb, x, y, z, color, max_diff, todo) \ + _check_volume_readback_pixel_4bpp_diff(__FILE__, __LINE__, rb, x, y, z, color, max_diff, todo) +static inline void _check_volume_readback_pixel_4bpp_diff(const char *file, uint32_t line, struct volume_readback *rb, + uint32_t x, uint32_t y, uint32_t z, uint32_t expected_color, uint32_t max_diff, BOOL todo) +{ + uint32_t color = get_volume_readback_color(rb, x, y, z); + + todo_wine_if(todo) ok_(file, line)(compare_color_4bpp(color, expected_color, max_diff), + "Got color 0x%08x, expected 0x%08x.\n", color, expected_color); +} + #define check_volume_readback_pixel_4bpp(rb, x, y, z, color, todo) \ _check_volume_readback_pixel_4bpp(__FILE__, __LINE__, rb, x, y, z, color, todo) static inline void _check_volume_readback_pixel_4bpp(const char *file, uint32_t line, struct volume_readback *rb, diff --git a/dlls/d3dx9_36/tests/surface.c b/dlls/d3dx9_36/tests/surface.c index 2b24555c8c8..38e328f58c5 100644 --- a/dlls/d3dx9_36/tests/surface.c +++ b/dlls/d3dx9_36/tests/surface.c @@ -26,22 +26,6 @@ #include <stdint.h> #include "d3dx9_test_images.h"
-/* - * MAKE_DDHRESULT is first defined in d3dx9.h, with the same definition as the - * one in ddraw.h. - */ -#ifdef MAKE_DDHRESULT -#undef MAKE_DDHRESULT -#endif -#include "ddraw.h" - -static BOOL compare_uint(uint32_t x, uint32_t y, uint32_t max_diff) -{ - uint32_t diff = x > y ? x - y : y - x; - - return diff <= max_diff; -} - static BOOL compare_float(float f, float g, uint32_t ulps) { int32_t x = *(int32_t *)&f; @@ -149,46 +133,6 @@ static HRESULT create_file(const char *filename, const unsigned char *data, cons return D3DERR_INVALIDCALL; }
-/* dds_pixel_format.flags */ -#define DDS_PF_ALPHA 0x00000001 -#define DDS_PF_ALPHA_ONLY 0x00000002 -#define DDS_PF_FOURCC 0x00000004 -#define DDS_PF_INDEXED 0x00000020 -#define DDS_PF_RGB 0x00000040 -#define DDS_PF_LUMINANCE 0x00020000 -#define DDS_PF_BUMPLUMINANCE 0x00040000 -#define DDS_PF_BUMPDUDV 0x00080000 - -struct dds_pixel_format -{ - DWORD size; - DWORD flags; - DWORD fourcc; - DWORD bpp; - DWORD rmask; - DWORD gmask; - DWORD bmask; - DWORD amask; -}; - -struct dds_header -{ - DWORD size; - DWORD flags; - DWORD height; - DWORD width; - DWORD pitch_or_linear_size; - DWORD depth; - DWORD miplevels; - DWORD reserved[11]; - struct dds_pixel_format pixel_format; - DWORD caps; - DWORD caps2; - DWORD caps3; - DWORD caps4; - DWORD reserved2; -}; - /* fills dds_header with reasonable default values */ static void fill_dds_header(struct dds_header *header) { @@ -3425,82 +3369,6 @@ static void test_D3DXLoadSurface(IDirect3DDevice9 *device) if(testbitmap_ok) DeleteFileA("testbitmap.bmp"); }
-#define check_dds_pixel_format_struct(pixel_format, expected_pixel_format, wine_todo) \ - check_dds_pixel_format_struct_(__FILE__, __LINE__, pixel_format, expected_pixel_format, wine_todo) -static void check_dds_pixel_format_struct_(const char *file, uint32_t line, const struct dds_pixel_format *pixel_format, - const struct dds_pixel_format *expected_pixel_format, BOOL wine_todo) -{ - BOOL matched; - - matched = !memcmp(expected_pixel_format, pixel_format, sizeof(*pixel_format)); - todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds pixel format values.\n"); - if (matched) - return; - - todo_wine_if(wine_todo && pixel_format->flags != expected_pixel_format->flags) - ok_(file, line)(pixel_format->flags == expected_pixel_format->flags, "Unexpected DDS pixel format flags %#lx.\n", - pixel_format->flags); - todo_wine_if(wine_todo && pixel_format->fourcc != expected_pixel_format->fourcc) - ok_(file, line)(pixel_format->fourcc == expected_pixel_format->fourcc, "Unexpected DDS pixel format fourcc %#lx.\n", - pixel_format->fourcc); - todo_wine_if(wine_todo && pixel_format->bpp != expected_pixel_format->bpp) - ok_(file, line)(pixel_format->bpp == expected_pixel_format->bpp, "Unexpected DDS pixel format bpp %#lx.\n", - pixel_format->bpp); - todo_wine_if(wine_todo && pixel_format->rmask != expected_pixel_format->rmask) - ok_(file, line)(pixel_format->rmask == expected_pixel_format->rmask, "Unexpected DDS pixel format rmask %#lx.\n", - pixel_format->rmask); - todo_wine_if(wine_todo && pixel_format->gmask != expected_pixel_format->gmask) - ok_(file, line)(pixel_format->gmask == expected_pixel_format->gmask, "Unexpected DDS pixel format gmask %#lx.\n", - pixel_format->gmask); - todo_wine_if(wine_todo && pixel_format->bmask != expected_pixel_format->bmask) - ok_(file, line)(pixel_format->bmask == expected_pixel_format->bmask, "Unexpected DDS pixel format bmask %#lx.\n", - pixel_format->bmask); - todo_wine_if(wine_todo && pixel_format->amask != expected_pixel_format->amask) - ok_(file, line)(pixel_format->amask == expected_pixel_format->amask, "Unexpected DDS pixel format amask %#lx.\n", - pixel_format->amask); -} - -#define check_dds_header(header, flags, height, width, pitch, depth, mip_levels, pixel_format, caps, caps2, wine_todo) \ - check_dds_header_(__FILE__, __LINE__, header, flags, height, width, pitch, depth, mip_levels, pixel_format, \ - caps, caps2, wine_todo) -static void check_dds_header_(const char *file, uint32_t line, const struct dds_header *header, uint32_t flags, - uint32_t height, uint32_t width, uint32_t pitch, uint32_t depth, uint32_t mip_levels, - const struct dds_pixel_format *pixel_format, uint32_t caps, uint32_t caps2, BOOL wine_todo) -{ - const struct dds_header expected_header = { sizeof(*header), flags, height, width, pitch, depth, mip_levels, { 0 }, - *pixel_format, caps, caps2, 0, 0, 0 }; - BOOL matched; - - matched = !memcmp(&expected_header, header, sizeof(*header)); - todo_wine_if(wine_todo) ok_(file, line)(matched, "Got unexpected dds header values.\n"); - if (matched) - return; - - todo_wine_if(wine_todo && header->flags != flags) - ok_(file, line)(header->flags == flags, "Unexpected DDS header flags %#lx.\n", header->flags); - todo_wine_if(wine_todo && header->width != width) - ok_(file, line)(header->width == width, "Unexpected DDS header width %#lx.\n", header->width); - todo_wine_if(wine_todo && header->height != height) - ok_(file, line)(header->height == height, "Unexpected DDS header height %#lx.\n", header->height); - todo_wine_if(wine_todo && header->pitch_or_linear_size != pitch) - ok_(file, line)(header->pitch_or_linear_size == pitch, "Unexpected DDS header pitch %#lx.\n", - header->pitch_or_linear_size); - todo_wine_if(wine_todo && header->depth != depth) - ok_(file, line)(header->depth == depth, "Unexpected DDS header depth %#lx.\n", header->depth); - todo_wine_if(wine_todo && header->miplevels != mip_levels) - ok_(file, line)(header->miplevels == mip_levels, "Unexpected DDS header mip levels %#lx.\n", header->miplevels); - ok_(file, line)(!memcmp(header->reserved, expected_header.reserved, sizeof(header->reserved)), - "Unexpected values in DDS header reserved field."); - check_dds_pixel_format_struct(&header->pixel_format, pixel_format, FALSE); - todo_wine_if(wine_todo && header->caps != caps) - ok_(file, line)(header->caps == caps, "Unexpected DDS header caps %#lx.\n", header->caps); - todo_wine_if(wine_todo && header->caps2 != caps2) - ok_(file, line)(header->caps2 == caps2, "Unexpected DDS header caps2 %#lx.\n", header->caps2); - ok_(file, line)(!header->caps3, "Unexpected DDS header caps3 %#lx.\n", header->caps3); - ok_(file, line)(!header->caps4, "Unexpected DDS header caps4 %#lx.\n", header->caps4); - ok_(file, line)(!header->reserved2, "Unexpected DDS header reserved2 %#lx.\n", header->reserved2); -} - #define DDS_FILE_HEADER_SIZE (sizeof(uint32_t) + sizeof(struct dds_header)) #define PALETTED_DDS_FILE_HEADER_SIZE (DDS_FILE_HEADER_SIZE + (sizeof(PALETTEENTRY) * 256)) static void test_save_surface_to_dds(IDirect3DDevice9 *device) diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index ce7f6d7056f..ca0069feee3 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -168,13 +168,6 @@ static inline void check_texture_mip_levels_(uint32_t line, IDirect3DBaseTexture mip_levels, expected_mip_levels); }
-static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) -{ - unsigned int diff = x > y ? x - y : y - x; - - return diff <= max_diff; -} - static BOOL compare_color(DWORD c1, DWORD c2, BYTE max_diff) { return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) diff --git a/dlls/d3dx9_36/tests/volume.c b/dlls/d3dx9_36/tests/volume.c index d7529eb486c..eed356be29e 100644 --- a/dlls/d3dx9_36/tests/volume.c +++ b/dlls/d3dx9_36/tests/volume.c @@ -392,6 +392,274 @@ static void test_D3DXLoadVolumeFromFileInMemory(IDirect3DDevice9 *device) IDirect3DVolumeTexture9_Release(volume_texture); }
+static void set_vec3(D3DXVECTOR3 *v, float x, float y, float z) +{ + v->x = x; + v->y = y; + v->z = z; +} + +static const D3DXVECTOR4 quadrant_color[] = { + { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, +}; + +static void WINAPI fill_func_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord, + const D3DXVECTOR3 *texelsize, void *data) +{ + D3DXVECTOR3 vec = *texcoord; + uint32_t idx; + + if (data) + { + *value = *(D3DXVECTOR4 *)data; + return; + } + + set_vec3(&vec, (vec.x / texelsize->x) - 0.5f, (vec.y / texelsize->y) - 0.5f, (vec.z / texelsize->z) - 0.5f); + if (vec.x < 8.0f) + idx = vec.y < 8.0f ? 0 : 2; + else + idx = vec.y < 8.0f ? 1 : 3; + idx += vec.z < 1.0f ? 0 : 4; + + *value = quadrant_color[idx]; +} + +#define check_volume_readback_slice_quadrants(rb, width, height, slice, expected, max_diff) \ + _check_volume_readback_slice_quadrants(__LINE__, rb, width, height, slice, expected, max_diff) +static inline void _check_volume_readback_slice_quadrants(unsigned int line, struct volume_readback *rb, + uint32_t width, uint32_t height, uint32_t slice, const uint32_t *expected, uint8_t max_diff) +{ + /* Order is: top left, top right, bottom left, bottom right. */ + _check_volume_readback_pixel_4bpp_diff(__FILE__, line, rb, 0, 0, slice, expected[0], max_diff, FALSE); + _check_volume_readback_pixel_4bpp_diff(__FILE__, line, rb, (width - 1), 0, slice, expected[1], max_diff, FALSE); + _check_volume_readback_pixel_4bpp_diff(__FILE__, line, rb, 0, (height - 1), slice, expected[2], max_diff, FALSE); + _check_volume_readback_pixel_4bpp_diff(__FILE__, line, rb, (width - 1), (height - 1), slice, expected[3], max_diff, + FALSE); +} + +static void test_d3dx_save_volume_to_file(IDirect3DDevice9 *device) +{ + static const struct dds_pixel_format d3dfmt_a8r8g8b8_pf = { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; + static const uint32_t front_expected[] = { 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff }; + static const uint32_t empty_expected[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + static const uint32_t back_expected[] = { 0xffffffff, 0xff0000ff, 0xffff0000, 0xff00ff00 }; + static const struct + { + D3DXIMAGE_FILEFORMAT format; + const char *name; + const char *suffix; + } tests[] = + { + { D3DXIFF_BMP, "D3DXIFF_BMP", "bmp" }, + { D3DXIFF_JPG, "D3DXIFF_JPG", "jpg" }, + { D3DXIFF_TGA, "D3DXIFF_TGA", "tga" }, + { D3DXIFF_PNG, "D3DXIFF_PNG", "png" }, + { D3DXIFF_DDS, "D3DXIFF_DDS", "dds" }, + }; + struct + { + DWORD magic; + struct dds_header header; + BYTE *data; + } *dds; + const D3DXVECTOR4 clear_val = { 0.0f, 0.0f, 0.0f, 0.0f }; + IDirect3DVolumeTexture9 *volume_texture; + struct volume_readback volume_rb; + ID3DXBuffer *buffer = NULL; + IDirect3DVolume9 *volume; + WCHAR name_buf_w[64]; + D3DXIMAGE_INFO info; + char name_buf_a[64]; + unsigned int i, j; + D3DBOX box; + HRESULT hr; + + if (!strcmp(winetest_platform, "wine")) + { + skip("Skipping D3DXSaveVolumeToFile{A,W,InMemory}() tests.\n"); + return; + } + + hr = IDirect3DDevice9_CreateVolumeTexture(device, 16, 16, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, + &volume_texture, NULL); + if (FAILED(hr)) + { + skip("Failed to create volume texture.\n"); + return; + } + + hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume); + + hr = D3DXSaveVolumeToFileInMemory(&buffer, D3DXIFF_DDS, volume, NULL, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + dds = ID3DXBuffer_GetBufferPointer(buffer); + check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_DEPTH | DDSD_PIXELFORMAT, 16, 16, 0, + 2, 0, &d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, DDSCAPS2_VOLUME, FALSE); + ID3DXBuffer_Release(buffer); + + /* + * Save with a box that has a depth of 1. This results in a DDS header + * without any depth/volume flags set, even though we're saving a volume. + */ + set_box(&box, 0, 0, 16, 16, 1, 2); + hr = D3DXSaveVolumeToFileInMemory(&buffer, D3DXIFF_DDS, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + dds = ID3DXBuffer_GetBufferPointer(buffer); + check_dds_header(&dds->header, DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT, 16, 16, 0, 0, 0, + &d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE); + ID3DXBuffer_Release(buffer); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("File format %u (%s)", i, tests[i].name); + + wsprintfA(name_buf_a, "save_volume_a.%s", tests[i].suffix); + wsprintfW(name_buf_w, L"save_volume_w.%S", tests[i].suffix); + + /* + * Test twice, first with a box that has a depth of 2, then second + * with a box that has a depth of 1. + */ + for (j = 0; j < 2; ++j) + { + winetest_push_context("%u", j); + hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + set_box(&box, 0, 0, 16, 16, j, 2); + hr = D3DXSaveVolumeToFileA(name_buf_a, tests[i].format, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXSaveVolumeToFileW(name_buf_w, tests[i].format, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXSaveVolumeToFileInMemory(&buffer, tests[i].format, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + /* ASCII string. */ + hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, (void *)&clear_val); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + memset(&info, 0, sizeof(info)); + hr = D3DXLoadVolumeFromFileA(volume, NULL, NULL, name_buf_a, NULL, D3DX_FILTER_NONE, 0, &info); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + get_texture_volume_readback(device, volume_texture, 0, &volume_rb); + if (tests[i].format == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 16, 16, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, back_expected, 0); + } + else + { + check_image_info(&info, 16, 16, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, 0); + } + } + else + { + const D3DFORMAT expected_fmt = (tests[i].format == D3DXIFF_JPG) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8; + const uint8_t max_diff = (tests[i].format == D3DXIFF_JPG) ? 40 : 0; + + check_image_info(&info, 16, 16, 1, 1, expected_fmt, D3DRTYPE_TEXTURE, tests[i].format, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, !j ? front_expected : back_expected, + max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, max_diff); + } + release_volume_readback(&volume_rb); + + /* Wide string. */ + hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, (void *)&clear_val); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + memset(&info, 0, sizeof(info)); + hr = D3DXLoadVolumeFromFileW(volume, NULL, NULL, name_buf_w, NULL, D3DX_FILTER_NONE, 0, &info); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + get_texture_volume_readback(device, volume_texture, 0, &volume_rb); + if (tests[i].format == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 16, 16, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, back_expected, 0); + } + else + { + check_image_info(&info, 16, 16, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, 0); + } + } + else + { + const D3DFORMAT expected_fmt = (tests[i].format == D3DXIFF_JPG) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8; + const uint8_t max_diff = (tests[i].format == D3DXIFF_JPG) ? 40 : 0; + + check_image_info(&info, 16, 16, 1, 1, expected_fmt, D3DRTYPE_TEXTURE, tests[i].format, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, !j ? front_expected : back_expected, + max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, max_diff); + } + release_volume_readback(&volume_rb); + + /* File in memory. */ + memset(&info, 0, sizeof(info)); + hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, ID3DXBuffer_GetBufferPointer(buffer), + ID3DXBuffer_GetBufferSize(buffer), NULL, D3DX_FILTER_NONE, 0, &info); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + get_texture_volume_readback(device, volume_texture, 0, &volume_rb); + if (tests[i].format == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 16, 16, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, back_expected, 0); + } + else + { + check_image_info(&info, 16, 16, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, 0); + } + } + else + { + const D3DFORMAT expected_fmt = (tests[i].format == D3DXIFF_JPG) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8; + const uint8_t max_diff = (tests[i].format == D3DXIFF_JPG) ? 40 : 0; + + check_image_info(&info, 16, 16, 1, 1, expected_fmt, D3DRTYPE_TEXTURE, tests[i].format, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, !j ? front_expected : back_expected, + max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, max_diff); + } + release_volume_readback(&volume_rb); + + ID3DXBuffer_Release(buffer); + DeleteFileA(name_buf_a); + DeleteFileW(name_buf_w); + winetest_pop_context(); + } + + winetest_pop_context(); + } + + IDirect3DVolume9_Release(volume); + IDirect3DVolumeTexture9_Release(volume_texture); +} + START_TEST(volume) { HWND wnd; @@ -428,6 +696,7 @@ START_TEST(volume)
test_D3DXLoadVolumeFromMemory(device); test_D3DXLoadVolumeFromFileInMemory(device); + test_d3dx_save_volume_to_file(device);
IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d); diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index e3444a063c7..14f6bdbfc33 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -279,3 +279,28 @@ HRESULT WINAPI D3DXLoadVolumeFromVolume(IDirect3DVolume9 *dst_volume, const PALE IDirect3DVolume9_UnlockBox(src_volume); return hr; } + +HRESULT WINAPI D3DXSaveVolumeToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format, + IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) +{ + FIXME("dst_buffer %p, file_format %#x, src_volume %p, src_palette %p, src_box %p, stub.\n", + dst_buffer, file_format, src_volume, src_palette, src_box); + + return E_NOTIMPL; +} + +HRESULT WINAPI D3DXSaveVolumeToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format, + IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) +{ + FIXME("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p stub.\n", + wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box); + return E_NOTIMPL; +} + +HRESULT WINAPI D3DXSaveVolumeToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format, + IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) +{ + FIXME("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p stub.\n", + wine_dbgstr_w(dst_filename), file_format, src_volume, src_palette, src_box); + return E_NOTIMPL; +} diff --git a/dlls/d3dx9_37/d3dx9_37.spec b/dlls/d3dx9_37/d3dx9_37.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_37/d3dx9_37.spec +++ b/dlls/d3dx9_37/d3dx9_37.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_38/d3dx9_38.spec b/dlls/d3dx9_38/d3dx9_38.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_38/d3dx9_38.spec +++ b/dlls/d3dx9_38/d3dx9_38.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_39/d3dx9_39.spec b/dlls/d3dx9_39/d3dx9_39.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_39/d3dx9_39.spec +++ b/dlls/d3dx9_39/d3dx9_39.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_40/d3dx9_40.spec b/dlls/d3dx9_40/d3dx9_40.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_40/d3dx9_40.spec +++ b/dlls/d3dx9_40/d3dx9_40.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_41/d3dx9_41.spec b/dlls/d3dx9_41/d3dx9_41.spec index 13405ad8909..e4304261fa3 100644 --- a/dlls/d3dx9_41/d3dx9_41.spec +++ b/dlls/d3dx9_41/d3dx9_41.spec @@ -287,9 +287,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_42/d3dx9_42.spec b/dlls/d3dx9_42/d3dx9_42.spec index 1f4cf67c7b2..b857564b2b3 100644 --- a/dlls/d3dx9_42/d3dx9_42.spec +++ b/dlls/d3dx9_42/d3dx9_42.spec @@ -280,9 +280,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/dlls/d3dx9_43/d3dx9_43.spec b/dlls/d3dx9_43/d3dx9_43.spec index 1f4cf67c7b2..b857564b2b3 100644 --- a/dlls/d3dx9_43/d3dx9_43.spec +++ b/dlls/d3dx9_43/d3dx9_43.spec @@ -280,9 +280,9 @@ @ stdcall D3DXSaveTextureToFileA(str long ptr ptr) @ stdcall D3DXSaveTextureToFileInMemory(ptr long ptr ptr) @ stdcall D3DXSaveTextureToFileW(wstr long ptr ptr) -@ stub D3DXSaveVolumeToFileA(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) -@ stub D3DXSaveVolumeToFileW(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileA(str long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileInMemory(ptr long ptr ptr ptr) +@ stdcall D3DXSaveVolumeToFileW(wstr long ptr ptr ptr) @ stub D3DXSimplifyMesh(ptr ptr ptr ptr long long ptr) @ stdcall D3DXSphereBoundProbe(ptr float ptr ptr) @ stub D3DXSplitMesh(ptr ptr long long ptr ptr ptr ptr ptr) diff --git a/include/d3dx9tex.h b/include/d3dx9tex.h index 3883165c67e..fa690107650 100644 --- a/include/d3dx9tex.h +++ b/include/d3dx9tex.h @@ -181,6 +181,9 @@ HRESULT WINAPI D3DXLoadVolumeFromMemory(struct IDirect3DVolume9 *destvolume, D3DFORMAT srcformat, UINT srcrowpitch, UINT srcslicepitch, const PALETTEENTRY *srcpalette, const D3DBOX *srcbox, DWORD filter, D3DCOLOR colorkey);
+HRESULT WINAPI D3DXSaveVolumeToFileInMemory(struct ID3DXBuffer **destbuffer, D3DXIMAGE_FILEFORMAT destformat, + struct IDirect3DVolume9 *srcvolume, const PALETTEENTRY *srcpalette, const D3DBOX *srcbox); + HRESULT WINAPI D3DXSaveVolumeToFileA(const char *destfile, D3DXIMAGE_FILEFORMAT destformat, struct IDirect3DVolume9 *srcvolume, const PALETTEENTRY *srcpalette, const D3DBOX *srcbox); HRESULT WINAPI D3DXSaveVolumeToFileW(const WCHAR *destfile, D3DXIMAGE_FILEFORMAT destformat,
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/d3dx9_private.h | 3 + dlls/d3dx9_36/surface.c | 13 +++- dlls/d3dx9_36/tests/volume.c | 6 -- dlls/d3dx9_36/volume.c | 127 +++++++++++++++++++++++++++++++--- 4 files changed, 132 insertions(+), 17 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index 6a9b3e12b7b..7da9f9dd788 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -316,6 +316,9 @@ HRESULT lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLO IDirect3DSurface9 **temp_surface, BOOL write); HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, IDirect3DSurface9 *temp_surface, BOOL update); +HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, + D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer); +const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format); HRESULT d3dx_pixels_init(const void *data, uint32_t row_pitch, uint32_t slice_pitch, const PALETTEENTRY *palette, enum d3dx_pixel_format_id format, uint32_t left, uint32_t top, uint32_t right, uint32_t bottom, uint32_t front, uint32_t back, struct d3dx_pixels *pixels); diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c index 6b986055b06..3813461bc9b 100644 --- a/dlls/d3dx9_36/surface.c +++ b/dlls/d3dx9_36/surface.c @@ -508,6 +508,12 @@ static HRESULT d3dx_init_dds_header(struct dds_header *header, D3DRESOURCETYPE r header->height = size->height; header->width = size->width; header->caps = DDS_CAPS_TEXTURE; + if (size->depth > 1) + { + header->flags |= DDS_DEPTH; + header->depth = size->depth; + header->caps2 |= DDS_CAPS2_VOLUME; + } if (header->pixel_format.flags & DDS_PF_ALPHA || header->pixel_format.flags & DDS_PF_ALPHA_ONLY) header->caps |= DDSCAPS_ALPHA; if (header->pixel_format.flags & DDS_PF_INDEXED) @@ -799,7 +805,7 @@ static enum d3dx_pixel_format_id d3dx_get_closest_d3dx_pixel_format_id(const enu return (bestfmt) ? bestfmt->format : D3DX_PIXEL_FORMAT_COUNT; }
-static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, +HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, D3DXIMAGE_FILEFORMAT file_format, ID3DXBuffer **dst_buffer) { enum d3dx_pixel_format_id dst_format = src_fmt_desc->format; @@ -871,6 +877,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const }
dst_fmt_desc = get_d3dx_pixel_format_info(dst_format); + src_pixels->size.depth = (file_format == D3DXIFF_DDS) ? src_pixels->size.depth : 1; hr = d3dx_calculate_pixels_size(dst_format, src_pixels->size.width, src_pixels->size.height, &dst_row_pitch, &dst_slice_pitch); if (FAILED(hr)) @@ -884,7 +891,7 @@ static HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const uint32_t header_size;
header_size = is_index_format(dst_fmt_desc) ? sizeof(*header) + DDS_PALETTE_SIZE : sizeof(*header); - hr = D3DXCreateBuffer(dst_slice_pitch + header_size, &buffer); + hr = D3DXCreateBuffer((dst_slice_pitch * src_pixels->size.depth) + header_size, &buffer); if (FAILED(hr)) return hr;
@@ -1226,7 +1233,7 @@ static BOOL image_is_argb(IWICBitmapFrameDecode *frame, struct d3dx_image *image return FALSE; }
-static const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format) +const char *debug_d3dx_image_file_format(D3DXIMAGE_FILEFORMAT format) { switch (format) { diff --git a/dlls/d3dx9_36/tests/volume.c b/dlls/d3dx9_36/tests/volume.c index eed356be29e..14df6552c74 100644 --- a/dlls/d3dx9_36/tests/volume.c +++ b/dlls/d3dx9_36/tests/volume.c @@ -477,12 +477,6 @@ static void test_d3dx_save_volume_to_file(IDirect3DDevice9 *device) D3DBOX box; HRESULT hr;
- if (!strcmp(winetest_platform, "wine")) - { - skip("Skipping D3DXSaveVolumeToFile{A,W,InMemory}() tests.\n"); - return; - } - hr = IDirect3DDevice9_CreateVolumeTexture(device, 16, 16, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &volume_texture, NULL); if (FAILED(hr)) diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index 14f6bdbfc33..f2d498b7ba2 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -283,24 +283,135 @@ HRESULT WINAPI D3DXLoadVolumeFromVolume(IDirect3DVolume9 *dst_volume, const PALE HRESULT WINAPI D3DXSaveVolumeToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE_FILEFORMAT file_format, IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) { - FIXME("dst_buffer %p, file_format %#x, src_volume %p, src_palette %p, src_box %p, stub.\n", + const struct pixel_format_desc *src_fmt_desc; + RECT src_rect_aligned, src_rect_unaligned; + D3DBOX src_box_aligned, src_box_tmp; + struct d3dx_pixels src_pixels; + D3DLOCKED_BOX locked_box; + ID3DXBuffer *buffer; + D3DVOLUME_DESC desc; + HRESULT hr; + + TRACE("dst_buffer %p, file_format %#x, src_volume %p, src_palette %p, src_box %p.\n", dst_buffer, file_format, src_volume, src_palette, src_box);
- return E_NOTIMPL; + if (!dst_buffer || !src_volume || file_format > D3DXIFF_PFM) + return D3DERR_INVALIDCALL; + + *dst_buffer = NULL; + switch (file_format) + { + case D3DXIFF_HDR: + case D3DXIFF_PFM: + case D3DXIFF_PPM: + FIXME("File format %s is not supported yet.\n", debug_d3dx_image_file_format(file_format)); + return E_NOTIMPL; + + default: + break; + } + + IDirect3DVolume9_GetDesc(src_volume, &desc); + src_fmt_desc = get_format_info(desc.Format); + if (is_unknown_format(src_fmt_desc)) + return E_NOTIMPL; + + if (!src_palette && is_index_format(src_fmt_desc)) + { + FIXME("Default palette unimplemented.\n"); + return E_NOTIMPL; + } + + if (!src_box) + { + set_d3dbox(&src_box_tmp, 0, 0, desc.Width, desc.Height, 0, desc.Depth); + src_box = &src_box_tmp; + } + else + { + if (src_box->Left >= src_box->Right || src_box->Right > desc.Width + || src_box->Top >= src_box->Bottom || src_box->Bottom > desc.Height + || src_box->Front >= src_box->Back || src_box->Back > desc.Depth) + { + WARN("Invalid src_box specified.\n"); + return D3DERR_INVALIDCALL; + } + } + + get_aligned_rect(src_box->Left, src_box->Top, src_box->Right, src_box->Bottom, desc.Width, desc.Height, + src_fmt_desc, &src_rect_aligned); + set_d3dbox(&src_box_aligned, src_rect_aligned.left, src_rect_aligned.top, src_rect_aligned.right, + src_rect_aligned.bottom, src_box->Front, src_box->Back); + + hr = IDirect3DVolume9_LockBox(src_volume, &locked_box, &src_box_aligned, 0); + if (FAILED(hr)) + return hr; + + SetRect(&src_rect_unaligned, src_box->Left, src_box->Top, src_box->Right, src_box->Bottom); + OffsetRect(&src_rect_unaligned, -src_rect_aligned.left, -src_rect_aligned.top); + set_d3dx_pixels(&src_pixels, locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, src_palette, + (src_box_aligned.Right - src_box_aligned.Left), (src_box_aligned.Bottom - src_box_aligned.Top), + (src_box_aligned.Back - src_box_aligned.Front), &src_rect_unaligned); + + hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); + if (FAILED(hr)) + { + IDirect3DVolume9_UnlockBox(src_volume); + return hr; + } + + IDirect3DVolume9_UnlockBox(src_volume); + *dst_buffer = buffer; + return D3D_OK; }
HRESULT WINAPI D3DXSaveVolumeToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format, IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) { - FIXME("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p stub.\n", - wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box); - return E_NOTIMPL; + ID3DXBuffer *buffer; + WCHAR *filename; + int32_t len; + HRESULT hr; + + TRACE("(%s, %#x, %p, %p, %p): relay.\n", wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box); + + if (!dst_filename) + return D3DERR_INVALIDCALL; + + len = MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, NULL, 0); + filename = malloc(len * sizeof(WCHAR)); + if (!filename) + return E_OUTOFMEMORY; + MultiByteToWideChar(CP_ACP, 0, dst_filename, -1, filename, len); + + hr = D3DXSaveVolumeToFileInMemory(&buffer, file_format, src_volume, src_palette, src_box); + if (SUCCEEDED(hr)) + { + hr = write_buffer_to_file(filename, buffer); + ID3DXBuffer_Release(buffer); + } + + free(filename); + return hr; }
HRESULT WINAPI D3DXSaveVolumeToFileW(const WCHAR *dst_filename, D3DXIMAGE_FILEFORMAT file_format, IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) { - FIXME("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p stub.\n", - wine_dbgstr_w(dst_filename), file_format, src_volume, src_palette, src_box); - return E_NOTIMPL; + ID3DXBuffer *buffer; + HRESULT hr; + + TRACE("(%s, %#x, %p, %p, %p): relay.\n", wine_dbgstr_w(dst_filename), file_format, src_volume, src_palette, src_box); + + if (!dst_filename) + return D3DERR_INVALIDCALL; + + hr = D3DXSaveVolumeToFileInMemory(&buffer, file_format, src_volume, src_palette, src_box); + if (SUCCEEDED(hr)) + { + hr = write_buffer_to_file(dst_filename, buffer); + ID3DXBuffer_Release(buffer); + } + + return hr; }
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx9_36/tests/texture.c | 2 +- dlls/d3dx9_36/texture.c | 31 ++++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c index ca0069feee3..1c8ba0507b3 100644 --- a/dlls/d3dx9_36/tests/texture.c +++ b/dlls/d3dx9_36/tests/texture.c @@ -3230,7 +3230,6 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) return; }
- todo_wine { hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)volume_texture, NULL); ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); if (SUCCEEDED(hr)) @@ -3249,6 +3248,7 @@ static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device) ID3DXBuffer_Release(buffer); }
+ todo_wine { hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL); ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#lx, expected %#lx\n", hr, D3D_OK); if (SUCCEEDED(hr)) diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 719a2787445..4b4192dc8b6 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -1858,7 +1858,6 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE { HRESULT hr; D3DRESOURCETYPE type; - IDirect3DSurface9 *surface;
TRACE("dst_buffer %p, file_format %u, src_texture %p, src_palette %p.\n", dst_buffer, file_format, src_texture, src_palette); @@ -1876,21 +1875,35 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE { case D3DRTYPE_TEXTURE: case D3DRTYPE_CUBETEXTURE: + { + IDirect3DSurface9 *surface; + hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface); + if (SUCCEEDED(hr)) + { + hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL); + IDirect3DSurface9_Release(surface); + } break; + } + case D3DRTYPE_VOLUMETEXTURE: - FIXME("Volume textures aren't supported yet\n"); - return E_NOTIMPL; + { + IDirect3DVolume9 *volume; + + hr = IDirect3DVolumeTexture9_GetVolumeLevel((IDirect3DVolumeTexture9 *)src_texture, 0, &volume); + if (SUCCEEDED(hr)) + { + hr = D3DXSaveVolumeToFileInMemory(dst_buffer, file_format, volume, src_palette, NULL); + IDirect3DVolume9_Release(volume); + } + break; + } + default: return D3DERR_INVALIDCALL; }
- if (SUCCEEDED(hr)) - { - hr = D3DXSaveSurfaceToFileInMemory(dst_buffer, file_format, surface, src_palette, NULL); - IDirect3DSurface9_Release(surface); - } - return hr; }
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
IDirect3DVolumeTexture9_Release(volume_texture);
}
+static void set_vec3(D3DXVECTOR3 *v, float x, float y, float z) +{
- v->x = x;
- v->y = y;
- v->z = z;
+}
+static const D3DXVECTOR4 quadrant_color[] = {
Style comments, sorry: ```suggestion:-0+0 static const D3DXVECTOR4 quadrant_color[] = { ```
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
}
+static void set_vec3(D3DXVECTOR3 *v, float x, float y, float z) +{
- v->x = x;
- v->y = y;
- v->z = z;
+}
+static const D3DXVECTOR4 quadrant_color[] = {
- { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f },
- { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f },
+};
+static void WINAPI fill_func_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
const D3DXVECTOR3 *texelsize, void *data)
Indent the continuation by 8 spaces, like you did for the next function. Both `texcoord` and `texelsize` could use a name more in the current style (up to you, maybe just add underscores to separate words, or simplify the names like `coord` or `c` for the former and `size` for the latter)
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
wsprintfA(name_buf_a, "save_volume_a.%s", tests[i].suffix);
wsprintfW(name_buf_w, L"save_volume_w.%S", tests[i].suffix);
/*
* Test twice, first with a box that has a depth of 2, then second
* with a box that has a depth of 1.
*/
for (j = 0; j < 2; ++j)
{
winetest_push_context("%u", j);
hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, NULL);
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
set_box(&box, 0, 0, 16, 16, j, 2);
hr = D3DXSaveVolumeToFileA(name_buf_a, tests[i].format, volume, NULL, &box);
I think we want to use temporary filenames and paths here (e.g. `GetTempPathA/W` and `GetTempFileNameA/W`). In other words, the idea from asm.c's `create_file()`, not surface.c `create_file()` :sweat_smile:
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
- ID3DXBuffer_Release(buffer);
- for (i = 0; i < ARRAY_SIZE(tests); ++i)
- {
winetest_push_context("File format %u (%s)", i, tests[i].name);
wsprintfA(name_buf_a, "save_volume_a.%s", tests[i].suffix);
wsprintfW(name_buf_w, L"save_volume_w.%S", tests[i].suffix);
/*
* Test twice, first with a box that has a depth of 2, then second
* with a box that has a depth of 1.
*/
for (j = 0; j < 2; ++j)
{
winetest_push_context("%u", j);
We might want to mention "Depth %u" or similar.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
{
check_image_info(&info, 16, 16, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE);
check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, front_expected, 0);
check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, back_expected, 0);
}
else
{
check_image_info(&info, 16, 16, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE);
check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 0, back_expected, 0);
check_volume_readback_slice_quadrants(&volume_rb, 16, 16, 1, empty_expected, 0);
}
}
else
{
const D3DFORMAT expected_fmt = (tests[i].format == D3DXIFF_JPG) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8;
const uint8_t max_diff = (tests[i].format == D3DXIFF_JPG) ? 40 : 0;
I guess I shouldn't be surprised about JPEG compression quality, but 40 sounds like a lot... Does it actually look that different? Could we tweak some quality knob to improve things?
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/tests/volume.c:
- IDirect3DVolumeTexture9 *volume_texture;
- struct volume_readback volume_rb;
- ID3DXBuffer *buffer = NULL;
- IDirect3DVolume9 *volume;
- WCHAR name_buf_w[64];
- D3DXIMAGE_INFO info;
- char name_buf_a[64];
- unsigned int i, j;
- D3DBOX box;
- HRESULT hr;
- if (!strcmp(winetest_platform, "wine"))
- {
skip("Skipping D3DXSaveVolumeToFile{A,W,InMemory}() tests.\n");
return;
- }
Since we temporarily skip the test on Wine, maybe we should split the new test to its own commit at the start of the series.
Matteo Bruni (@Mystral) commented about include/d3dx9tex.h:
D3DFORMAT srcformat, UINT srcrowpitch, UINT srcslicepitch, const PALETTEENTRY *srcpalette, const D3DBOX *srcbox, DWORD filter, D3DCOLOR colorkey);
+HRESULT WINAPI D3DXSaveVolumeToFileInMemory(struct ID3DXBuffer **destbuffer, D3DXIMAGE_FILEFORMAT destformat,
struct IDirect3DVolume9 *srcvolume, const PALETTEENTRY *srcpalette, const D3DBOX *srcbox);
This would need to go with the test, if you follow my suggestion above. Or, it could also be a separate patch at the start of the series.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/volume.c:
- TRACE("dst_buffer %p, file_format %#x, src_volume %p, src_palette %p, src_box %p.\n", dst_buffer, file_format, src_volume, src_palette, src_box);
- return E_NOTIMPL;
- if (!dst_buffer || !src_volume || file_format > D3DXIFF_PFM)
return D3DERR_INVALIDCALL;
- *dst_buffer = NULL;
- switch (file_format)
- {
case D3DXIFF_HDR:
case D3DXIFF_PFM:
case D3DXIFF_PPM:
FIXME("File format %s is not supported yet.\n", debug_d3dx_image_file_format(file_format));
return E_NOTIMPL;
Do you know if native supports those formats in `D3DXSaveVolumeToFile*` in the first place? No reason it shouldn't, but you know...
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/volume.c:
- }
- get_aligned_rect(src_box->Left, src_box->Top, src_box->Right, src_box->Bottom, desc.Width, desc.Height,
src_fmt_desc, &src_rect_aligned);
- set_d3dbox(&src_box_aligned, src_rect_aligned.left, src_rect_aligned.top, src_rect_aligned.right,
src_rect_aligned.bottom, src_box->Front, src_box->Back);
- hr = IDirect3DVolume9_LockBox(src_volume, &locked_box, &src_box_aligned, 0);
- if (FAILED(hr))
return hr;
- SetRect(&src_rect_unaligned, src_box->Left, src_box->Top, src_box->Right, src_box->Bottom);
- OffsetRect(&src_rect_unaligned, -src_rect_aligned.left, -src_rect_aligned.top);
- set_d3dx_pixels(&src_pixels, locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, src_palette,
(src_box_aligned.Right - src_box_aligned.Left), (src_box_aligned.Bottom - src_box_aligned.Top),
(src_box_aligned.Back - src_box_aligned.Front), &src_rect_unaligned);
Could we use `d3dx_pixels_init()` here?
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/volume.c:
- *dst_buffer = buffer;
- return D3D_OK;
}
HRESULT WINAPI D3DXSaveVolumeToFileA(const char *dst_filename, D3DXIMAGE_FILEFORMAT file_format, IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box) {
- FIXME("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p stub.\n",
wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box);
- return E_NOTIMPL;
- ID3DXBuffer *buffer;
- WCHAR *filename;
- int32_t len;
- HRESULT hr;
- TRACE("(%s, %#x, %p, %p, %p): relay.\n", wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box);
Let's recover the message from the `FIXME()` (minus " stub") instead.
Matteo Bruni (@Mystral) commented about dlls/d3dx9_36/texture.c:
{ FIXME("DDS file format isn't supported yet\n"); return E_NOTIMPL; }
Just curious: are we basically ready to get rid of this or does it still need work?