[PATCH 2/5] d3d9: Check for support before creating textures

Stefan Dösinger stefan at codeweavers.com
Tue Sep 3 07:07:14 CDT 2013


I'm checking this in d3d9/d3d8/ddraw because we create textures for
everything nowadays, even stand-alone surfaces. Handling this in the
client library also allows the client libraries to control the
difference between sysmem and scratch resources, e.g. like in
CreateImageSurface in d3d8.
---
 dlls/d3d9/device.c            | 49 +++++++++++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/tests/texture.c | 10 +++++++--
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index f805228..ae6fced 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -730,6 +730,23 @@ static void WINAPI d3d9_device_GetGammaRamp(IDirect3DDevice9Ex *iface, UINT swap
     wined3d_mutex_unlock();
 }
 
+static BOOL d3d9_device_check_format_support(struct d3d9_device *device, D3DFORMAT fmt,
+        DWORD usage, D3DRESOURCETYPE type)
+{
+    D3DDEVICE_CREATION_PARAMETERS creation_parameters;
+    HRESULT hr;
+
+    hr = IDirect3DDevice9_GetCreationParameters(&device->IDirect3DDevice9Ex_iface, &creation_parameters);
+    if (FAILED(hr))
+        return FALSE;
+
+    hr = IDirect3D9_CheckDeviceFormat(&device->d3d_parent->IDirect3D9Ex_iface,
+            creation_parameters.AdapterOrdinal, creation_parameters.DeviceType,
+            D3DFMT_X8R8G8B8, usage, type, fmt);
+
+    return SUCCEEDED(hr);
+}
+
 static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
         UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
         D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
@@ -742,6 +759,7 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
     TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
             iface, width, height, levels, usage, format, pool, texture, shared_handle);
 
+    *texture = NULL;
     if (shared_handle)
     {
         if (pool == D3DPOOL_SYSTEMMEM)
@@ -754,6 +772,13 @@ static HRESULT WINAPI d3d9_device_CreateTexture(IDirect3DDevice9Ex *iface,
             FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
     }
 
+    if (pool != D3DPOOL_SCRATCH &&
+            !d3d9_device_check_format_support(device, format, usage, D3DRTYPE_TEXTURE))
+    {
+        WARN("Texture format not supported.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return D3DERR_OUTOFVIDEOMEMORY;
@@ -798,6 +823,14 @@ static HRESULT WINAPI d3d9_device_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
     if (shared_handle)
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
 
+    *texture = NULL;
+    if (pool != D3DPOOL_SCRATCH &&
+            !d3d9_device_check_format_support(device, format, usage, D3DRTYPE_VOLUMETEXTURE))
+    {
+        WARN("Texture format not supported.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return D3DERR_OUTOFVIDEOMEMORY;
@@ -830,6 +863,14 @@ static HRESULT WINAPI d3d9_device_CreateCubeTexture(IDirect3DDevice9Ex *iface,
     if (shared_handle)
         FIXME("Resource sharing not implemented, *shared_handle %p.\n", *shared_handle);
 
+    *texture = NULL;
+    if (pool != D3DPOOL_SCRATCH &&
+            !d3d9_device_check_format_support(device, format, usage, D3DRTYPE_CUBETEXTURE))
+    {
+        WARN("Texture format not supported.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
     if (!object)
         return D3DERR_OUTOFVIDEOMEMORY;
@@ -927,6 +968,14 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
             device, width, height, format, flags, surface, usage, pool,
             multisample_type, multisample_quality);
 
+    *surface = NULL;
+    if (pool != D3DPOOL_SCRATCH &&
+            !d3d9_device_check_format_support(device, format, usage, D3DRTYPE_SURFACE))
+    {
+        WARN("Surface format not supported.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
     desc.resource_type = WINED3D_RTYPE_TEXTURE;
     desc.format = wined3dformat_from_d3dformat(format);
     desc.multisample_type = multisample_type;
diff --git a/dlls/d3dx9_36/tests/texture.c b/dlls/d3dx9_36/tests/texture.c
index f4e3a7f..3a48a20 100644
--- a/dlls/d3dx9_36/tests/texture.c
+++ b/dlls/d3dx9_36/tests/texture.c
@@ -25,7 +25,7 @@
 #include "d3dx9tex.h"
 #include "resources.h"
 
-static int has_2d_dxt5, has_cube_dxt5;
+static int has_2d_dxt5, has_cube_dxt5, has_volume_dxt5;
 
 /* 2x2 16-bit dds, no mipmaps */
 static const unsigned char dds_16bit[] = {
@@ -1565,7 +1565,10 @@ static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *devic
     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);
-    ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    if (has_volume_dxt5)
+        ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+    else
+        todo_wine ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
     if (SUCCEEDED(hr))
     {
         levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
@@ -1816,6 +1819,9 @@ START_TEST(texture)
     hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
             D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, D3DFMT_DXT5);
     has_cube_dxt5 = SUCCEEDED(hr);
+    hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+            D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5);
+    has_volume_dxt5 = SUCCEEDED(hr);
 
     test_D3DXCheckTextureRequirements(device);
     test_D3DXCheckCubeTextureRequirements(device);
-- 
1.8.1.5




More information about the wine-patches mailing list