Henri Verbeet : wined3d: Don' t try to draw with unsupported attribute data types.

Alexandre Julliard julliard at winehq.org
Mon Sep 22 07:04:50 CDT 2008


Module: wine
Branch: master
Commit: f84680e66c298b93b1cf78515c42f2be7928568d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f84680e66c298b93b1cf78515c42f2be7928568d

Author: Henri Verbeet <hverbeet at 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];




More information about the wine-cvs mailing list