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);
};
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)
{
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
unsigned int i, j;
TRACE("base %p, data %p, data_size %lu, effect %p, pool %p, skip_constants %s.\n",
base, data, data_size, effect, pool, debugstr_a(skip_constants_string));
TRACE("base %p, data %p, data_size %lu, defines %p, include %p, eflags %#x, errors %p, "
"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->pool = pool;
@ -7041,9 +7043,11 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
const D3DXMACRO *defines, struct ID3DXInclude *include, const char *skipconstants, DWORD flags,
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;
DWORD size;
TRACE("device %p, srcfile %s, defines %p, include %p, skipconstants %s, "
"flags %#x, pool %p, effect %p, compilationerrors %p.\n",
@ -7053,14 +7057,33 @@ HRESULT WINAPI D3DXCreateEffectFromFileExW(struct IDirect3DDevice9 *device, cons
if (!device || !srcfile)
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))
{
LeaveCriticalSection(&from_file_mutex);
heap_free(filename_a);
return D3DXERR_INVALIDDATA;
}
ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
UnmapViewOfFile(buffer);
ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool,
effect, compilationerrors);
ID3DXInclude_Close(include, buffer);
LeaveCriticalSection(&from_file_mutex);
heap_free(filename_a);
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 CRITICAL_SECTION from_file_mutex;
static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
{
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")}
};
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
* D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
/* 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
* 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 *p, *parent_name = "";
@ -250,7 +249,7 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
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, '\\')))
++p;
@ -301,7 +300,7 @@ error:
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);
@ -310,13 +309,10 @@ static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *
return S_OK;
}
static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = {
d3dincludefromfile_open,
d3dincludefromfile_close
};
struct D3DXIncludeImpl {
ID3DXInclude ID3DXInclude_iface;
const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl =
{
d3dx_include_from_file_open,
d3dx_include_from_file_close
};
HRESULT WINAPI D3DXAssembleShaderFromFileA(const char *filename, const D3DXMACRO *defines,
@ -348,7 +344,7 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
const void *buffer;
DWORD len;
HRESULT hr;
struct D3DXIncludeImpl includefromfile;
struct d3dx_include_from_file include_from_file;
char *filename_a;
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)
{
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
include = &includefromfile.ID3DXInclude_iface;
include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &include_from_file.ID3DXInclude_iface;
}
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;
DWORD len, filename_len;
HRESULT hr;
struct D3DXIncludeImpl includefromfile;
struct d3dx_include_from_file include_from_file;
char *filename_a;
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)
{
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
include = &includefromfile.ID3DXInclude_iface;
include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &include_from_file.ID3DXInclude_iface;
}
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;
DWORD len;
HRESULT hr;
struct D3DXIncludeImpl includefromfile;
struct d3dx_include_from_file include_from_file;
char *filename_a;
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)
{
includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
include = &includefromfile.ID3DXInclude_iface;
include_from_file.ID3DXInclude_iface.lpVtbl = &d3dx_include_from_file_vtbl;
include = &include_from_file.ID3DXInclude_iface;
}
len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);