[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