[4/5] d3dx9: Implement D3DXCreateVolumeTextureFromFileInMemoryEx. (try 2)

Józef Kucia joseph.kucia at gmail.com
Fri Jun 29 07:17:01 CDT 2012


try 2: Rename mip_level_size to src_slice_pitch.
---
 dlls/d3dx9_36/d3dx9_36_private.h |    2 +
 dlls/d3dx9_36/surface.c          |   52 ++++++++++++
 dlls/d3dx9_36/tests/texture.c    |   53 ++++++------
 dlls/d3dx9_36/texture.c          |  164 +++++++++++++++++++++++++++++++++-----
 4 files changed, 225 insertions(+), 46 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 1cbb7cf..fe3d090 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -68,6 +68,8 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data,
     DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
     const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
+HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
+    const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
 
 /* debug helpers */
 const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 7be3ebe..845a1f7 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -499,6 +499,58 @@ HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const vo
     return D3D_OK;
 }
 
+HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
+    const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
+{
+    HRESULT hr;
+    UINT mip_level;
+    UINT mip_levels;
+    UINT src_slice_pitch;
+    UINT src_row_pitch;
+    D3DBOX src_box;
+    UINT width, height, depth;
+    IDirect3DVolume9 *volume;
+    const struct dds_header *header = src_data;
+    const BYTE *pixels = (BYTE *)(header + 1);
+
+    if (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE)
+        return D3DXERR_INVALIDDATA;
+
+    width = src_info->Width;
+    height = src_info->Height;
+    depth = src_info->Depth;
+    mip_levels = min(src_info->MipLevels, IDirect3DVolumeTexture9_GetLevelCount(volume_texture));
+
+    for (mip_level = 0; mip_level < mip_levels; mip_level++)
+    {
+        hr = calculate_dds_surface_size(src_info, width, height, &src_row_pitch, &src_slice_pitch);
+        if (FAILED(hr)) return hr;
+
+        hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, mip_level, &volume);
+        if (FAILED(hr)) return hr;
+
+        src_box.Left = 0;
+        src_box.Top = 0;
+        src_box.Right = width;
+        src_box.Bottom = height;
+        src_box.Front = 0;
+        src_box.Back = depth;
+
+        hr = D3DXLoadVolumeFromMemory(volume, palette, NULL, pixels, src_info->Format,
+            src_row_pitch, src_slice_pitch, NULL, &src_box, filter, color_key);
+
+        IDirect3DVolume9_Release(volume);
+        if (FAILED(hr)) return hr;
+
+        pixels += depth * src_slice_pitch;
+        width = max(1, width / 2);
+        height = max(1, height / 2);
+        depth = max(1, depth / 2);
+    }
+
+    return D3D_OK;
+}
+
 /************************************************************
  * D3DXGetImageInfoFromFileInMemory
  *
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index 6cee065..44bf235 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -1359,40 +1359,39 @@ static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *devic
     IDirect3DVolumeTexture9 *volume_texture;
     D3DVOLUME_DESC volume_desc;
 
-    todo_wine {
-        hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
-        ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+    hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 
-        hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
-        ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+    hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 
-        hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
-        ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+    hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 
-        hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
-        ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+    hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
+    ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
 
-        hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
-        if (SUCCEEDED(hr))
-        {
-            levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
-            ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
+    hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
+    ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    if (SUCCEEDED(hr))
+    {
+        levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
+        ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
 
-            hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
-            ok(hr == D3D_OK, "GetLevelDesc returend %#x, expected %#x\n", hr, D3D_OK);
-            ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
-            ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
-            ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
+        hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
+        ok(hr == D3D_OK, "GetLevelDesc returend %#x, expected %#x\n", hr, D3D_OK);
+        ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
+        ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
+        ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
 
-            hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
-            ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
-            ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
-            ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
-            ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
+        hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
+        ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+        ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
+        ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
+        ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
 
-            ref = IDirect3DVolumeTexture9_Release(volume_texture);
-            ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
-        }
+        ref = IDirect3DVolumeTexture9_Release(volume_texture);
+        ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
     }
 }
 
diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c
index 1e87a00..f439913 100644
--- a/dlls/d3dx9_36/texture.c
+++ b/dlls/d3dx9_36/texture.c
@@ -977,40 +977,166 @@ HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
                                                 usage, format, pool, texture, NULL);
 }
 
-HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
-                                                      LPCVOID data,
-                                                      UINT datasize,
-                                                      LPDIRECT3DVOLUMETEXTURE9 *texture)
+HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device,
+                                                       const void *data,
+                                                       UINT data_size,
+                                                       IDirect3DVolumeTexture9 **volume_texture)
 {
-    TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
+    TRACE("(%p, %p, %u, %p): relay\n", device, data, data_size, volume_texture);
 
-    return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
+    return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
         D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
-        0, NULL, NULL, texture);
+        0, NULL, NULL, volume_texture);
 }
 
-HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
-                                                         LPCVOID data,
-                                                         UINT datasize,
+HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
+                                                         const void *data,
+                                                         UINT data_size,
                                                          UINT width,
                                                          UINT height,
                                                          UINT depth,
-                                                         UINT miplevels,
+                                                         UINT mip_levels,
                                                          DWORD usage,
                                                          D3DFORMAT format,
                                                          D3DPOOL pool,
                                                          DWORD filter,
-                                                         DWORD mipfilter,
-                                                         D3DCOLOR colorkey,
-                                                         D3DXIMAGE_INFO *imageinfo,
+                                                         DWORD mip_filter,
+                                                         D3DCOLOR color_key,
+                                                         D3DXIMAGE_INFO *info,
                                                          PALETTEENTRY *palette,
-                                                         LPDIRECT3DVOLUMETEXTURE9 *texture)
+                                                         IDirect3DVolumeTexture9 **volume_texture)
 {
-    FIXME("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p) : stub\n",
-        device, data, datasize, width, height, depth, miplevels, usage, format, pool,
-        filter, mipfilter, colorkey, imageinfo, palette, texture);
+    HRESULT hr;
+    D3DCAPS9 caps;
+    D3DXIMAGE_INFO image_info;
+    BOOL dynamic_texture;
+    BOOL file_width = FALSE;
+    BOOL file_height = FALSE;
+    BOOL file_depth = FALSE;
+    BOOL file_format = FALSE;
+    BOOL file_mip_levels = FALSE;
+    IDirect3DVolumeTexture9 *tex, *buftex;
+
+    TRACE("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n",
+            device, data, data_size, width, height, depth, mip_levels, usage, format, pool,
+            filter, mip_filter, color_key, info, palette, volume_texture);
+
+    if (!device || !data || !data_size || !volume_texture)
+        return D3DERR_INVALIDCALL;
+
+    hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info);
+    if (FAILED(hr)) return hr;
+
+    if (image_info.ImageFileFormat != D3DXIFF_DDS)
+        return D3DXERR_INVALIDDATA;
+
+    if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
+        width = image_info.Width;
+    if (width == D3DX_DEFAULT)
+        width = make_pow2(image_info.Width);
+
+    if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
+        height = image_info.Height;
+    if (height == D3DX_DEFAULT)
+        height = make_pow2(image_info.Height);
+
+    if (depth == 0 || depth == D3DX_DEFAULT_NONPOW2)
+        depth = image_info.Depth;
+    if (depth == D3DX_DEFAULT)
+        depth = make_pow2(image_info.Depth);
+
+    if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
+        format = image_info.Format;
+
+    if (width == D3DX_FROM_FILE)
+    {
+        file_width = TRUE;
+        width = image_info.Width;
+    }
+
+    if (height == D3DX_FROM_FILE)
+    {
+        file_height = TRUE;
+        height = image_info.Height;
+    }
+
+    if (depth == D3DX_FROM_FILE)
+    {
+        file_depth = TRUE;
+        depth = image_info.Depth;
+    }
+
+    if (format == D3DFMT_FROM_FILE)
+    {
+        file_format = TRUE;
+        format = image_info.Format;
+    }
+
+    if (mip_levels == D3DX_FROM_FILE)
+    {
+        file_mip_levels = TRUE;
+        mip_levels = image_info.MipLevels;
+    }
+
+    hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mip_levels, usage, &format, pool);
+    if (FAILED(hr)) return hr;
+
+    if ((file_width && width != image_info.Width)
+            || (file_height && height != image_info.Height)
+            || (file_depth && depth != image_info.Depth)
+            || (file_format && format != image_info.Format)
+            || (file_mip_levels && mip_levels != image_info.MipLevels))
+        return D3DERR_NOTAVAILABLE;
 
-    return E_NOTIMPL;
+    hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+    if (FAILED(hr))
+        return D3DERR_INVALIDCALL;
+
+    if (mip_levels > image_info.MipLevels)
+    {
+        FIXME("Generation of mipmaps for volume textures is not implemented yet\n");
+        mip_levels = image_info.MipLevels;
+    }
+
+    dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
+    if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
+    {
+        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
+        tex = buftex;
+    }
+    else
+    {
+        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
+        buftex = NULL;
+    }
+
+    if (FAILED(hr)) return hr;
+
+    hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info);
+    if (FAILED(hr))
+    {
+        IDirect3DVolumeTexture9_Release(tex);
+        return hr;
+    }
+
+    if (buftex)
+    {
+        hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
+        if (FAILED(hr))
+        {
+            IDirect3DVolumeTexture9_Release(buftex);
+            return hr;
+        }
+
+        IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
+        IDirect3DVolumeTexture9_Release(buftex);
+    }
+
+    if (info)
+        *info = image_info;
+
+    *volume_texture = tex;
+    return D3D_OK;
 }
 
 HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,
-- 
1.7.8.6




More information about the wine-patches mailing list