* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
#include "d3d9_private.h"
-WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
-
-typedef struct _D3DDECLTYPE_INFO {
- D3DDECLTYPE d3dType;
+static const struct
+{
enum wined3d_format_id format;
- int size;
- int typesize;
-} D3DDECLTYPE_INFO;
-
-static D3DDECLTYPE_INFO const d3d_dtype_lookup[D3DDECLTYPE_UNUSED] = {
- {D3DDECLTYPE_FLOAT1, WINED3DFMT_R32_FLOAT, 1, sizeof(float)},
- {D3DDECLTYPE_FLOAT2, WINED3DFMT_R32G32_FLOAT, 2, sizeof(float)},
- {D3DDECLTYPE_FLOAT3, WINED3DFMT_R32G32B32_FLOAT, 3, sizeof(float)},
- {D3DDECLTYPE_FLOAT4, WINED3DFMT_R32G32B32A32_FLOAT, 4, sizeof(float)},
- {D3DDECLTYPE_D3DCOLOR, WINED3DFMT_B8G8R8A8_UNORM, 4, sizeof(BYTE)},
- {D3DDECLTYPE_UBYTE4, WINED3DFMT_R8G8B8A8_UINT, 4, sizeof(BYTE)},
- {D3DDECLTYPE_SHORT2, WINED3DFMT_R16G16_SINT, 2, sizeof(short int)},
- {D3DDECLTYPE_SHORT4, WINED3DFMT_R16G16B16A16_SINT, 4, sizeof(short int)},
- {D3DDECLTYPE_UBYTE4N, WINED3DFMT_R8G8B8A8_UNORM, 4, sizeof(BYTE)},
- {D3DDECLTYPE_SHORT2N, WINED3DFMT_R16G16_SNORM, 2, sizeof(short int)},
- {D3DDECLTYPE_SHORT4N, WINED3DFMT_R16G16B16A16_SNORM, 4, sizeof(short int)},
- {D3DDECLTYPE_USHORT2N, WINED3DFMT_R16G16_UNORM, 2, sizeof(short int)},
- {D3DDECLTYPE_USHORT4N, WINED3DFMT_R16G16B16A16_UNORM, 4, sizeof(short int)},
- {D3DDECLTYPE_UDEC3, WINED3DFMT_R10G10B10A2_UINT, 3, sizeof(short int)},
- {D3DDECLTYPE_DEC3N, WINED3DFMT_R10G10B10A2_SNORM, 3, sizeof(short int)},
- {D3DDECLTYPE_FLOAT16_2, WINED3DFMT_R16G16_FLOAT, 2, sizeof(short int)},
- {D3DDECLTYPE_FLOAT16_4, WINED3DFMT_R16G16B16A16_FLOAT, 4, sizeof(short int)}};
-
-#define D3D_DECL_SIZE(type) d3d_dtype_lookup[type].size
-#define D3D_DECL_TYPESIZE(type) d3d_dtype_lookup[type].typesize
+ unsigned int component_count;
+ unsigned int component_size;
+}
+d3d_dtype_lookup[] =
+{
+ /* D3DDECLTYPE_FLOAT1 */ {WINED3DFMT_R32_FLOAT, 1, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT2 */ {WINED3DFMT_R32G32_FLOAT, 2, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT3 */ {WINED3DFMT_R32G32B32_FLOAT, 3, sizeof(float)},
+ /* D3DDECLTYPE_FLOAT4 */ {WINED3DFMT_R32G32B32A32_FLOAT, 4, sizeof(float)},
+ /* D3DDECLTYPE_D3DCOLOR */ {WINED3DFMT_B8G8R8A8_UNORM, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_UBYTE4 */ {WINED3DFMT_R8G8B8A8_UINT, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_SHORT2 */ {WINED3DFMT_R16G16_SINT, 2, sizeof(short int)},
+ /* D3DDECLTYPE_SHORT4 */ {WINED3DFMT_R16G16B16A16_SINT, 4, sizeof(short int)},
+ /* D3DDECLTYPE_UBYTE4N */ {WINED3DFMT_R8G8B8A8_UNORM, 4, sizeof(BYTE)},
+ /* D3DDECLTYPE_SHORT2N */ {WINED3DFMT_R16G16_SNORM, 2, sizeof(short int)},
+ /* D3DDECLTYPE_SHORT4N */ {WINED3DFMT_R16G16B16A16_SNORM, 4, sizeof(short int)},
+ /* D3DDECLTYPE_USHORT2N */ {WINED3DFMT_R16G16_UNORM, 2, sizeof(short int)},
+ /* D3DDECLTYPE_USHORT4N */ {WINED3DFMT_R16G16B16A16_UNORM, 4, sizeof(short int)},
+ /* D3DDECLTYPE_UDEC3 */ {WINED3DFMT_R10G10B10X2_UINT, 3, sizeof(short int)},
+ /* D3DDECLTYPE_DEC3N */ {WINED3DFMT_R10G10B10X2_SNORM, 3, sizeof(short int)},
+ /* D3DDECLTYPE_FLOAT16_2 */ {WINED3DFMT_R16G16_FLOAT, 2, sizeof(short int)},
+ /* D3DDECLTYPE_FLOAT16_4 */ {WINED3DFMT_R16G16B16A16_FLOAT, 4, sizeof(short int)}
+};
+
+static inline struct d3d9_vertex_declaration *impl_from_IDirect3DVertexDeclaration9(IDirect3DVertexDeclaration9 *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3d9_vertex_declaration, IDirect3DVertexDeclaration9_iface);
+}
HRESULT vdecl_convert_fvf(
DWORD fvf,
elements[idx].Stream = 0;
elements[idx].Method = D3DDECLMETHOD_DEFAULT;
elements[idx].Offset = offset;
- offset += D3D_DECL_SIZE(elements[idx].Type) * D3D_DECL_TYPESIZE(elements[idx].Type);
+ offset += d3d_dtype_lookup[elements[idx].Type].component_count
+ * d3d_dtype_lookup[elements[idx].Type].component_size;
}
*ppVertexElements = elements;
return D3D_OK;
}
-/* IDirect3DVertexDeclaration9 IUnknown parts follow: */
-static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_QueryInterface(LPDIRECT3DVERTEXDECLARATION9 iface, REFIID riid, LPVOID* ppobj) {
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
-
- TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
+static HRESULT WINAPI d3d9_vertex_declaration_QueryInterface(IDirect3DVertexDeclaration9 *iface,
+ REFIID riid, void **out)
+{
+ TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
- if (IsEqualGUID(riid, &IID_IUnknown)
- || IsEqualGUID(riid, &IID_IDirect3DVertexDeclaration9)) {
+ if (IsEqualGUID(riid, &IID_IDirect3DVertexDeclaration9)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
IDirect3DVertexDeclaration9_AddRef(iface);
- *ppobj = This;
+ *out = iface;
return S_OK;
}
- WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
- *ppobj = NULL;
+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+
+ *out = NULL;
return E_NOINTERFACE;
}
-static ULONG WINAPI IDirect3DVertexDeclaration9Impl_AddRef(LPDIRECT3DVERTEXDECLARATION9 iface) {
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("%p increasing refcount to %u.\n", iface, ref);
-
- if(ref == 1) {
- IDirect3DDevice9Ex_AddRef(This->parentDevice);
- if (!This->convFVF)
- {
- wined3d_mutex_lock();
- wined3d_vertex_declaration_incref(This->wineD3DVertexDeclaration);
- wined3d_mutex_unlock();
- }
- }
-
- return ref;
-}
+static ULONG WINAPI d3d9_vertex_declaration_AddRef(IDirect3DVertexDeclaration9 *iface)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+ ULONG refcount = InterlockedIncrement(&declaration->refcount);
-void IDirect3DVertexDeclaration9Impl_Destroy(LPDIRECT3DVERTEXDECLARATION9 iface) {
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
- if(This->ref != 0) {
- /* Should not happen unless wine has a bug or the application releases references it does not own */
- ERR("Destroying vdecl with ref != 0\n");
+ if (refcount == 1)
+ {
+ IDirect3DDevice9Ex_AddRef(declaration->parent_device);
+ wined3d_mutex_lock();
+ wined3d_vertex_declaration_incref(declaration->wined3d_declaration);
+ wined3d_mutex_unlock();
}
- wined3d_mutex_lock();
- wined3d_vertex_declaration_decref(This->wineD3DVertexDeclaration);
- wined3d_mutex_unlock();
+ return refcount;
}
-static ULONG WINAPI IDirect3DVertexDeclaration9Impl_Release(LPDIRECT3DVERTEXDECLARATION9 iface) {
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("%p decreasing refcount to %u.\n", iface, ref);
+static ULONG WINAPI d3d9_vertex_declaration_Release(IDirect3DVertexDeclaration9 *iface)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
+ ULONG refcount = InterlockedDecrement(&declaration->refcount);
- if (ref == 0) {
- IDirect3DDevice9Ex *parentDevice = This->parentDevice;
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
- if(!This->convFVF) {
- IDirect3DVertexDeclaration9Impl_Destroy(iface);
- }
+ if (!refcount)
+ {
+ IDirect3DDevice9Ex *parent_device = declaration->parent_device;
+ wined3d_mutex_lock();
+ wined3d_vertex_declaration_decref(declaration->wined3d_declaration);
+ wined3d_mutex_unlock();
/* Release the device last, as it may cause the device to be destroyed. */
- IDirect3DDevice9Ex_Release(parentDevice);
+ IDirect3DDevice9Ex_Release(parent_device);
}
- return ref;
+
+ return refcount;
}
-/* IDirect3DVertexDeclaration9 Interface follow: */
-static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDevice(IDirect3DVertexDeclaration9 *iface,
- IDirect3DDevice9 **device)
+static HRESULT WINAPI d3d9_vertex_declaration_GetDevice(IDirect3DVertexDeclaration9 *iface, IDirect3DDevice9 **device)
{
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
TRACE("iface %p, device %p.\n", iface, device);
- *device = (IDirect3DDevice9 *)This->parentDevice;
+ *device = (IDirect3DDevice9 *)declaration->parent_device;
IDirect3DDevice9_AddRef(*device);
TRACE("Returning device %p.\n", *device);
return D3D_OK;
}
-static HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDeclaration(LPDIRECT3DVERTEXDECLARATION9 iface, D3DVERTEXELEMENT9* pDecl, UINT* pNumElements) {
- IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
+static HRESULT WINAPI d3d9_vertex_declaration_GetDeclaration(IDirect3DVertexDeclaration9 *iface,
+ D3DVERTEXELEMENT9 *elements, UINT *element_count)
+{
+ struct d3d9_vertex_declaration *declaration = impl_from_IDirect3DVertexDeclaration9(iface);
- TRACE("iface %p, elements %p, element_count %p.\n", iface, pDecl, pNumElements);
+ TRACE("iface %p, elements %p, element_count %p.\n", iface, elements, element_count);
- *pNumElements = This->element_count;
+ *element_count = declaration->element_count;
- /* Passing a NULL pDecl is used to just retrieve the number of elements */
- if (!pDecl) {
- TRACE("NULL pDecl passed. Returning D3D_OK.\n");
+ /* Passing a NULL elements is used to just retrieve the number of elements */
+ if (!elements)
return D3D_OK;
- }
- TRACE("Copying %p to %p\n", This->elements, pDecl);
- CopyMemory(pDecl, This->elements, This->element_count * sizeof(D3DVERTEXELEMENT9));
+ TRACE("Copying %p to %p.\n", declaration->elements, elements);
+ memcpy(elements, declaration->elements, sizeof(*declaration->elements) * declaration->element_count);
return D3D_OK;
}
-static const IDirect3DVertexDeclaration9Vtbl Direct3DVertexDeclaration9_Vtbl =
+static const struct IDirect3DVertexDeclaration9Vtbl d3d9_vertex_declaration_vtbl =
{
/* IUnknown */
- IDirect3DVertexDeclaration9Impl_QueryInterface,
- IDirect3DVertexDeclaration9Impl_AddRef,
- IDirect3DVertexDeclaration9Impl_Release,
+ d3d9_vertex_declaration_QueryInterface,
+ d3d9_vertex_declaration_AddRef,
+ d3d9_vertex_declaration_Release,
/* IDirect3DVertexDeclaration9 */
- IDirect3DVertexDeclaration9Impl_GetDevice,
- IDirect3DVertexDeclaration9Impl_GetDeclaration
+ d3d9_vertex_declaration_GetDevice,
+ d3d9_vertex_declaration_GetDeclaration,
};
+struct d3d9_vertex_declaration *unsafe_impl_from_IDirect3DVertexDeclaration9(IDirect3DVertexDeclaration9 *iface)
+{
+ if (!iface)
+ return NULL;
+ assert(iface->lpVtbl == &d3d9_vertex_declaration_vtbl);
+ return CONTAINING_RECORD(iface, struct d3d9_vertex_declaration, IDirect3DVertexDeclaration9_iface);
+}
+
static void STDMETHODCALLTYPE d3d9_vertexdeclaration_wined3d_object_destroyed(void *parent)
{
- IDirect3DVertexDeclaration9Impl *declaration = parent;
+ struct d3d9_vertex_declaration *declaration = parent;
HeapFree(GetProcessHeap(), 0, declaration->elements);
HeapFree(GetProcessHeap(), 0, declaration);
}
d3d9_vertexdeclaration_wined3d_object_destroyed,
};
-static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9* d3d9_elements,
- WINED3DVERTEXELEMENT **wined3d_elements, UINT *element_count)
+static HRESULT convert_to_wined3d_declaration(const D3DVERTEXELEMENT9 *d3d9_elements,
+ struct wined3d_vertex_element **wined3d_elements, UINT *element_count)
{
const D3DVERTEXELEMENT9* element;
UINT count = 1;
UINT i;
- TRACE("d3d9_elements %p, wined3d_elements %p\n", d3d9_elements, wined3d_elements);
+ TRACE("d3d9_elements %p, wined3d_elements %p, element_count %p\n", d3d9_elements, wined3d_elements, element_count);
element = d3d9_elements;
while (element++->Stream != 0xff && count++ < 128);
/* Skip the END element */
--count;
- *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WINED3DVERTEXELEMENT));
+ *wined3d_elements = HeapAlloc(GetProcessHeap(), 0, count * sizeof(**wined3d_elements));
if (!*wined3d_elements) {
FIXME("Memory allocation failed\n");
return D3DERR_OUTOFVIDEOMEMORY;
(*wined3d_elements)[i].format = d3d_dtype_lookup[d3d9_elements[i].Type].format;
(*wined3d_elements)[i].input_slot = d3d9_elements[i].Stream;
(*wined3d_elements)[i].offset = d3d9_elements[i].Offset;
- (*wined3d_elements)[i].output_slot = ~0U;
+ (*wined3d_elements)[i].output_slot = WINED3D_OUTPUT_SLOT_SEMANTIC;
+ (*wined3d_elements)[i].input_slot_class = WINED3D_INPUT_PER_VERTEX_DATA;
+ (*wined3d_elements)[i].instance_data_step_rate = 0;
(*wined3d_elements)[i].method = d3d9_elements[i].Method;
(*wined3d_elements)[i].usage = d3d9_elements[i].Usage;
(*wined3d_elements)[i].usage_idx = d3d9_elements[i].UsageIndex;
return D3D_OK;
}
-HRESULT vertexdeclaration_init(IDirect3DVertexDeclaration9Impl *declaration,
- IDirect3DDevice9Impl *device, const D3DVERTEXELEMENT9 *elements)
+static HRESULT vertexdeclaration_init(struct d3d9_vertex_declaration *declaration,
+ struct d3d9_device *device, const D3DVERTEXELEMENT9 *elements)
{
- WINED3DVERTEXELEMENT *wined3d_elements;
+ struct wined3d_vertex_element *wined3d_elements;
UINT wined3d_element_count;
UINT element_count;
HRESULT hr;
return hr;
}
- declaration->lpVtbl = &Direct3DVertexDeclaration9_Vtbl;
- declaration->ref = 1;
+ declaration->IDirect3DVertexDeclaration9_iface.lpVtbl = &d3d9_vertex_declaration_vtbl;
+ declaration->refcount = 1;
element_count = wined3d_element_count + 1;
declaration->elements = HeapAlloc(GetProcessHeap(), 0, element_count * sizeof(*declaration->elements));
wined3d_mutex_lock();
hr = wined3d_vertex_declaration_create(device->wined3d_device, wined3d_elements, wined3d_element_count,
- declaration, &d3d9_vertexdeclaration_wined3d_parent_ops, &declaration->wineD3DVertexDeclaration);
+ declaration, &d3d9_vertexdeclaration_wined3d_parent_ops, &declaration->wined3d_declaration);
wined3d_mutex_unlock();
HeapFree(GetProcessHeap(), 0, wined3d_elements);
if (FAILED(hr))
return hr;
}
- declaration->parentDevice = &device->IDirect3DDevice9Ex_iface;
- IDirect3DDevice9Ex_AddRef(declaration->parentDevice);
+ declaration->parent_device = &device->IDirect3DDevice9Ex_iface;
+ IDirect3DDevice9Ex_AddRef(declaration->parent_device);
+
+ return D3D_OK;
+}
+
+HRESULT d3d9_vertex_declaration_create(struct d3d9_device *device,
+ const D3DVERTEXELEMENT9 *elements, struct d3d9_vertex_declaration **declaration)
+{
+ struct d3d9_vertex_declaration *object;
+ HRESULT hr;
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ return E_OUTOFMEMORY;
+
+ hr = vertexdeclaration_init(object, device, elements);
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ TRACE("Created vertex declaration %p.\n", object);
+ *declaration = object;
return D3D_OK;
}