Module: wine Branch: master Commit: f84680e66c298b93b1cf78515c42f2be7928568d URL: http://source.winehq.org/git/wine.git/?a=commit;h=f84680e66c298b93b1cf78515c...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Thu Sep 18 14:57:54 2008 +0200
wined3d: Don't try to draw with unsupported attribute data types.
---
dlls/wined3d/drawprim.c | 17 +++++--- dlls/wined3d/vertexdeclaration.c | 89 +++++++++++++++++++++++++++++++++++++- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 100 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 37cbe19..c4154a7 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -219,17 +219,22 @@ void primitiveDeclarationConvertToStridedData( stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx);
if (stride_used) { - TRACE("Loaded %s array %u [usage=%s, usage_idx=%u, " + TRACE("Load %s array %u [usage=%s, usage_idx=%u, " "stream=%u, offset=%u, stride=%u, type=%s, VBO=%u]\n", useVertexShaderFunction? "shader": "fixed function", idx, debug_d3ddeclusage(element->Usage), element->UsageIndex, element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), streamVBO);
- strided->u.input[idx].lpData = data; - strided->u.input[idx].dwType = element->Type; - strided->u.input[idx].dwStride = stride; - strided->u.input[idx].VBO = streamVBO; - strided->u.input[idx].streamNo = element->Stream; + if (!useVertexShaderFunction && !vertexDeclaration->ffp_valid[i]) { + WARN("Skipping unsupported fixed function element of type %s and usage %s\n", + debug_d3ddecltype(element->Type), debug_d3ddeclusage(element->Usage)); + } else { + strided->u.input[idx].lpData = data; + strided->u.input[idx].dwType = element->Type; + strided->u.input[idx].dwStride = stride; + strided->u.input[idx].VBO = streamVBO; + strided->u.input[idx].streamNo = element->Stream; + } } } /* Now call PreLoad on all the vertex buffers. In the very rare case diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index 7b57e55..7fc711b 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -74,6 +74,7 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat }
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); + HeapFree(GetProcessHeap(), 0, This->ffp_valid); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -118,6 +119,90 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVerte return hr; }
+static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element) +{ + switch(element->Usage) + { + case WINED3DDECLUSAGE_POSITION: + case WINED3DDECLUSAGE_POSITIONT: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT2: + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_BLENDWEIGHT: + switch(element->Type) + { + case WINED3DDECLTYPE_D3DCOLOR: + case WINED3DDECLTYPE_UBYTE4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_NORMAL: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_TEXCOORD: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT1: + case WINED3DDECLTYPE_FLOAT2: + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_SHORT2: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_FLOAT16_2: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + case WINED3DDECLUSAGE_COLOR: + switch(element->Type) + { + case WINED3DDECLTYPE_FLOAT3: + case WINED3DDECLTYPE_FLOAT4: + case WINED3DDECLTYPE_D3DCOLOR: + case WINED3DDECLTYPE_UBYTE4: + case WINED3DDECLTYPE_SHORT4: + case WINED3DDECLTYPE_UBYTE4N: + case WINED3DDECLTYPE_SHORT4N: + case WINED3DDECLTYPE_USHORT4N: + case WINED3DDECLTYPE_FLOAT16_4: + return TRUE; + default: + return FALSE; + } + + default: + return FALSE; + } +} + static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface, const WINED3DVERTEXELEMENT *elements, UINT element_count) { IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface; @@ -136,7 +221,8 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte
This->declarationWNumElements = element_count; This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); - if (!This->pDeclarationWine) { + This->ffp_valid = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->ffp_valid) * element_count); + if (!This->pDeclarationWine || !This->ffp_valid) { ERR("Memory allocation failed\n"); return WINED3DERR_OUTOFVIDEOMEMORY; } else { @@ -149,6 +235,7 @@ static HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVerte This->num_streams = 0; This->position_transformed = FALSE; for (i = 0; i < element_count; ++i) { + This->ffp_valid[i] = declaration_element_valid_ffp(&This->pDeclarationWine[i]);
if(This->pDeclarationWine[i].Usage == WINED3DDECLUSAGE_POSITIONT) { This->position_transformed = TRUE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f2c1701..0354ead 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1500,6 +1500,7 @@ typedef struct IWineD3DVertexDeclarationImpl { IWineD3DDeviceImpl *wineD3DDevice;
WINED3DVERTEXELEMENT *pDeclarationWine; + BOOL *ffp_valid; UINT declarationWNumElements;
DWORD streams[MAX_STREAMS];