d3dx9: Allow D3DXAssembleShader calls with NULL parameters.

Matteo Bruni matteo.mystral at gmail.com
Sat Jun 5 14:14:38 CDT 2010


This also allows Universal Combat to go one step further
(http://bugs.winehq.org/show_bug.cgi?id=11021).
-------------- next part --------------
From 29e96de08354388a12788819058d5d3def7ab752 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Sat, 5 Jun 2010 17:12:14 +0200
Subject: d3dx9: Allow D3DXAssembleShader calls with NULL parameters.

---
 dlls/d3dx9_36/shader.c    |   70 +++++++++++++++++++++++++-------------------
 dlls/d3dx9_36/tests/asm.c |   19 ++++++++++++
 2 files changed, 59 insertions(+), 30 deletions(-)

diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index b226fa6..3a7824a 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -411,25 +411,28 @@ HRESULT assemble_shader(const char *preprocShader, const char *preprocMessages,
         TRACE("Shader source:\n");
         TRACE("%s\n", debugstr_a(preprocShader));
 
-        size = (messages ? strlen(messages) : 0) +
-            (preprocMessages ? strlen(preprocMessages) : 0) + 1;
-        hr = D3DXCreateBuffer(size, &buffer);
-        if(FAILED(hr))
-        {
-            HeapFree(GetProcessHeap(), 0, messages);
-            if(shader) SlDeleteShader(shader);
-            return hr;
-        }
-        pos = ID3DXBuffer_GetBufferPointer(buffer);
-        if(preprocMessages)
+        if(ppErrorMsgs)
         {
-            CopyMemory(pos, preprocMessages, strlen(preprocMessages) + 1);
-            pos += strlen(preprocMessages);
-        }
-        if(messages)
-            CopyMemory(pos, messages, strlen(messages) + 1);
+            size = (messages ? strlen(messages) : 0) +
+                (preprocMessages ? strlen(preprocMessages) : 0) + 1;
+            hr = D3DXCreateBuffer(size, &buffer);
+            if(FAILED(hr))
+            {
+                HeapFree(GetProcessHeap(), 0, messages);
+                if(shader) SlDeleteShader(shader);
+                return hr;
+            }
+            pos = ID3DXBuffer_GetBufferPointer(buffer);
+            if(preprocMessages)
+            {
+                CopyMemory(pos, preprocMessages, strlen(preprocMessages) + 1);
+                pos += strlen(preprocMessages);
+            }
+            if(messages)
+                CopyMemory(pos, messages, strlen(messages) + 1);
 
-        *ppErrorMsgs = buffer;
+            *ppErrorMsgs = buffer;
+        }
 
         HeapFree(GetProcessHeap(), 0, messages);
     }
@@ -448,15 +451,18 @@ HRESULT assemble_shader(const char *preprocShader, const char *preprocMessages,
         return D3DXERR_INVALIDDATA;
     }
 
-    size = HeapSize(GetProcessHeap(), 0, res);
-    hr = D3DXCreateBuffer(size, &buffer);
-    if(FAILED(hr))
+    if(ppShader)
     {
-        HeapFree(GetProcessHeap(), 0, res);
-        return hr;
+        size = HeapSize(GetProcessHeap(), 0, res);
+        hr = D3DXCreateBuffer(size, &buffer);
+        if(FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, res);
+            return hr;
+        }
+        CopyMemory(ID3DXBuffer_GetBufferPointer(buffer), res, size);
+        *ppShader = buffer;
     }
-    CopyMemory(ID3DXBuffer_GetBufferPointer(buffer), res, size);
-    *ppShader = buffer;
 
     HeapFree(GetProcessHeap(), 0, res);
 
@@ -500,7 +506,8 @@ HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
     }
     current_include = include;
 
-    *shader = *error_messages = NULL;
+    if(shader) *shader = NULL;
+    if(error_messages) *error_messages = NULL;
     wpp_output_size = wpp_output_capacity = 0;
     wpp_output = NULL;
 
@@ -525,11 +532,14 @@ HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
             TRACE("Preprocessor messages:\n");
             TRACE("%s", wpp_messages);
 
-            size = strlen(wpp_messages) + 1;
-            hr = D3DXCreateBuffer(size, &buffer);
-            if(FAILED(hr)) goto cleanup;
-            CopyMemory(ID3DXBuffer_GetBufferPointer(buffer), wpp_messages, size);
-            *error_messages = buffer;
+            if(error_messages)
+            {
+                size = strlen(wpp_messages) + 1;
+                hr = D3DXCreateBuffer(size, &buffer);
+                if(FAILED(hr)) goto cleanup;
+                CopyMemory(ID3DXBuffer_GetBufferPointer(buffer), wpp_messages, size);
+                *error_messages = buffer;
+            }
         }
         if(data)
         {
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index cc0b6ae..9ed1be8 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1435,6 +1435,25 @@ static void assembleshader_test(void) {
     }
     if(shader) ID3DXBuffer_Release(shader);
 
+    /* NULL messages test */
+    shader = NULL;
+    hr = D3DXAssembleShader(test1, strlen(test1),
+                            defines, NULL, D3DXSHADER_SKIPVALIDATION,
+                            &shader, NULL);
+    ok(hr == D3D_OK, "NULL messages test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+    if(shader) ID3DXBuffer_Release(shader);
+
+    /* NULL shader test */
+    messages = NULL;
+    hr = D3DXAssembleShader(test1, strlen(test1),
+                            defines, NULL, D3DXSHADER_SKIPVALIDATION,
+                            NULL, &messages);
+    ok(hr == D3D_OK, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+    if(messages) {
+        trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+        ID3DXBuffer_Release(messages);
+    }
+
     /* pInclude test */
     shader = NULL;
     messages = NULL;
-- 
1.6.4.4


More information about the wine-patches mailing list