[PATCH 2/5] wined3d: Add a geometry shader object.
Henri Verbeet
hverbeet at codeweavers.com
Sun Jan 3 14:18:23 CST 2010
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 f7fb4cd..f599478 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2748,6 +2748,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,
--
1.6.4.4
More information about the wine-patches
mailing list