d3dx9: Fix handling of includes in D3DXCreateEffectFromFileExW().

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Matteo Bruni 2018-03-22 21:43:04 +01:00 committed by Alexandre Julliard
parent 9a7cb34d0f
commit f5b888a708
3 changed files with 55 additions and 28 deletions

View File

@ -69,6 +69,14 @@ struct pixel_format_desc {
void (*to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette); void (*to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette);
}; };
struct d3dx_include_from_file
{
ID3DXInclude ID3DXInclude_iface;
};
extern CRITICAL_SECTION from_file_mutex DECLSPEC_HIDDEN;
extern const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl DECLSPEC_HIDDEN;
static inline BOOL is_conversion_from_supported(const struct pixel_format_desc *format) static inline BOOL is_conversion_from_supported(const struct pixel_format_desc *format)
{ {
if (format->type == FORMAT_ARGB || format->type == FORMAT_ARGBF16 if (format->type == FORMAT_ARGB || format->type == FORMAT_ARGBF16

View File

@ -6664,8 +6664,10 @@ static HRESULT d3dx9_base_effect_init(struct d3dx9_base_effect *base,
#endif #endif
unsigned int i, j; unsigned int i, j;
TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n", TRACE("base %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
base, data, data_size, effect, pool, debugstr_a(skip_constants_string)); "effect %p, pool %p, skip_constants %s.\n",
base, data, data_size, defines, include, eflags, errors, effect, pool,
debugstr_a(skip_constants_string));
base->effect = effect; base->effect = effect;
base->pool = pool; base->pool = pool;
@ -7041,9 +7043,11 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags, const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors) struct ID3DXEffectPool *pool, struct ID3DXEffect **effect, struct ID3DXBuffer **compilationerrors)
{ {
void *buffer; struct d3dx_include_from_file include_from_file;
const void *buffer;
unsigned int size;
char *filename_a;
HRESULT ret; HRESULT ret;
DWORD size;
TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, " TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
"flags %#x, pool %p, effect %p, compilationerrors %p.\n", "flags %#x, pool %p, effect %p, compilationerrors %p.\n",
@ -7053,14 +7057,33 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
if (!device || !srcfile) if (!device || !srcfile)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
ret = map_view_of_file(srcfile, &buffer, &size); if (!include)
{
include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &include_from_file.ID3DXInclude_iface;
}
size = WideCharToMultiByte(CP_ACP, 0, srcfile, -1, NULL, 0, NULL, NULL);
filename_a = heap_alloc(size);
if (!filename_a)
return E_OUTOFMEMORY;
WideCharToMultiByte(CP_ACP, 0, srcfile, -1, filename_a, size, NULL, NULL);
EnterCriticalSection(&from_file_mutex);
ret = ID3DXInclude_Open(include, D3DXINC_LOCAL, filename_a, NULL, &buffer, &size);
if (FAILED(ret)) if (FAILED(ret))
{
LeaveCriticalSection(&from_file_mutex);
heap_free(filename_a);
return D3DXERR_INVALIDDATA; return D3DXERR_INVALIDDATA;
}
ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors); ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
UnmapViewOfFile(buffer); effect, compilationerrors);
ID3DXInclude_Close(include, buffer);
LeaveCriticalSection(&from_file_mutex);
heap_free(filename_a);
return ret; return ret;
} }

View File

