Module: wine Branch: master Commit: 41401fb8cffb895b66648ed31fb5266e8121d665 URL: http://source.winehq.org/git/wine.git/?a=commit;h=41401fb8cffb895b66648ed31f...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Sun Jan 3 21:18:23 2010 +0100
wined3d: Add a geometry shader object.
This is just the object used to store the byte code, the shader compiler doesn't know how to handle geometry shaders yet.
---
dlls/wined3d/device.c | 31 +++++++++++++ dlls/wined3d/shader.c | 98 ++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 10 ++++ include/wine/wined3d.idl | 16 +++++++ 4 files changed, 155 insertions(+), 0 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d0660b4..78db960 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1181,6 +1181,36 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *ifac return WINED3D_OK; }
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateGeometryShader(IWineD3DDevice *iface, + const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, + IWineD3DGeometryShader **shader, IUnknown *parent, + const struct wined3d_parent_ops *parent_ops) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + struct wined3d_geometryshader *object; + HRESULT hr; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate shader memory.\n"); + return E_OUTOFMEMORY; + } + + hr = geometryshader_init(object, This, byte_code, output_signature, parent, parent_ops); + if (FAILED(hr)) + { + WARN("Failed to initialize geometry shader, hr %#x.\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created geometry shader %p.\n", object); + *shader = (IWineD3DGeometryShader *)object; + + return WINED3D_OK; +} + static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface, const DWORD *pFunction, const struct wined3d_shader_signature *output_signature, IWineD3DPixelShader **ppPixelShader, IUnknown *parent, @@ -6804,6 +6834,7 @@ static const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_CreateVertexDeclaration, IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF, IWineD3DDeviceImpl_CreateVertexShader, + IWineD3DDeviceImpl_CreateGeometryShader, IWineD3DDeviceImpl_CreatePixelShader, IWineD3DDeviceImpl_CreatePalette, /*** Odd functions **/ diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 01ddfe6..398ea64 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -400,6 +400,104 @@ HRESULT vertexshader_init(IWineD3DVertexShaderImpl *shader, IWineD3DDeviceImpl * return WINED3D_OK; }
+static HRESULT STDMETHODCALLTYPE geometryshader_QueryInterface(IWineD3DGeometryShader *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IWineD3DGeometryShader) + || IsEqualGUID(riid, &IID_IWineD3DBaseShader) + || IsEqualGUID(riid, &IID_IWineD3DBase) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE geometryshader_AddRef(IWineD3DGeometryShader *iface) +{ + struct wined3d_geometryshader *shader = (struct wined3d_geometryshader *)iface; + ULONG refcount = InterlockedIncrement(&shader->base_shader.ref); + + TRACE("%p increasing refcount to %u.\n", shader, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE geometryshader_Release(IWineD3DGeometryShader *iface) +{ + struct wined3d_geometryshader *shader = (struct wined3d_geometryshader *)iface; + ULONG refcount = InterlockedDecrement(&shader->base_shader.ref); + + TRACE("%p decreasing refcount to %u.\n", shader, refcount); + + if (!refcount) + { + shader_cleanup((IWineD3DBaseShader *)iface); + shader->base_shader.parent_ops->wined3d_object_destroyed(shader->base_shader.parent); + HeapFree(GetProcessHeap(), 0, shader); + } + + return refcount; +} + +static HRESULT STDMETHODCALLTYPE geometryshader_GetParent(IWineD3DGeometryShader *iface, IUnknown **parent) +{ + TRACE("iface %p, parent %p.\n", iface, parent); + + shader_get_parent((IWineD3DBaseShaderImpl *)iface, parent); + + return WINED3D_OK; +} + +static HRESULT STDMETHODCALLTYPE geometryshader_GetFunction(IWineD3DGeometryShader *iface, void *data, UINT *data_size) +{ + TRACE("iface %p, data %p, data_size %p.\n", iface, data, data_size); + + return shader_get_function((IWineD3DBaseShaderImpl *)iface, data, data_size); +} + +static const IWineD3DGeometryShaderVtbl wined3d_geometryshader_vtbl = +{ + /* IUnknown methods */ + geometryshader_QueryInterface, + geometryshader_AddRef, + geometryshader_Release, + /* IWineD3DBase methods */ + geometryshader_GetParent, + /* IWineD3DBaseShader methods */ + geometryshader_GetFunction, +}; + +HRESULT geometryshader_init(struct wined3d_geometryshader *shader, IWineD3DDeviceImpl *device, + const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) +{ + HRESULT hr; + + shader->vtbl = &wined3d_geometryshader_vtbl; + shader_init(&shader->base_shader, device, parent, parent_ops); + + hr = shader_set_function((IWineD3DBaseShaderImpl *)shader, byte_code, output_signature, 0); + if (FAILED(hr)) + { + WARN("Failed to set function, hr %#x.\n", hr); + shader_cleanup((IWineD3DBaseShader *)shader); + return hr; + } + + shader->base_shader.load_local_constsF = FALSE; + + return WINED3D_OK; +} + static HRESULT STDMETHODCALLTYPE pixelshader_QueryInterface(IWineD3DPixelShader *iface, REFIID riid, void **object) { TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3cb0942..e95cbdf 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2749,6 +2749,16 @@ HRESULT vertexshader_init(IWineD3DVertexShaderImpl *shader, IWineD3DDeviceImpl * const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+struct wined3d_geometryshader +{ + const struct IWineD3DGeometryShaderVtbl *vtbl; + IWineD3DBaseShaderClass base_shader; +}; + +HRESULT geometryshader_init(struct wined3d_geometryshader *shader, IWineD3DDeviceImpl *device, + const DWORD *byte_code, const struct wined3d_shader_signature *output_signature, + IUnknown *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + /***************************************************************************** * IDirect3DPixelShader implementation structure */ diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index 7c44b5e..16ae443 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -2844,6 +2844,15 @@ interface IWineD3DVertexShader : IWineD3DBaseShader [ object, local, + uuid(8276c113-388b-49d1-ad8b-c9dd8bcbabcd) +] +interface IWineD3DGeometryShader : IWineD3DBaseShader +{ +} + +[ + object, + local, uuid(818503da-6f30-11d9-c687-00046142c14f) ] interface IWineD3DPixelShader : IWineD3DBaseShader @@ -2981,6 +2990,13 @@ interface IWineD3DDevice : IWineD3DBase [in] IUnknown *parent, [in] const struct wined3d_parent_ops *parent_ops ); + HRESULT CreateGeometryShader( + [in] const DWORD *byte_code, + [in] const struct wined3d_shader_signature *output_signature, + [out] IWineD3DGeometryShader **shader, + [in] IUnknown *parent, + [in] const struct wined3d_parent_ops *parent_ops + ); HRESULT CreatePixelShader( [in] const DWORD *function, [in] const struct wined3d_shader_signature *output_signature,