[1/2] d3dx9_36: Handle parent_data parameter of D3DXInclude.Open() function.

Matteo Bruni matteo.mystral at gmail.com
Tue Jul 27 16:32:03 CDT 2010


-------------- next part --------------
From 0840ddf7bae02a0a758134d25e18e122d62c2bb3 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Tue, 27 Jul 2010 23:02:59 +0200
Subject: d3dx9_36: Handle parent_data parameter of D3DXInclude.Open() function.

This patch adds a table keeping filename and data of each included
shader file, allowing to generate the correct value for parent_data.
---
 dlls/d3dx9_36/shader.c    |   63 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/d3dx9_36/tests/asm.c |   59 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 116 insertions(+), 6 deletions(-)

diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 9677e0b..4013eec 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -181,6 +181,19 @@ struct mem_file_desc
 
 struct mem_file_desc current_shader;
 LPD3DXINCLUDE current_include;
+
+#define INCLUDES_INITIAL_CAPACITY 4
+
+struct loaded_include
+{
+    const char *name;
+    const char *data;
+};
+
+struct loaded_include *includes;
+int includes_capacity, includes_size;
+const char *parent_include;
+
 char *wpp_output;
 int wpp_output_capacity, wpp_output_size;
 
@@ -275,6 +288,22 @@ static char *wpp_lookup_mem(const char *filename, const char *parent_name,
 {
     /* Here we return always ok. We will maybe fail on the next wpp_open_mem */
     char *path;
+    int i;
+
+    parent_include = NULL;
+    if(parent_name[0] != '\0')
+    {
+        for(i = 0; i < includes_size; i++)
+        {
+            if(!strcmp(parent_name, includes[i].name))
+            {
+                parent_include = includes[i].data;
+                break;
+            }
+        }
+        if(parent_include == NULL)
+            ERR("Parent include file missing\n");
+    }
 
     path = malloc(strlen(filename) + 1);
     if(!path) return NULL;
@@ -302,13 +331,44 @@ static void *wpp_open_mem(const char *filename, int type)
     }
     hr = ID3DXInclude_Open(current_include,
                            type ? D3DXINC_SYSTEM : D3DXINC_LOCAL,
-                           filename, NULL, (LPCVOID *)&desc->buffer,
+                           filename, parent_include, (LPCVOID *)&desc->buffer,
                            &desc->size);
     if(FAILED(hr))
     {
         HeapFree(GetProcessHeap(), 0, desc);
         return NULL;
     }
+
+    if(includes_capacity == includes_size)
+    {
+        if(includes_capacity == 0)
+        {
+            includes = HeapAlloc(GetProcessHeap(), 0, INCLUDES_INITIAL_CAPACITY);
+            if(includes == NULL)
+            {
+                ERR("Error allocating memory for the loaded includes structure\n");
+                goto end;
+            }
+            includes_capacity = INCLUDES_INITIAL_CAPACITY;
+        }
+        else
+        {
+            int newcapacity = includes_capacity * 2;
+            struct loaded_include *newincludes =
+                HeapReAlloc(GetProcessHeap(), 0, includes, newcapacity);
+            if(newincludes == NULL)
+            {
+                ERR("Error reallocating memory for the loaded includes structure\n");
+                goto end;
+            }
+            includes = newincludes;
+            includes_capacity = newcapacity;
+        }
+    }
+    includes[includes_size].name = filename;
+    includes[includes_size++].data = desc->buffer;
+
+end:
     desc->pos = 0;
     return desc;
 }
@@ -505,6 +565,7 @@ HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
         }
     }
     current_include = include;
+    includes_size = 0;
 
     if(shader) *shader = NULL;
     if(error_messages) *error_messages = NULL;
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index 5f7e776..388e74e 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1500,14 +1500,33 @@ static HRESULT WINAPI testD3DXInclude_open(ID3DXInclude *iface,
                                            LPCSTR filename, LPCVOID parent_data,
                                            LPCVOID *data, UINT *bytes) {
     char *buffer;
-    char include[] = "#define REGISTER r0\nvs.1.1\n";
-
-    trace("filename = %s\n",filename);
-
-    buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include));
-    CopyMemory(buffer, include, sizeof(include));
+    const char include[] = "#define REGISTER r0\nvs.1.1\n";
+    const char include2[] = "#include \"incl3.vsh\"\n";
+    const char include3[] = "vs.1.1\n";
+
+    trace("filename = %s\n", filename);
+    trace("parent_data = (%p) -> %s\n", parent_data, (char *)parent_data);
+
+    if(!strcmp(filename,"incl.vsh")) {
+        buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include));
+        CopyMemory(buffer, include, sizeof(include));
+        *bytes = sizeof(include);
+        /* Also check for the correct parent_data content */
+        ok(parent_data == NULL, "wrong parent_data value\n");
+    }
+    else if(!strcmp(filename,"incl3.vsh")) {
+        buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include3));
+        CopyMemory(buffer, include3, sizeof(include3));
+        *bytes = sizeof(include3);
+        /* Also check for the correct parent_data content */
+        ok(parent_data != NULL && !strncmp(include2, parent_data, strlen(include2)), "wrong parent_data value\n");
+    }
+    else {
+        buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include2));
+        CopyMemory(buffer, include2, sizeof(include2));
+        *bytes = sizeof(include2);
+    }
     *data = buffer;
-    *bytes = sizeof(include);
     return S_OK;
 }
 
@@ -1538,6 +1557,10 @@ static void assembleshader_test(void) {
         "#include \"incl.vsh\"\n"
         "mov REGISTER, v0\n"
     };
+    const char testshader2[] = {
+        "#include \"incl2.vsh\"\n"
+        "mov REGISTER, v0\n"
+    };
     HRESULT hr;
     LPD3DXBUFFER shader, messages;
     D3DXMACRO defines[] = {
@@ -1600,6 +1623,32 @@ static void assembleshader_test(void) {
     }
     if(shader) ID3DXBuffer_Release(shader);
 
+    /* "unexpected #include file from memory" test */
+    shader = NULL;
+    messages = NULL;
+    hr = D3DXAssembleShader(testshader, strlen(testshader),
+                            NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+                            &shader, &messages);
+    ok(hr == D3DXERR_INVALIDDATA, "D3DXAssembleShader 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);
+    }
+    if(shader) ID3DXBuffer_Release(shader);
+
+    /* recursive #include test */
+    shader = NULL;
+    messages = NULL;
+    hr = D3DXAssembleShader(testshader2, strlen(testshader2),
+                            NULL, (LPD3DXINCLUDE)&include, D3DXSHADER_SKIPVALIDATION,
+                            &shader, &messages);
+    ok(hr == D3D_OK, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+    if(messages) {
+        trace("recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+        ID3DXBuffer_Release(messages);
+    }
+    if(shader) ID3DXBuffer_Release(shader);
+
     todo_wine {
 
     shader_vsh_res = create_file("shader.vsh", testshader, sizeof(testshader));
-- 
1.7.1


More information about the wine-patches mailing list