diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 058d8dcbdae..d0bc584dad3 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -168,9 +168,13 @@ struct d3d10_geometry_shader { const struct ID3D10GeometryShaderVtbl *vtbl; LONG refcount; + + IWineD3DGeometryShader *wined3d_shader; + struct wined3d_shader_signature output_signature; }; -HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader); +HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct d3d10_device *device, + const void *byte_code, SIZE_T byte_code_length) DECLSPEC_HIDDEN; /* ID3D10PixelShader */ struct d3d10_pixel_shader diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 39be2ef5eae..191e681a3d9 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -848,6 +848,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateVertexShader(ID3D10Device *i static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShader(ID3D10Device *iface, const void *byte_code, SIZE_T byte_code_length, ID3D10GeometryShader **shader) { + struct d3d10_device *This = (struct d3d10_device *)iface; struct d3d10_geometry_shader *object; HRESULT hr; @@ -861,7 +862,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateGeometryShader(ID3D10Device return E_OUTOFMEMORY; } - hr = d3d10_geometry_shader_init(object); + hr = d3d10_geometry_shader_init(object, This, byte_code, byte_code_length); if (FAILED(hr)) { WARN("Failed to initialize geometry shader, hr %#x.\n", hr); diff --git a/dlls/d3d10core/shader.c b/dlls/d3d10core/shader.c index e8602b505c1..256f2811eb6 100644 --- a/dlls/d3d10core/shader.c +++ b/dlls/d3d10core/shader.c @@ -313,7 +313,7 @@ static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShade if (!refcount) { - HeapFree(GetProcessHeap(), 0, This); + IWineD3DGeometryShader_Release(This->wined3d_shader); } return refcount; @@ -365,11 +365,45 @@ static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl = d3d10_geometry_shader_SetPrivateDataInterface, }; -HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader) +static void STDMETHODCALLTYPE d3d10_geometry_shader_wined3d_object_destroyed(void *parent) { + struct d3d10_geometry_shader *shader = parent; + shader_free_signature(&shader->output_signature); + HeapFree(GetProcessHeap(), 0, shader); +} + +static const struct wined3d_parent_ops d3d10_geometry_shader_wined3d_parent_ops = +{ + d3d10_geometry_shader_wined3d_object_destroyed, +}; + +HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct d3d10_device *device, + const void *byte_code, SIZE_T byte_code_length) +{ + struct d3d10_shader_info shader_info; + HRESULT hr; + shader->vtbl = &d3d10_geometry_shader_vtbl; shader->refcount = 1; + shader_info.output_signature = &shader->output_signature; + hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info); + if (FAILED(hr)) + { + ERR("Failed to extract shader, hr %#x.\n", hr); + return hr; + } + + hr = IWineD3DDevice_CreateGeometryShader(device->wined3d_device, + shader_info.shader_code, &shader->output_signature, &shader->wined3d_shader, + (IUnknown *)shader, &d3d10_geometry_shader_wined3d_parent_ops); + if (FAILED(hr)) + { + WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr); + shader_free_signature(&shader->output_signature); + return hr; + } + return S_OK; }