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. :)
-- v2: d3dx9: Use D3DXSaveVolumeToFileInMemory() inside of D3DXSaveTextureToFileInMemory(). d3dx9: Implement D3DXSaveVolumeToFile{A,W,InMemory}(). d3dx9/tests: Add tests for D3DXSaveVolumeToFile{A,W,InMemory}(). d3dx9: Add stubs for D3DXSaveVolumeToFile{A,W,InMemory}().
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/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 +++--- 21 files changed, 85 insertions(+), 60 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/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)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- 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 | 268 ++++++++++++++++++++++++ include/d3dx9tex.h | 3 + 5 files changed, 422 insertions(+), 139 deletions(-)
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..1d2d0eda601 100644 --- a/dlls/d3dx9_36/tests/volume.c +++ b/dlls/d3dx9_36/tests/volume.c @@ -392,6 +392,273 @@ 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 *coord, const D3DXVECTOR3 *size, void *data) +{ + D3DXVECTOR3 vec = *coord; + uint32_t idx; + + if (data) + { + *value = *(D3DXVECTOR4 *)data; + return; + } + + set_vec3(&vec, (vec.x / size->x) - 0.5f, (vec.y / size->y) - 0.5f, (vec.z / size->z) - 0.5f); + if (vec.x < 16.0f) + idx = vec.y < 16.0f ? 0 : 2; + else + idx = vec.y < 16.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 + { + const char *name; + + D3DXIMAGE_FILEFORMAT iff; + D3DFORMAT saved_format; + uint8_t max_diff; + } tests[] = + { + { "D3DXIFF_BMP", D3DXIFF_BMP, D3DFMT_A8R8G8B8 }, + { "D3DXIFF_JPG", D3DXIFF_JPG, D3DFMT_X8R8G8B8, .max_diff = 1 }, + { "D3DXIFF_TGA", D3DXIFF_TGA, D3DFMT_A8R8G8B8 }, + { "D3DXIFF_PNG", D3DXIFF_PNG, D3DFMT_A8R8G8B8 }, + { "D3DXIFF_DDS", D3DXIFF_DDS, D3DFMT_A8R8G8B8 }, + { "D3DXIFF_HDR", D3DXIFF_HDR, D3DFMT_A32B32G32R32F, .max_diff = 1 }, + { "D3DXIFF_PFM", D3DXIFF_PFM, D3DFMT_A32B32G32R32F }, + { "D3DXIFF_PPM", D3DXIFF_PPM, D3DFMT_X8R8G8B8 }, + }; + 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; + WCHAR name_buf_w[MAX_PATH]; + char name_buf_a[MAX_PATH]; + IDirect3DVolume9 *volume; + D3DXIMAGE_INFO info; + 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, 32, 32, 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, 32, 32, 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, 32, 32, 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, 32, 32, 0, 0, 0, + &d3dfmt_a8r8g8b8_pf, DDSCAPS_TEXTURE | DDSCAPS_ALPHA, 0, FALSE); + ID3DXBuffer_Release(buffer); + + GetTempPathA(ARRAY_SIZE(name_buf_a), name_buf_a); + GetTempFileNameA(name_buf_a, "dxa", 0, name_buf_a); + + GetTempPathW(ARRAY_SIZE(name_buf_w), name_buf_w); + GetTempFileNameW(name_buf_w, L"dxw", 0, name_buf_w); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("File format %u (%s)", i, tests[i].name); + + /* + * 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("Depth %u", 2 - j); + hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + set_box(&box, 0, 0, 32, 32, j, 2); + + hr = D3DXSaveVolumeToFileA(name_buf_a, tests[i].iff, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXSaveVolumeToFileW(name_buf_w, tests[i].iff, volume, NULL, &box); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXSaveVolumeToFileInMemory(&buffer, tests[i].iff, 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].iff == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 32, 32, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, back_expected, 0); + } + else + { + check_image_info(&info, 32, 32, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, 0); + } + } + else + { + check_image_info(&info, 32, 32, 1, 1, tests[i].saved_format, D3DRTYPE_TEXTURE, tests[i].iff, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, !j ? front_expected : back_expected, + tests[i].max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, tests[i].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].iff == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 32, 32, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, back_expected, 0); + } + else + { + check_image_info(&info, 32, 32, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, 0); + } + } + else + { + check_image_info(&info, 32, 32, 1, 1, tests[i].saved_format, D3DRTYPE_TEXTURE, tests[i].iff, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, !j ? front_expected : back_expected, + tests[i].max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, tests[i].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].iff == D3DXIFF_DDS) + { + if (!j) + { + check_image_info(&info, 32, 32, 2, 1, D3DFMT_A8R8G8B8, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, front_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, back_expected, 0); + } + else + { + check_image_info(&info, 32, 32, 1, 1, D3DFMT_A8R8G8B8, D3DRTYPE_TEXTURE, D3DXIFF_DDS, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, back_expected, 0); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, 0); + } + } + else + { + check_image_info(&info, 32, 32, 1, 1, tests[i].saved_format, D3DRTYPE_TEXTURE, tests[i].iff, FALSE); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 0, !j ? front_expected : back_expected, + tests[i].max_diff); + check_volume_readback_slice_quadrants(&volume_rb, 32, 32, 1, empty_expected, tests[i].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 +695,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/include/d3dx9tex.h b/include/d3dx9tex.h index 3883165c67e..ae3fd8c34ff 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 **dst_buffer, D3DXIMAGE_FILEFORMAT dst_format, + struct IDirect3DVolume9 *src_volume, const PALETTEENTRY *src_palette, const D3DBOX *src_box); + 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 | 24 +++---- dlls/d3dx9_36/volume.c | 118 ++++++++++++++++++++++++++++++++-- 4 files changed, 137 insertions(+), 21 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 1d2d0eda601..b090e31a8b1 100644 --- a/dlls/d3dx9_36/tests/volume.c +++ b/dlls/d3dx9_36/tests/volume.c @@ -453,6 +453,7 @@ static void test_d3dx_save_volume_to_file(IDirect3DDevice9 *device) D3DXIMAGE_FILEFORMAT iff; D3DFORMAT saved_format; uint8_t max_diff; + BOOL wine_todo; } tests[] = { { "D3DXIFF_BMP", D3DXIFF_BMP, D3DFMT_A8R8G8B8 }, @@ -460,9 +461,9 @@ static void test_d3dx_save_volume_to_file(IDirect3DDevice9 *device) { "D3DXIFF_TGA", D3DXIFF_TGA, D3DFMT_A8R8G8B8 }, { "D3DXIFF_PNG", D3DXIFF_PNG, D3DFMT_A8R8G8B8 }, { "D3DXIFF_DDS", D3DXIFF_DDS, D3DFMT_A8R8G8B8 }, - { "D3DXIFF_HDR", D3DXIFF_HDR, D3DFMT_A32B32G32R32F, .max_diff = 1 }, - { "D3DXIFF_PFM", D3DXIFF_PFM, D3DFMT_A32B32G32R32F }, - { "D3DXIFF_PPM", D3DXIFF_PPM, D3DFMT_X8R8G8B8 }, + { "D3DXIFF_HDR", D3DXIFF_HDR, D3DFMT_A32B32G32R32F, .max_diff = 1, .wine_todo = TRUE }, + { "D3DXIFF_PFM", D3DXIFF_PFM, D3DFMT_A32B32G32R32F, .wine_todo = TRUE }, + { "D3DXIFF_PPM", D3DXIFF_PPM, D3DFMT_X8R8G8B8, .wine_todo = TRUE }, }; struct { @@ -482,12 +483,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, 32, 32, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &volume_texture, NULL); if (FAILED(hr)) @@ -544,13 +539,18 @@ static void test_d3dx_save_volume_to_file(IDirect3DDevice9 *device) set_box(&box, 0, 0, 32, 32, j, 2);
hr = D3DXSaveVolumeToFileA(name_buf_a, tests[i].iff, volume, NULL, &box); - ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tests[i].wine_todo) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = D3DXSaveVolumeToFileW(name_buf_w, tests[i].iff, volume, NULL, &box); - ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tests[i].wine_todo) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
hr = D3DXSaveVolumeToFileInMemory(&buffer, tests[i].iff, volume, NULL, &box); - ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + todo_wine_if(tests[i].wine_todo) ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (!strcmp(winetest_platform, "wine") && tests[i].wine_todo) + { + winetest_pop_context(); + continue; + }
/* ASCII string. */ hr = D3DXFillVolumeTexture(volume_texture, fill_func_volume, (void *)&clear_val); diff --git a/dlls/d3dx9_36/volume.c b/dlls/d3dx9_36/volume.c index 14f6bdbfc33..546959b017e 100644 --- a/dlls/d3dx9_36/volume.c +++ b/dlls/d3dx9_36/volume.c @@ -283,24 +283,130 @@ 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; + struct d3dx_pixels src_pixels; + D3DLOCKED_BOX locked_box; + ID3DXBuffer *buffer; + D3DVOLUME_DESC desc; + D3DBOX src_box_tmp; + 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; + } + } + + hr = IDirect3DVolume9_LockBox(src_volume, &locked_box, NULL, D3DLOCK_READONLY); + if (FAILED(hr)) + return hr; + + hr = d3dx_pixels_init(locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, src_palette, + src_fmt_desc->format, src_box->Left, src_box->Top, src_box->Right, src_box->Bottom, src_box->Front, + src_box->Back, &src_pixels); + if (FAILED(hr)) + { + IDirect3DVolume9_UnlockBox(src_volume); + return hr; + } + + hr = d3dx_save_pixels_to_memory(&src_pixels, src_fmt_desc, file_format, &buffer); + IDirect3DVolume9_UnlockBox(src_volume); + if (SUCCEEDED(hr)) + *dst_buffer = buffer; + + return hr; }
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", + ID3DXBuffer *buffer; + WCHAR *filename; + HRESULT hr; + int len; + + TRACE("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p.\n", wine_dbgstr_a(dst_filename), file_format, src_volume, src_palette, src_box); - return E_NOTIMPL; + + 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", + ID3DXBuffer *buffer; + HRESULT hr; + + TRACE("dst_filename %s, file_format %#x, src_volume %p, src_palette %p, src_box %p.\n", wine_dbgstr_w(dst_filename), file_format, src_volume, src_palette, src_box); - return E_NOTIMPL; + + 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; }
On Tue Mar 18 18:32:59 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/7577/diffs?diff_id=164932&start_sha=c592af0c989d202ae74fb9b140acef84db7e99be#00fcd0e0df705d939078be032416805331b596d0_402_402)
No problem, I'm not sure how a lot of the code in these patches ended up the way that it did... Must be a combination of written awhile ago and copy pasting from other code. :)
On Tue Mar 18 18:32:59 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/7577/diffs?diff_id=164932&start_sha=c592af0c989d202ae74fb9b140acef84db7e99be#00fcd0e0df705d939078be032416805331b596d0_532_539)
I _think_ I did this in a way that matches what you've described, but I'll let you mark this as resolved just to confirm :) I'm using random paths/filenames now and just reusing the same name for each different IFF. Not sure if that really matters or not, but I feel like it should be fine.
On Tue Mar 18 18:32:59 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/7577/diffs?diff_id=164932&start_sha=c592af0c989d202ae74fb9b140acef84db7e99be#00fcd0e0df705d939078be032416805331b596d0_567_580)
I probably spent way longer investigating this than I should have, but basically what I found was:
Native had a max diff of 5, we had a max diff of 40. Even setting the libjpeg encoder to the maximum quality didn't get us within the same max diff as native. I then also enabled smoothing, the best I could get was a max diff of 10.
For some reason I thought JPG blocks were 4x4, they're 8x8. I've updated the tests now to have the quadrants as 8x8 and now we're within a max diff of 1, which is the same as native. I feel like that "resolves" things, although it does seem like our JPEG encoding is inferior to native and I've only masked the issue. Not sure if anything would rely upon this, or if I should make a note of it somewhere.
On Tue Mar 18 18:42:01 2025 +0000, Matteo Bruni wrote:
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.
I _think_ I've done what you were describing here, putting the tests into a separate commit after the stubs.
On Tue Mar 18 18:42:22 2025 +0000, Matteo Bruni wrote:
Do you know if native supports those formats in `D3DXSaveVolumeToFile*` in the first place? No reason it shouldn't, but you know...
Added tests for these now, it does. :)
On Tue Mar 18 18:33:00 2025 +0000, Connor McAdams wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/7577/diffs?diff_id=164932&start_sha=c592af0c989d202ae74fb9b140acef84db7e99be#71438e818afcc0c8e9d7a96e1b1a0419757bcde7_354_344)
Should be fixed now. :)
On Sun Mar 16 17:33:09 2025 +0000, Matteo Bruni wrote:
Just curious: are we basically ready to get rid of this or does it still need work?
The next set of patches will get rid of this, the only thing impeding us from removing that check now is that we can't properly save textures with multiple levels/cube textures. I guess we could change it now to only be hit if a texture has multiple levels or is a cube texture, but I didn't do that because these used to be in one big patch series.
I can change this now if you'd prefer, or we can just wait until the next MR which will fully implement saving textures to DDS files.
On Tue Mar 18 23:33:01 2025 +0000, Connor McAdams wrote:
I probably spent way longer investigating this than I should have, but basically what I found was: Native had a max diff of 5, we had a max diff of 40. Even setting the libjpeg encoder to the maximum quality didn't get us within the same max diff as native. I then also enabled smoothing, the best I could get was a max diff of 10. For some reason I thought JPG blocks were 4x4, they're 8x8. I've updated the tests now to have the quadrants as 8x8 and now we're within a max diff of 1, which is the same as native. I feel like that "resolves" things, although it does seem like our JPEG encoding is inferior to native and I've only masked the issue. Not sure if anything would rely upon this, or if I should make a note of it somewhere.
Okay I don't know what I was saying earlier, spent some time thinking this over while taking a walk :D it had 8x8 quadrants before. AFAIU from some researching just now, JPEG is usually encoded as 4:2:0, which results in 8x8 blocks for luma, and 16x16 blocks for chroma IIUC. Which would explain why upping the size to 32x32 increases the accuracy of compression here.
Not sure how much it matters, but wanted to make sure what I did actually made sense.
On Tue Mar 18 23:33:01 2025 +0000, Connor McAdams wrote:
Okay I don't know what I was saying earlier, spent some time thinking this over while taking a walk :D it had 8x8 quadrants before. AFAIU from some researching just now, JPEG is usually encoded as 4:2:0, which results in 8x8 blocks for luma, and 16x16 blocks for chroma IIUC. Which would explain why upping the size to 32x32 increases the accuracy of compression here. Not sure how much it matters, but wanted to make sure what I did actually made sense.
Thanks for the deep dive. It makes sense to me, very interesting! Don't go crazy into further investigations, BUT if you're already set up, you could try to disable chroma subsampling[1] and see if that checks out.
At any rate, the current version seems certainly fine for this general `D3DXSaveVolumeToFile()` test and this MR.
It's up to you how to follow up on this JPEG compression detail. If disabling chroma subsampling does the trick, we have a path to properly fixing it, at some point. Either way, a test highlighting the issue would be probably ideal, with a small comment explaining the issue and possibly a `FIXME()` when saving to `D3DXIFF_JPG`. But I'm cool anyway, as long as there will be *something* to remind us when we forget.
[1]: With a very quick and dirty search I found this: ``` cinfo->comp_info[0].v_samp_factor = 1; cinfo->comp_info[0].h_samp_factor = 1; ``` which might or might not be easy to integrate into windowscodecs and do the right thing...
On Thu Mar 20 00:24:33 2025 +0000, Connor McAdams wrote:
The next set of patches will get rid of this, the only thing impeding us from removing that check now is that we can't properly save textures with multiple levels/cube textures. I guess we could change it now to only be hit if a texture has multiple levels or is a cube texture, but I didn't do that because these used to be in one big patch series. I can change this now if you'd prefer, or we can just wait until the next MR which will fully implement saving textures to DDS files.
This is totally fine.
This merge request was approved by Matteo Bruni.
On Thu Mar 20 00:24:33 2025 +0000, Matteo Bruni wrote:
Thanks for the deep dive. It makes sense to me, very interesting! Don't go crazy into further investigations, BUT if you're already set up, you could try to disable chroma subsampling[1] and see if that checks out. At any rate, the current version seems certainly fine for this general `D3DXSaveVolumeToFile()` test and this MR. It's up to you how to follow up on this JPEG compression detail. If disabling chroma subsampling does the trick, we have a path to properly fixing it, at some point. Either way, a test highlighting the issue would be probably ideal, with a small comment explaining the issue and possibly a `FIXME()` when saving to `D3DXIFF_JPG`. But I'm cool anyway, as long as there will be *something* to remind us when we forget. [1]: With a very quick and dirty search I found this:
cinfo->comp_info[0].v_samp_factor = 1; cinfo->comp_info[0].h_samp_factor = 1;
which might or might not be easy to integrate into windowscodecs and do the right thing...
Ah yep, changing those component sampling factors fixes the old tests, it actually makes our encoder produce better results than the native one. :)
I'll write a test showing this in the next MR. As for how to integrate it into windowscodecs, it looks like there's an option to set [WICJpegYCrCbSubsamplingOption](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/ne-wincodec-wic...) which we don't currently handle.
Thanks for the thorough review and looking further into this! :D