[16/18] d3dx9: Implement D3DXAssembleShaderFromFile

Matteo Bruni matteo.mystral at gmail.com
Sun Aug 16 12:54:15 CDT 2009


-------------- next part --------------
From 46a640a3025c2862e8556eaaf46d01f54f55a7b9 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Sun, 16 Aug 2009 17:13:08 +0200
Subject: d3dx9: Implement D3DXAssembleShaderFromFile

---
 dlls/d3dx9_36/d3dx9_36.spec |    4 +-
 dlls/d3dx9_36/shader.c      |  208 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 210 insertions(+), 2 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index 7afd10c..0d39114 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -1,6 +1,6 @@
 @ stdcall D3DXAssembleShader(ptr long ptr ptr long ptr ptr)
-@ stub D3DXAssembleShaderFromFileA
-@ stub D3DXAssembleShaderFromFileW
+@ stdcall D3DXAssembleShaderFromFileA(str ptr ptr long ptr ptr)
+@ stdcall D3DXAssembleShaderFromFileW(wstr ptr ptr long ptr ptr)
 @ stub D3DXAssembleShaderFromResourceA
 @ stub D3DXAssembleShaderFromResourceW
 @ stdcall D3DXBoxBoundProbe(ptr ptr ptr ptr)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index a6de032..eb14eb5 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -403,3 +403,211 @@ HRESULT WINAPI D3DXAssembleShader(LPCSTR pSrcData, UINT SrcDataLen,
     LeaveCriticalSection(&mutex);
     return hr;
 }
