diff --git a/dlls/d3d10core/buffer.c b/dlls/d3d10core/buffer.c index c4f32bf75c3..a4198c16351 100644 --- a/dlls/d3d10core/buffer.c +++ b/dlls/d3d10core/buffer.c @@ -65,6 +65,7 @@ static ULONG STDMETHODCALLTYPE d3d10_buffer_Release(ID3D10Buffer *iface) if (!refcount) { + IWineD3DBuffer_Release(This->wined3d_buffer); HeapFree(GetProcessHeap(), 0, This); } diff --git a/dlls/d3d10core/d3d10core_private.h b/dlls/d3d10core/d3d10core_private.h index 263c22def02..fd689b9e500 100644 --- a/dlls/d3d10core/d3d10core_private.h +++ b/dlls/d3d10core/d3d10core_private.h @@ -74,6 +74,8 @@ struct d3d10_buffer { const struct ID3D10BufferVtbl *vtbl; LONG refcount; + + IWineD3DBuffer *wined3d_buffer; }; /* ID3D10RenderTargetView */ diff --git a/dlls/d3d10core/device.c b/dlls/d3d10core/device.c index 46e57b2acba..7c39ce5b3b9 100644 --- a/dlls/d3d10core/device.c +++ b/dlls/d3d10core/device.c @@ -560,7 +560,10 @@ static void STDMETHODCALLTYPE d3d10_device_Flush(ID3D10Device *iface) static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBuffer(ID3D10Device *iface, const D3D10_BUFFER_DESC *desc, const D3D10_SUBRESOURCE_DATA *data, ID3D10Buffer **buffer) { + struct d3d10_device *This = (struct d3d10_device *)iface; + struct wined3d_buffer_desc wined3d_desc; struct d3d10_buffer *object; + HRESULT hr; FIXME("iface %p, desc %p, data %p, buffer %p partial stub!\n", iface, desc, data, buffer); @@ -574,6 +577,23 @@ static HRESULT STDMETHODCALLTYPE d3d10_device_CreateBuffer(ID3D10Device *iface, object->vtbl = &d3d10_buffer_vtbl; object->refcount = 1; + FIXME("Implement DXGI<->wined3d usage conversion\n"); + + wined3d_desc.byte_width = desc->ByteWidth; + wined3d_desc.usage = desc->Usage; + wined3d_desc.bind_flags = desc->BindFlags; + wined3d_desc.cpu_access_flags = desc->CPUAccessFlags; + wined3d_desc.misc_flags = desc->MiscFlags; + + hr = IWineD3DDevice_CreateBuffer(This->wined3d_device, &wined3d_desc, + (IUnknown *)object, &object->wined3d_buffer); + if (FAILED(hr)) + { + ERR("CreateBuffer failed, returning %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + *buffer = (ID3D10Buffer *)object; TRACE("Created ID3D10Buffer %p\n", object); diff --git a/dlls/wined3d/Makefile.in b/dlls/wined3d/Makefile.in index 1653fdec8d5..2f8f0c0942f 100644 --- a/dlls/wined3d/Makefile.in +++ b/dlls/wined3d/Makefile.in @@ -11,6 +11,7 @@ C_SRCS = \ ati_fragment_shader.c \ baseshader.c \ basetexture.c \ + buffer.c \ clipper.c \ context.c \ cubetexture.c \ diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c new file mode 100644 index 00000000000..8a7d72dd88d --- /dev/null +++ b/dlls/wined3d/buffer.c @@ -0,0 +1,151 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "config.h" +#include "wine/port.h" + +#include "wined3d_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d); + +/* IUnknown methods */ + +static HRESULT STDMETHODCALLTYPE buffer_QueryInterface(IWineD3DBuffer *iface, + REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_IWineD3DBuffer) + || IsEqualGUID(riid, &IID_IWineD3DResource) + || 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 buffer_AddRef(IWineD3DBuffer *iface) +{ + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + ULONG refcount = InterlockedIncrement(&This->resource.ref); + + TRACE("%p increasing refcount to %u\n", This, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface) +{ + struct wined3d_buffer *This = (struct wined3d_buffer *)iface; + ULONG refcount = InterlockedDecrement(&This->resource.ref); + + TRACE("%p decreasing refcount to %u\n", This, refcount); + + if (!refcount) + { + resource_cleanup((IWineD3DResource *)iface); + HeapFree(GetProcessHeap(), 0, This); + } + + return refcount; +} + +/* IWineD3DBase methods */ + +static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknown **parent) +{ + return resource_get_parent((IWineD3DResource *)iface, parent); +} + +/* IWineD3DResource methods */ + +static HRESULT STDMETHODCALLTYPE buffer_GetDevice(IWineD3DBuffer *iface, IWineD3DDevice **device) +{ + return resource_get_device((IWineD3DResource *)iface, device); +} + +static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *iface, + REFGUID guid, const void *data, DWORD data_size, DWORD flags) +{ + return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags); +} + +static HRESULT STDMETHODCALLTYPE buffer_GetPrivateData(IWineD3DBuffer *iface, + REFGUID guid, void *data, DWORD *data_size) +{ + return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size); +} + +static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid) +{ + return resource_free_private_data((IWineD3DResource *)iface, guid); +} + +static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority) +{ + return resource_set_priority((IWineD3DResource *)iface, priority); +} + +static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface) +{ + return resource_get_priority((IWineD3DResource *)iface); +} + +static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) +{ + TRACE("iface %p\n", iface); +} + +static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface) +{ + TRACE("iface %p\n", iface); +} + +static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface) +{ + return resource_get_type((IWineD3DResource *)iface); +} + +const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = +{ + /* IUnknown methods */ + buffer_QueryInterface, + buffer_AddRef, + buffer_Release, + /* IWineD3DBase methods */ + buffer_GetParent, + /* IWineD3DResource methods */ + buffer_GetDevice, + buffer_SetPrivateData, + buffer_GetPrivateData, + buffer_FreePrivateData, + buffer_SetPriority, + buffer_GetPriority, + buffer_PreLoad, + buffer_UnLoad, + buffer_GetType, +}; diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d2297692556..6be674606b2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -133,6 +133,48 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetParent(IWineD3DDevice *iface, IUnkno return WINED3D_OK; } +static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, + struct wined3d_buffer_desc *desc, IUnknown *parent, IWineD3DBuffer **buffer) +{ + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + struct wined3d_buffer *object; + HRESULT hr; + + TRACE("iface %p, desc %p, parent %p, buffer %p\n", iface, desc, parent, buffer); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); + if (!object) + { + ERR("Failed to allocate memory\n"); + return E_OUTOFMEMORY; + } + + object->vtbl = &wined3d_buffer_vtbl; + object->desc = *desc; + + FIXME("Ignoring access flags (pool)\n"); + + hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, desc->byte_width, + desc->usage, WINED3DFMT_UNKNOWN, WINED3DPOOL_MANAGED, parent); + if (FAILED(hr)) + { + WARN("Failed to initialize resource, returning %#x\n", hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + TRACE("Created resource %p\n", object); + + IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object); + + TRACE("size %#x, usage=%#x, format %s, memory @ %p, iface @ %p\n", object->resource.size, object->resource.usage, + debug_d3dformat(object->resource.format), object->resource.allocatedMemory, object); + + *buffer = (IWineD3DBuffer *)object; + + return WINED3D_OK; +} + static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage, DWORD FVF, WINED3DPOOL Pool, IWineD3DVertexBuffer** ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent) { @@ -7478,8 +7520,12 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW This->stateBlock->pIndexData = NULL; } } - break; + + case WINED3DRTYPE_BUFFER: + /* Nothing to do, yet.*/ + break; + default: FIXME("(%p) unknown resource type %p %u\n", This, resource, IWineD3DResource_GetType(resource)); break; @@ -7524,6 +7570,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = /*** IWineD3DDevice methods ***/ IWineD3DDeviceImpl_GetParent, /*** Creation methods**/ + IWineD3DDeviceImpl_CreateBuffer, IWineD3DDeviceImpl_CreateVertexBuffer, IWineD3DDeviceImpl_CreateIndexBuffer, IWineD3DDeviceImpl_CreateStateBlock, diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index ee0e5997ffa..1b6934c4c06 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -907,6 +907,7 @@ const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) { RES_TO_STR(WINED3DRTYPE_CUBETEXTURE); RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER); RES_TO_STR(WINED3DRTYPE_INDEXBUFFER); + RES_TO_STR(WINED3DRTYPE_BUFFER); #undef RES_TO_STR default: FIXME("Unrecognized %u WINED3DRESOURCETYPE!\n", res); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 91f2f50742f..8a88cf1f2b1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1974,6 +1974,17 @@ typedef struct WineQueryEventData { WineD3DContext *ctx; } WineQueryEventData; +/* IWineD3DBuffer */ +struct wined3d_buffer +{ + const struct IWineD3DBufferVtbl *vtbl; + IWineD3DResourceClass resource; + + struct wined3d_buffer_desc desc; +}; + +extern const IWineD3DBufferVtbl wined3d_buffer_vtbl; + /***************************************************************************** * IWineD3DSwapChainImpl implementation structure (extends IUnknown) */ diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index d53aa2464bf..dc376d06c0f 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -762,6 +762,7 @@ typedef enum _WINED3DRESOURCETYPE WINED3DRTYPE_CUBETEXTURE = 5, WINED3DRTYPE_VERTEXBUFFER = 6, WINED3DRTYPE_INDEXBUFFER = 7, + WINED3DRTYPE_BUFFER = 8, WINED3DRTYPE_FORCE_DWORD = 0x7fffffff } WINED3DRESOURCETYPE; const UINT WINED3DRTYPECOUNT = WINED3DRTYPE_INDEXBUFFER + 1; @@ -2175,6 +2176,15 @@ typedef struct _WINEDDOVERLAYFX DWORD dwFlags; /* flags */ } WINEDDOVERLAYFX; +struct wined3d_buffer_desc +{ + UINT byte_width; + DWORD usage; + UINT bind_flags; + UINT cpu_access_flags; + UINT misc_flags; +}; + interface IWineD3DResource; interface IWineD3DSurface; interface IWineD3DVolume; @@ -2889,6 +2899,15 @@ interface IWineD3DSwapChain : IWineD3DBase ); } +[ + object, + local, + uuid(b3f028e8-1a40-4ab3-9292-5bf6cfd80209) +] +interface IWineD3DBuffer : IWineD3DResource +{ +} + [ object, local, @@ -2948,6 +2967,11 @@ interface IWineD3DPixelShader : IWineD3DBaseShader ] interface IWineD3DDevice : IWineD3DBase { + HRESULT CreateBuffer( + [in] struct wined3d_buffer_desc *desc, + [in] IUnknown *parent, + [out] IWineD3DBuffer **buffer + ); HRESULT CreateVertexBuffer( [in] UINT length, [in] DWORD usage,