Commit 5b8b97a7 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Cleanup vertex declaration initialization.

parent 0a4fa886
...@@ -1572,41 +1572,36 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, U ...@@ -1572,41 +1572,36 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetSwapChain(IWineD3DDevice *iface, U
} }
} }
/***** static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice *iface,
* Vertex Declaration IWineD3DVertexDeclaration **declaration, IUnknown *parent,
*****/ const WINED3DVERTEXELEMENT *elements, UINT element_count)
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface, IWineD3DVertexDeclaration** ppVertexDeclaration, {
IUnknown *parent, const WINED3DVERTEXELEMENT *elements, UINT element_count) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexDeclarationImpl *object = NULL; IWineD3DVertexDeclarationImpl *object = NULL;
HRESULT hr = WINED3D_OK; HRESULT hr;
TRACE("(%p) : directXVersion %u, elements %p, element_count %d, ppDecl=%p\n", TRACE("iface %p, declaration %p, parent %p, elements %p, element_count %u.\n",
This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, elements, element_count, ppVertexDeclaration); iface, declaration, parent, elements, element_count);
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)); object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if(!object) if(!object)
{ {
ERR("Out of memory\n"); ERR("Failed to allocate vertex declaration memory.\n");
*ppVertexDeclaration = NULL; return E_OUTOFMEMORY;
return WINED3DERR_OUTOFVIDEOMEMORY;
} }
object->lpVtbl = &IWineD3DVertexDeclaration_Vtbl; hr = vertexdeclaration_init(object, This, elements, element_count, parent);
object->wineD3DDevice = This; if (FAILED(hr))
object->parent = parent; {
object->ref = 1; WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
HeapFree(GetProcessHeap(), 0, object);
*ppVertexDeclaration = (IWineD3DVertexDeclaration *)object; return hr;
hr = vertexdeclaration_init(object, elements, element_count);
if(FAILED(hr)) {
IWineD3DVertexDeclaration_Release((IWineD3DVertexDeclaration *)object);
*ppVertexDeclaration = NULL;
} }
return hr; TRACE("Created verrtex declaration %p.\n", object);
*declaration = (IWineD3DVertexDeclaration *)object;
return WINED3D_OK;
} }
static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the GL info, which has the type table */
...@@ -1746,20 +1741,22 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the ...@@ -1746,20 +1741,22 @@ static unsigned int ConvertFvfToDeclaration(IWineD3DDeviceImpl *This, /* For the
return size; return size;
} }
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3DDevice* iface, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *Parent, DWORD Fvf) { static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclarationFromFVF(IWineD3DDevice *iface,
WINED3DVERTEXELEMENT* elements = NULL; IWineD3DVertexDeclaration **declaration, IUnknown *parent, DWORD fvf)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
WINED3DVERTEXELEMENT *elements;
unsigned int size; unsigned int size;
DWORD hr; DWORD hr;
size = ConvertFvfToDeclaration(This, Fvf, &elements); TRACE("iface %p, declaration %p, parent %p, fvf %#x.\n", iface, declaration, parent, fvf);
if (size == ~0U) return WINED3DERR_OUTOFVIDEOMEMORY;
hr = IWineD3DDevice_CreateVertexDeclaration(iface, ppVertexDeclaration, Parent, elements, size); size = ConvertFvfToDeclaration(This, fvf, &elements);
HeapFree(GetProcessHeap(), 0, elements); if (size == ~0U) return E_OUTOFMEMORY;
if (hr != S_OK) return hr;
return WINED3D_OK; hr = IWineD3DDevice_CreateVertexDeclaration(iface, declaration, parent, elements, size);
HeapFree(GetProcessHeap(), 0, elements);
return hr;
} }
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
......
...@@ -190,39 +190,51 @@ static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element) ...@@ -190,39 +190,51 @@ static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
} }
} }
HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, static const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
const WINED3DVERTEXELEMENT *elements, UINT element_count)
{ {
HRESULT hr = WINED3D_OK; /* IUnknown */
unsigned int i; IWineD3DVertexDeclarationImpl_QueryInterface,
char isPreLoaded[MAX_STREAMS]; IWineD3DVertexDeclarationImpl_AddRef,
IWineD3DVertexDeclarationImpl_Release,
/* IWineD3DVertexDeclaration */
IWineD3DVertexDeclarationImpl_GetParent,
IWineD3DVertexDeclarationImpl_GetDevice,
};
TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion); HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device,
memset(isPreLoaded, 0, sizeof(isPreLoaded)); const WINED3DVERTEXELEMENT *elements, UINT element_count, IUnknown *parent)
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
WORD preloaded = 0; /* MAX_STREAMS, 16 */
unsigned int i;
if (TRACE_ON(d3d_decl)) { if (TRACE_ON(d3d_decl))
for (i = 0; i < element_count; ++i) { {
dump_wined3dvertexelement(elements+i); for (i = 0; i < element_count; ++i)
{
dump_wined3dvertexelement(elements + i);
} }
} }
This->element_count = element_count; declaration->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
This->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->elements) * element_count); declaration->ref = 1;
if (!This->elements) declaration->parent = parent;
declaration->wineD3DDevice = device;
declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
if (!declaration->elements)
{ {
ERR("Memory allocation failed\n"); ERR("Failed to allocate elements memory.\n");
return WINED3DERR_OUTOFVIDEOMEMORY; return E_OUTOFMEMORY;
} }
declaration->element_count = element_count;
/* Do some static analysis on the elements to make reading the declaration more comfortable /* Do some static analysis on the elements to make reading the
* for the drawing code * declaration more comfortable for the drawing code. */
*/ for (i = 0; i < element_count; ++i)
This->num_streams = 0; {
This->position_transformed = FALSE; struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
for (i = 0; i < element_count; ++i) {
struct wined3d_vertex_declaration_element *e = &This->elements[i];
e->format_desc = getFormatDescEntry(elements[i].format, &This->wineD3DDevice->adapter->gl_info); e->format_desc = getFormatDescEntry(elements[i].format, gl_info);
e->ffp_valid = declaration_element_valid_ffp(&elements[i]); e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
e->input_slot = elements[i].input_slot; e->input_slot = elements[i].input_slot;
e->offset = elements[i].offset; e->offset = elements[i].offset;
...@@ -231,51 +243,39 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, ...@@ -231,51 +243,39 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
e->usage = elements[i].usage; e->usage = elements[i].usage;
e->usage_idx = elements[i].usage_idx; e->usage_idx = elements[i].usage_idx;
if (e->usage == WINED3DDECLUSAGE_POSITIONT) This->position_transformed = TRUE; if (e->usage == WINED3DDECLUSAGE_POSITIONT) declaration->position_transformed = TRUE;
/* Find the Streams used in the declaration. The vertex buffers have to be loaded /* Find the streams used in the declaration. The vertex buffers have
* when drawing, but filter tesselation pseudo streams * to be loaded when drawing, but filter tesselation pseudo streams. */
*/
if (e->input_slot >= MAX_STREAMS) continue; if (e->input_slot >= MAX_STREAMS) continue;
if (!e->format_desc->gl_vtx_format) if (!e->format_desc->gl_vtx_format)
{ {
FIXME("The application tries to use an unsupported format (%s), returning E_FAIL\n", FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
debug_d3dformat(elements[i].format)); debug_d3dformat(elements[i].format));
/* The caller will release the vdecl, which will free This->elements */ HeapFree(GetProcessHeap(), 0, declaration->elements);
return E_FAIL; return E_FAIL;
} }
if (e->offset & 0x3) if (e->offset & 0x3)
{ {
WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL\n", i, e->offset); WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL.\n", i, e->offset);
HeapFree(GetProcessHeap(), 0, declaration->elements);
return E_FAIL; return E_FAIL;
} }
if (!isPreLoaded[e->input_slot]) if (!(preloaded & (1 << e->input_slot)))
{ {
This->streams[This->num_streams] = e->input_slot; declaration->streams[declaration->num_streams] = e->input_slot;
This->num_streams++; ++declaration->num_streams;
isPreLoaded[e->input_slot] = 1; preloaded |= 1 << e->input_slot;
} }
if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT) if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
{ {
if (!GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) This->half_float_conv_needed = TRUE; if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
} }
} }
TRACE("Returning\n"); return WINED3D_OK;
return hr;
} }
const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
{
/* IUnknown */
IWineD3DVertexDeclarationImpl_QueryInterface,
IWineD3DVertexDeclarationImpl_AddRef,
IWineD3DVertexDeclarationImpl_Release,
/* IWineD3DVertexDeclaration */
IWineD3DVertexDeclarationImpl_GetParent,
IWineD3DVertexDeclarationImpl_GetDevice,
};
...@@ -2198,10 +2198,8 @@ typedef struct IWineD3DVertexDeclarationImpl { ...@@ -2198,10 +2198,8 @@ typedef struct IWineD3DVertexDeclarationImpl {
BOOL half_float_conv_needed; BOOL half_float_conv_needed;
} IWineD3DVertexDeclarationImpl; } IWineD3DVertexDeclarationImpl;
extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl DECLSPEC_HIDDEN; HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, IWineD3DDeviceImpl *device,
const WINED3DVERTEXELEMENT *elements, UINT element_count, IUnknown *parent) DECLSPEC_HIDDEN;
HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
const WINED3DVERTEXELEMENT *elements, UINT element_count) DECLSPEC_HIDDEN;
/***************************************************************************** /*****************************************************************************
* IWineD3DStateBlock implementation structure * IWineD3DStateBlock implementation structure
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment