wined3d: Cleanup vertex declaration initialization.
This commit is contained in:
parent
0a4fa886a7
commit
5b8b97a737
|
@ -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
|
||||||
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);
|
||||||
|
if (size == ~0U) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
hr = IWineD3DDevice_CreateVertexDeclaration(iface, declaration, parent, elements, size);
|
||||||
HeapFree(GetProcessHeap(), 0, elements);
|
HeapFree(GetProcessHeap(), 0, elements);
|
||||||
if (hr != S_OK) return hr;
|
return hr;
|
||||||
|
|
||||||
return WINED3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
|
static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface,
|
||||||
|
|
|
@ -190,86 +190,7 @@ 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;
|
|
||||||
unsigned int i;
|
|
||||||
char isPreLoaded[MAX_STREAMS];
|
|
||||||
|
|
||||||
TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
|
|
||||||
memset(isPreLoaded, 0, sizeof(isPreLoaded));
|
|
||||||
|
|
||||||
if (TRACE_ON(d3d_decl)) {
|
|
||||||
for (i = 0; i < element_count; ++i) {
|
|
||||||
dump_wined3dvertexelement(elements+i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
This->element_count = element_count;
|
|
||||||
This->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->elements) * element_count);
|
|
||||||
if (!This->elements)
|
|
||||||
{
|
|
||||||
ERR("Memory allocation failed\n");
|
|
||||||
return WINED3DERR_OUTOFVIDEOMEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do some static analysis on the elements to make reading the declaration more comfortable
|
|
||||||
* for the drawing code
|
|
||||||
*/
|
|
||||||
This->num_streams = 0;
|
|
||||||
This->position_transformed = FALSE;
|
|
||||||
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->ffp_valid = declaration_element_valid_ffp(&elements[i]);
|
|
||||||
e->input_slot = elements[i].input_slot;
|
|
||||||
e->offset = elements[i].offset;
|
|
||||||
e->output_slot = elements[i].output_slot;
|
|
||||||
e->method = elements[i].method;
|
|
||||||
e->usage = elements[i].usage;
|
|
||||||
e->usage_idx = elements[i].usage_idx;
|
|
||||||
|
|
||||||
if (e->usage == WINED3DDECLUSAGE_POSITIONT) This->position_transformed = TRUE;
|
|
||||||
|
|
||||||
/* Find the Streams used in the declaration. The vertex buffers have to be loaded
|
|
||||||
* when drawing, but filter tesselation pseudo streams
|
|
||||||
*/
|
|
||||||
if (e->input_slot >= MAX_STREAMS) continue;
|
|
||||||
|
|
||||||
if (!e->format_desc->gl_vtx_format)
|
|
||||||
{
|
|
||||||
FIXME("The application tries to use an unsupported format (%s), returning E_FAIL\n",
|
|
||||||
debug_d3dformat(elements[i].format));
|
|
||||||
/* The caller will release the vdecl, which will free This->elements */
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e->offset & 0x3)
|
|
||||||
{
|
|
||||||
WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL\n", i, e->offset);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isPreLoaded[e->input_slot])
|
|
||||||
{
|
|
||||||
This->streams[This->num_streams] = e->input_slot;
|
|
||||||
This->num_streams++;
|
|
||||||
isPreLoaded[e->input_slot] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("Returning\n");
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
|
|
||||||
{
|
{
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
IWineD3DVertexDeclarationImpl_QueryInterface,
|
IWineD3DVertexDeclarationImpl_QueryInterface,
|
||||||
|
@ -279,3 +200,82 @@ const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
|
||||||
IWineD3DVertexDeclarationImpl_GetParent,
|
IWineD3DVertexDeclarationImpl_GetParent,
|
||||||
IWineD3DVertexDeclarationImpl_GetDevice,
|
IWineD3DVertexDeclarationImpl_GetDevice,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *declaration, IWineD3DDeviceImpl *device,
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
for (i = 0; i < element_count; ++i)
|
||||||
|
{
|
||||||
|
dump_wined3dvertexelement(elements + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declaration->lpVtbl = &IWineD3DVertexDeclaration_Vtbl;
|
||||||
|
declaration->ref = 1;
|
||||||
|
declaration->parent = parent;
|
||||||
|
declaration->wineD3DDevice = device;
|
||||||
|
declaration->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*declaration->elements) * element_count);
|
||||||
|
if (!declaration->elements)
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate elements memory.\n");
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
declaration->element_count = element_count;
|
||||||
|
|
||||||
|
/* Do some static analysis on the elements to make reading the
|
||||||
|
* declaration more comfortable for the drawing code. */
|
||||||
|
for (i = 0; i < element_count; ++i)
|
||||||
|
{
|
||||||
|
struct wined3d_vertex_declaration_element *e = &declaration->elements[i];
|
||||||
|
|
||||||
|
e->format_desc = getFormatDescEntry(elements[i].format, gl_info);
|
||||||
|
e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
|
||||||
|
e->input_slot = elements[i].input_slot;
|
||||||
|
e->offset = elements[i].offset;
|
||||||
|
e->output_slot = elements[i].output_slot;
|
||||||
|
e->method = elements[i].method;
|
||||||
|
e->usage = elements[i].usage;
|
||||||
|
e->usage_idx = elements[i].usage_idx;
|
||||||
|
|
||||||
|
if (e->usage == WINED3DDECLUSAGE_POSITIONT) declaration->position_transformed = TRUE;
|
||||||
|
|
||||||
|
/* Find the streams used in the declaration. The vertex buffers have
|
||||||
|
* to be loaded when drawing, but filter tesselation pseudo streams. */
|
||||||
|
if (e->input_slot >= MAX_STREAMS) continue;
|
||||||
|
|
||||||
|
if (!e->format_desc->gl_vtx_format)
|
||||||
|
{
|
||||||
|
FIXME("The application tries to use an unsupported format (%s), returning E_FAIL.\n",
|
||||||
|
debug_d3dformat(elements[i].format));
|
||||||
|
HeapFree(GetProcessHeap(), 0, declaration->elements);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->offset & 0x3)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(preloaded & (1 << e->input_slot)))
|
||||||
|
{
|
||||||
|
declaration->streams[declaration->num_streams] = e->input_slot;
|
||||||
|
++declaration->num_streams;
|
||||||
|
preloaded |= 1 << e->input_slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elements[i].format == WINED3DFMT_R16G16_FLOAT || elements[i].format == WINED3DFMT_R16G16B16A16_FLOAT)
|
||||||
|
{
|
||||||
|
if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]) declaration->half_float_conv_needed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WINED3D_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue