Module: wine Branch: master Commit: 2a62616ac7301b20edd9e6cc20eecb740ed08ce2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2a62616ac7301b20edd9e6cc20...
Author: Matteo Bruni matteo.mystral@gmail.com Date: Wed Jul 28 17:32:42 2010 +0200
d3dx9: Handle parent_data parameter of D3DXInclude.Open() function.
---
dlls/d3dx9_36/shader.c | 70 ++++++++++++++++++++++++++++++++++++++++++++- dlls/d3dx9_36/tests/asm.c | 59 ++++++++++++++++++++++++++++++++++--- 2 files changed, 123 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 2c21773..ba23f07 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,25 @@ 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"); + return NULL; + } + }
path = malloc(strlen(filename) + 1); if(!path) return NULL; @@ -302,15 +334,50 @@ 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 error; + } + 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 error; + } + includes = newincludes; + includes_capacity = newcapacity; + } + } + includes[includes_size].name = filename; + includes[includes_size++].data = desc->buffer; + desc->pos = 0; return desc; + +error: + ID3DXInclude_Close(current_include, desc->buffer); + HeapFree(GetProcessHeap(), 0, desc); + return NULL; }
static void wpp_close_mem(void *file) @@ -505,6 +572,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));