Henri Verbeet : wined3d: Refuse to create shaders with a NULL function.

Alexandre Julliard julliard at winehq.org
Tue Dec 16 08:40:34 CST 2008


Module: wine
Branch: master
Commit: 46572f682ceb651803d7ef6c166d514381ff42a2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=46572f682ceb651803d7ef6c166d514381ff42a2

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Mon Dec 15 16:35:13 2008 +0100

wined3d: Refuse to create shaders with a NULL function.

---

 dlls/d3d8/device.c       |   59 +++++++++++++++++++++++++++++++++------------
 dlls/d3d8/vertexshader.c |    2 +-
 dlls/d3d9/tests/shader.c |   10 +++++++-
 dlls/wined3d/device.c    |    5 ++++
 4 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 58f698a..41d8554 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -1599,20 +1599,28 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
 
     wined3d_vertex_declaration = ((IDirect3DVertexDeclaration8Impl *)object->vertex_declaration)->wined3d_vertex_declaration;
 
-    /* Usage is missing ... Use SetRenderState to set the sw vp render state in SetVertexShader */
-    hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
+    if (pFunction)
+    {
+        /* Usage is missing ... Use SetRenderState to set the sw vp render state in SetVertexShader */
+        hrc = IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, wined3d_vertex_declaration,
+                pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
 
-    if (FAILED(hrc)) {
-        /* free up object */
-        FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
-        free_shader_handle(This, handle);
-        IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
-        HeapFree(GetProcessHeap(), 0, object);
-        *ppShader = 0;
-    } else {
-        load_local_constants(pDeclaration, object->wineD3DVertexShader);
-        TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
+        if (FAILED(hrc))
+        {
+            /* free up object */
+            FIXME("Call to IWineD3DDevice_CreateVertexShader failed\n");
+            free_shader_handle(This, handle);
+            IDirect3DVertexDeclaration8_Release(object->vertex_declaration);
+            HeapFree(GetProcessHeap(), 0, object);
+            *ppShader = 0;
+        }
+        else
+        {
+            load_local_constants(pDeclaration, object->wineD3DVertexShader);
+            TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);
+        }
     }
+
     LeaveCriticalSection(&d3d8_cs);
 
     return hrc;
@@ -1706,9 +1714,19 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShader(LPDIRECT3DDEVICE8 ifa
             hrc = D3DERR_INVALIDCALL;
         } else {
             IDirect3DVertexShader8Impl *shader = This->shader_handles[pShader - (VS_HIGHESTFIXEDFXF + 1)];
-            IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
-                    shader ? ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration : NULL);
-            hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, 0 == shader ? NULL : shader->wineD3DVertexShader);
+
+            if (shader)
+            {
+                hrc = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice,
+                        ((IDirect3DVertexDeclaration8Impl *)shader->vertex_declaration)->wined3d_vertex_declaration);
+                if (SUCCEEDED(hrc))
+                    hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, shader->wineD3DVertexShader);
+            }
+            else
+            {
+                hrc = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, NULL);
+                if (SUCCEEDED(hrc)) hrc = IWineD3DDevice_SetVertexShader(This->WineD3DDevice, NULL);
+            }
         }
     }
     TRACE("(%p) : returning hr(%u)\n", This, hrc);
@@ -1860,7 +1878,16 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEV
     }
 
     shader = This->shader_handles[pVertexShader - (VS_HIGHESTFIXEDFXF + 1)];
-    hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
+    if (shader->wineD3DVertexShader)
+    {
+        hr = IWineD3DVertexShader_GetFunction(shader->wineD3DVertexShader, pData, pSizeOfData);
+    }
+    else
+    {
+        *pSizeOfData = 0;
+        hr = D3D_OK;
+    }
+
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
diff --git a/dlls/d3d8/vertexshader.c b/dlls/d3d8/vertexshader.c
index bdc6685..8cd822b 100644
--- a/dlls/d3d8/vertexshader.c
+++ b/dlls/d3d8/vertexshader.c
@@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DVertexShader8Impl_Release(IDirect3DVertexShader8 *i
 
     if (ref == 0) {
         IDirect3DVertexDeclaration8_Release(This->vertex_declaration);
-        IWineD3DVertexShader_Release(This->wineD3DVertexShader);
+        if (This->wineD3DVertexShader) IWineD3DVertexShader_Release(This->wineD3DVertexShader);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
diff --git a/dlls/d3d9/tests/shader.c b/dlls/d3d9/tests/shader.c
index dcf8851..522f128 100644
--- a/dlls/d3d9/tests/shader.c
+++ b/dlls/d3d9/tests/shader.c
@@ -90,7 +90,11 @@ static void test_get_set_vertex_shader(IDirect3DDevice9 *device_ptr)
     HRESULT hret = 0;
     int shader_refcount = 0;
     int i = 0;
-    
+
+    hret = IDirect3DDevice9_CreateVertexShader(device_ptr, NULL, &shader_ptr);
+    ok(hret == D3DERR_INVALIDCALL, "CreateVertexShader returned %#x, expected D3DERR_INVALIDCALL (%#x).\n",
+            hret, D3DERR_INVALIDCALL);
+
     hret = IDirect3DDevice9_CreateVertexShader(device_ptr, simple_vs, &shader_ptr);
     ok(hret == D3D_OK && shader_ptr != NULL, "CreateVertexShader returned: hret 0x%x, shader_ptr %p. "
         "Expected hret 0x%x, shader_ptr != %p. Aborting.\n", hret, shader_ptr, D3D_OK, NULL);
@@ -155,6 +159,10 @@ static void test_get_set_pixel_shader(IDirect3DDevice9 *device_ptr)
     int shader_refcount = 0;
     int i = 0;
 
+    hret = IDirect3DDevice9_CreatePixelShader(device_ptr, NULL, &shader_ptr);
+    ok(hret == D3DERR_INVALIDCALL, "CreatePixelShader returned %#x, expected D3DERR_INVALIDCALL (%#x).\n",
+            hret, D3DERR_INVALIDCALL);
+
     hret = IDirect3DDevice9_CreatePixelShader(device_ptr, simple_ps, &shader_ptr);
     ok(hret == D3D_OK && shader_ptr != NULL, "CreatePixelShader returned: hret 0x%x, shader_ptr %p. "
         "Expected hret 0x%x, shader_ptr != %p. Aborting.\n", hret, shader_ptr, D3D_OK, NULL);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a99ff56..b765f12 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1874,6 +1874,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac
     IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DVertexShaderImpl *object;  /* NOTE: impl usage is ok, this is a create */
     HRESULT hr = WINED3D_OK;
+
+    if (!pFunction) return WINED3DERR_INVALIDCALL;
+
     D3DCREATESHADEROBJECTINSTANCE(object, VertexShader)
     object->baseShader.shader_ins = IWineD3DVertexShaderImpl_shader_ins;
 
@@ -1900,6 +1903,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface
     IWineD3DPixelShaderImpl *object; /* NOTE: impl allowed, this is a create */
     HRESULT hr = WINED3D_OK;
 
+    if (!pFunction) return WINED3DERR_INVALIDCALL;
+
     D3DCREATESHADEROBJECTINSTANCE(object, PixelShader)
     object->baseShader.shader_ins = IWineD3DPixelShaderImpl_shader_ins;
     hr = IWineD3DPixelShader_SetFunction(*ppPixelShader, pFunction);




More information about the wine-cvs mailing list