@ -214,7 +214,6 @@ HRESULT WINAPI D3DXAssembleShader(const char *data, UINT data_len, const D3DXMAC
static const void *main_file_data; static const void *main_file_data;
static CRITICAL_SECTION from_file_mutex;
static CRITICAL_SECTION_DEBUG from_file_mutex_debug = static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
{ {
0, 0, &from_file_mutex, 0, 0, &from_file_mutex,
@ -224,14 +223,14 @@ static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
}, },
0, 0, {(DWORD_PTR)(__FILE__ ": from_file_mutex")} 0, 0, {(DWORD_PTR)(__FILE__ ": from_file_mutex")}
}; };
static CRITICAL_SECTION from_file_mutex = {&from_file_mutex_debug, -1, 0, 0, 0, 0}; CRITICAL_SECTION from_file_mutex = {&from_file_mutex_debug, -1, 0, 0, 0, 0};
/* D3DXInclude private implementation, used to implement /* D3DXInclude private implementation, used to implement
* D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */ * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
/* To be able to correctly resolve include search paths we have to store the /* To be able to correctly resolve include search paths we have to store the
* pathname of each include file. We store the pathname pointer right before * pathname of each include file. We store the pathname pointer right before
* the file data. */ * the file data. */
static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type, static HRESULT WINAPI d3dx_include_from_file_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type,
const char *filename, const void *parent_data, const void **data, UINT *bytes) const char *filename, const void *parent_data, const void **data, UINT *bytes)
{ {
const char *p, *parent_name = ""; const char *p, *parent_name = "";
@ -250,7 +249,7 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
parent_name = *((const char **)main_file_data - 1); parent_name = *((const char **)main_file_data - 1);
} }
TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename), debugstr_a(parent_name)); TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename), debugstr_a(parent_name));
if ((p = strrchr(parent_name, '\\'))) if ((p = strrchr(parent_name, '\\')))
++p; ++p;
@ -301,7 +300,7 @@ error:
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
} }
static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *data) static HRESULT WINAPI d3dx_include_from_file_close(ID3DXInclude *iface, const void *data)
{ {
HeapFree(GetProcessHeap(), 0, *((char **)data - 1)); HeapFree(GetProcessHeap(), 0, *((char **)data - 1));
HeapFree(GetProcessHeap(), 0, (char **)data - 1); HeapFree(GetProcessHeap(), 0, (char **)data - 1);
@ -310,13 +309,10 @@ static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *
return S_OK; return S_OK;
} }
static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = { const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl =
d3dincludefromfile_open, {
d3dincludefromfile_close d3dx_include_from_file_open,
}; d3dx_include_from_file_close
struct D3DXIncludeImpl {
ID3DXInclude ID3DXInclude_iface;
}; };
HRESULT WINAPI D3DXAssembleShaderFromFileA(const char *filename, const D3DXMACRO *defines, HRESULT WINAPI D3DXAssembleShaderFromFileA(const char *filename, const D3DXMACRO *defines,
@ -348,7 +344,7 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
const void *buffer; const void *buffer;
DWORD len; DWORD len;
HRESULT hr; HRESULT hr;
struct D3DXIncludeImpl includefromfile; struct d3dx_include_from_file include_from_file;
char *filename_a; char *filename_a;
TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n", TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
@ -356,8 +352,8 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
if(!include) if(!include)
{ {
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl; include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &includefromfile.ID3DXInclude_iface; include = &include_from_file.ID3DXInclude_iface;
} }
len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL); len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
@ -481,7 +477,7 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
const void *buffer; const void *buffer;
DWORD len, filename_len; DWORD len, filename_len;
HRESULT hr; HRESULT hr;
struct D3DXIncludeImpl includefromfile; struct d3dx_include_from_file include_from_file;
char *filename_a; char *filename_a;
TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, " TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
@ -491,8 +487,8 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
if (!include) if (!include)
{ {
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl; include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &includefromfile.ID3DXInclude_iface; include = &include_from_file.ID3DXInclude_iface;
} }
filename_len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL); filename_len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
@ -606,7 +602,7 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
const void *buffer; const void *buffer;
DWORD len; DWORD len;
HRESULT hr; HRESULT hr;
struct D3DXIncludeImpl includefromfile; struct d3dx_include_from_file include_from_file;
char *filename_a; char *filename_a;
TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n", TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
@ -614,8 +610,8 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
if (!include) if (!include)
{ {
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl; include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &includefromfile.ID3DXInclude_iface; include = &include_from_file.ID3DXInclude_iface;
} }
len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL); len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);