+
+char *wpp_lookup_win( const char *name, const char *parent_name,
+                      char **include_path, int include_path_count )
+{
+    char *path;
+    int i;
+    HANDLE file;
+
+    TRACE("Looking up for include file %s, parent %s\n", name, parent_name);
+
+    if(current_include != NULL)
+    {
+        /* We can't know if the include can be resolved, here we return
+         * always ok (accepting the given filename). The following loadfile
+         * eventually will fail. */
+        path = malloc(strlen(name) + 1);
+        strcpy(path, name);
+        return path;
+    }
+
+    if(parent_name)
+    {
+        /* Search directory of parent include and then -I path */
+        const char *p;
+
+        if ((p = strrchr( parent_name, '\\' ))) p++;
+        else p = parent_name;
+        path = malloc( (p - parent_name) + strlen(name) + 1 );
+        memcpy( path, parent_name, p - parent_name );
+        strcpy( path + (p - parent_name), name );
+        file = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                           FILE_ATTRIBUTE_NORMAL, NULL);
+        if (file != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle( file );
+            return path;
+        }
+        free( path );
+    }
+    /* Search -I path */
+    for(i = 0; i < include_path_count; i++)
+    {
+        path = malloc(strlen(include_path[i]) + strlen(name) + 2);
+        strcpy(path, include_path[i]);
+        strcat(path, "\\");
+        strcat(path, name);
+        file = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                           FILE_ATTRIBUTE_NORMAL, NULL);
+        if (file != INVALID_HANDLE_VALUE)
+        {
+            CloseHandle( file );
+            return path;
+        }
+        free( path );
+    }
+    return NULL;
+}
+
+void *wpp_open_win(const char *filename, int type)
+{
+    HANDLE file;
+
+    TRACE("Opening file %s\n", filename);
+
+    if(current_include != NULL)
+    {
+        HRESULT hr;
+        struct mem_file_desc *desc;
+
+        desc = malloc(sizeof(struct mem_file_desc));
+        if(!desc)
+        {
+            ERR("Error allocating memory\n");
+            return NULL;
+        }
+        hr = ID3DXInclude_Open(current_include,
+                               type ? D3DXINC_SYSTEM : D3DXINC_LOCAL,
+                               filename, NULL, (LPCVOID *)&desc->buffer,
+                               &desc->size);
+        if(FAILED(hr))
+        {
+            free(desc);
+            return NULL;
+        }
+        desc->pos = 0;
+        TRACE("Opened file, desc %p\n",desc);
+        return desc;
+    }
+
+    file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                       FILE_ATTRIBUTE_NORMAL, NULL);
+    if (file == INVALID_HANDLE_VALUE) return NULL;
+    return file;
+}
+
+void wpp_close_win(void *file)
+{
+    TRACE("Closing file %p\n",file);
+
+    if(current_include != NULL)
+    {
+        struct mem_file_desc *desc = file;
+
+        ID3DXInclude_Close(current_include, desc->buffer);
+        free(desc);
+    }
+    else CloseHandle(file);
+}
+
+int wpp_read_win(void *file, char *buffer, unsigned int len)
+{
+    DWORD bytesRead;
+
+    if(current_include != NULL)
+    {
+        struct mem_file_desc *desc = file;
+
+        if(desc->pos + len > desc->size) len = desc->size - desc->pos;
+        memcpy(buffer, &desc->buffer[desc->pos], len);
+        desc->pos += len;
+        return len;
+    }
+
+    if(!ReadFile(file, buffer, len, &bytesRead, NULL)) return 0;
+    return bytesRead;
+}
+
+HRESULT WINAPI D3DXAssembleShaderFromFileA(LPCSTR pSrcFile,
+                                           CONST D3DXMACRO* pDefines,
+                                           LPD3DXINCLUDE pInclude,
+                                           DWORD Flags,
+                                           LPD3DXBUFFER* ppShader,
+                                           LPD3DXBUFFER* ppErrorMsgs)
+{
+    LPWSTR pSrcFileW = NULL;
+    DWORD len;
+    HRESULT ret;
+
+    if (!pSrcFile) return D3DXERR_INVALIDDATA;
+
+    len = MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, NULL, 0 );
+    pSrcFileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+    MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, pSrcFileW, len );
+    ret=D3DXAssembleShaderFromFileW(pSrcFileW, pDefines, pInclude, Flags, ppShader, ppErrorMsgs);
+    HeapFree( GetProcessHeap(), 0, pSrcFileW );
+    return ret;
+}
+
+HRESULT WINAPI D3DXAssembleShaderFromFileW(LPCWSTR pSrcFile,
+                                           CONST D3DXMACRO* pDefines,
+                                           LPD3DXINCLUDE pInclude,
+                                           DWORD Flags,
+                                           LPD3DXBUFFER* ppShader,
+                                           LPD3DXBUFFER* ppErrorMsgs)
+{
+    DWORD len;
+    int ret;
+    char *pSrcFileA;
+    HRESULT hr;
+
+    struct wpp_io_callback wpp_callback = {
+        wpp_lookup_win,
+        wpp_open_win,
+        wpp_close_win,
+        wpp_read_win,
+        wpp_write_mem,
+    };
+
+    EnterCriticalSection(&mutex);
+
+    /* TODO: Flags */
+    if(Flags) FIXME("Flags: %x\n", Flags);
+
+    if(pDefines != NULL)
+    {
+        while(pDefines->Name != NULL)
+        {
+            wpp_add_define(pDefines->Name, pDefines->Definition);
+            pDefines++;
+        }
+    }
+    current_include = pInclude;
+
+    *ppShader = *ppErrorMsgs = NULL;
+    wpp_output_size = wpp_output_capacity = 0;
+
+    /* Preprocess shader */
+    wpp_set_callback(&wpp_callback);
+    wpp_set_exit_on_error(0);
+    len = WideCharToMultiByte( CP_ACP, 0, pSrcFile, -1, NULL, 0, NULL, NULL );
+    pSrcFileA = HeapAlloc( GetProcessHeap(), 0, len * sizeof(CHAR) );
+    WideCharToMultiByte( CP_ACP, 0, pSrcFile, -1, pSrcFileA, len, NULL, NULL );
+
+    ret = wpp_parse(pSrcFileA, NULL);
+    wpp_close_output();
+    HeapFree( GetProcessHeap(), 0, pSrcFileA );
+    if(ret)
+    {
+        TRACE("Error during shader preprocessing\n");
+        free(wpp_output);
+        LeaveCriticalSection(&mutex);
+        return D3DXERR_INVALIDDATA;
+    }
+
+    hr = assemble_shader(wpp_output, ppShader, ppErrorMsgs);
+    LeaveCriticalSection(&mutex);
+    return hr;
+}
-- 
1.6.3.3


More information about the wine-patches mailing list