diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 30912f1668f..75e173f873d 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1764,38 +1764,29 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac const DWORD *pFunction, const struct wined3d_shader_signature *output_signature, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexShaderImpl *object; /* NOTE: impl usage is ok, this is a create */ - HRESULT hr = WINED3D_OK; - - if (!pFunction) return WINED3DERR_INVALIDCALL; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DVertexShaderImpl *object; + HRESULT hr; object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); if (!object) { - ERR("Out of memory\n"); - *ppVertexShader = NULL; - return WINED3DERR_OUTOFVIDEOMEMORY; + ERR("Failed to allocate shader memory.\n"); + return E_OUTOFMEMORY; } - object->lpVtbl = &IWineD3DVertexShader_Vtbl; - object->parent = parent; - shader_init(&object->baseShader, iface); - list_add_head(&This->shaders, &object->baseShader.shader_list_entry); - *ppVertexShader = (IWineD3DVertexShader *)object; - - TRACE("(%p) : Created vertex shader %p\n", This, *ppVertexShader); - - hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction, output_signature); + hr = vertexshader_init(object, This, pFunction, output_signature, parent); if (FAILED(hr)) { - WARN("(%p) : Failed to set function, returning %#x\n", iface, hr); - IWineD3DVertexShader_Release(*ppVertexShader); - *ppVertexShader = NULL; + WARN("Failed to initialize vertex shader, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); return hr; } - return hr; + TRACE("Created vertex shader %p.\n", object); + *ppVertexShader = (IWineD3DVertexShader *)object; + + return WINED3D_OK; } static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index d24ecd6364a..ea700baba61 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -332,7 +332,7 @@ static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertex return WINED3D_OK; } -const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = +static const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl = { /*** IUnknown methods ***/ IWineD3DVertexShaderImpl_QueryInterface, @@ -352,3 +352,27 @@ void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockIm args->fog_src = stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z; args->swizzle_map = ((IWineD3DDeviceImpl *)shader->baseShader.device)->strided_streams.swizzle_map; } + +HRESULT vertexshader_init(IWineD3DVertexShaderImpl *shader, IWineD3DDeviceImpl *device, + const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, + IUnknown *parent) +{ + HRESULT hr; + + if (!byte_code) return WINED3DERR_INVALIDCALL; + + shader->lpVtbl = &IWineD3DVertexShader_Vtbl; + shader->parent = parent; + shader_init(&shader->baseShader, (IWineD3DDevice *)device); + list_add_head(&device->shaders, &shader->baseShader.shader_list_entry); + + hr = IWineD3DVertexShader_SetFunction((IWineD3DVertexShader *)shader, byte_code, output_signature); + if (FAILED(hr)) + { + WARN("Failed to set function, hr %#x.\n", hr); + shader_cleanup((IWineD3DBaseShader *)shader); + return hr; + } + + return WINED3D_OK; +} diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 11f8c99326b..784b024387b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2775,10 +2775,12 @@ typedef struct IWineD3DVertexShaderImpl { UINT min_rel_offset, max_rel_offset; UINT rel_offset; } IWineD3DVertexShaderImpl; -extern const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl DECLSPEC_HIDDEN; void find_vs_compile_args(IWineD3DVertexShaderImpl *shader, IWineD3DStateBlockImpl *stateblock, struct vs_compile_args *args) DECLSPEC_HIDDEN; +HRESULT vertexshader_init(IWineD3DVertexShaderImpl *shader, IWineD3DDeviceImpl *device, + const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, + IUnknown *parent) DECLSPEC_HIDDEN; /***************************************************************************** * IDirect3DPixelShader implementation structure