[WINED3D 3] Add position_transformed flag to Strided data format.

Ivan Gyurdiev ivg231 at gmail.com
Fri Jul 7 01:23:10 CDT 2006


I don't like how the transformed position is currently being tracked.

In half the places we compare the data type to a FLOAT4 - it doesn't 
make sense to convert an explicit mark of transformed data (such as 
D3DFVF_XYZRHW, or D3DDECLUSAGE_POSITIONT), to some kind of made up 
FLOAT4 indicator. What's to say the app won't write 4-coordinate 
untransformed data, with garbage in the 4th coord. Are there tests that 
show this isn't the case (for vertex declarations)?

Then in the other half we use an FVF (even when there is no FVF, but 
only a vertex declaration is available). We make up a fake FVF. While I 
tend to use "fakes" myself, you use the new format to represent the old 
data, not the other way around, which is a bad idea.

Get rid of all of this, store the transformed position flag when the 
strided data is created.
-------------- next part --------------
---
 dlls/ddraw/device.c            |    4 +-
 dlls/wined3d/drawprim.c        |   96 ++++++++++++++++------------------------
 dlls/wined3d/vertexbuffer.c    |    9 ++--
 dlls/wined3d/wined3d_private.h |    1 
 include/wine/wined3d_types.h   |    1 
 5 files changed, 46 insertions(+), 65 deletions(-)

diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 63f272b..bdb4d05 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -3076,7 +3076,9 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrid
         if (VertexType & D3DFVF_XYZRHW)
         {
             WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
-        }
+            WineD3DStrided.u.s.position_transformed = TRUE;
+        } else
+            WineD3DStrided.u.s.position_transformed = FALSE;
     }
 
     if(VertexType & D3DFVF_NORMAL)
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index e15f74b..780dee6 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -38,30 +38,6 @@ extern IWineD3DPixelShaderImpl*         
 #undef GL_VERSION_1_4 /* To be fixed, caused by mesa headers */
 #endif
 
-/* Returns bits for what is expected from the fixed function pipeline, and whether
-   a vertex shader will be in use. Note the fvf bits returned may be split over
-   multiple streams only if the vertex shader was created, otherwise it all relates
-   to stream 0                                                                      */
-static BOOL initializeFVF(IWineD3DDevice *iface, DWORD *FVFbits)
-{
-
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
-#if 0 /* TODO: d3d8 call setvertexshader needs to set the FVF in the state block when implemented */
-    /* The first thing to work out is if we are using the fixed function pipeline
-       which is either SetVertexShader with < VS_HIGHESTFIXEDFXF - in which case this
-       is the FVF, or with a shader which was created with no function - in which
-       case there is an FVF per declared stream. If this occurs, we also maintain
-       an 'OR' of all the FVF's together so we know what to expect across all the
-       streams                                                                        */
-#endif
-    *FVFbits = This->stateBlock->fvf;
-#if 0
-        *FVFbits = This->stateBlock->vertexShaderDecl->allFVF;
-#endif
-    return FALSE;
-}
-
 /* Issues the glBegin call for gl given the primitive type and count */
 static DWORD primitiveToGl(D3DPRIMITIVETYPE PrimitiveType,
                     DWORD            NumPrimitives,
@@ -246,21 +222,37 @@ void d3ddevice_set_ortho(IWineD3DDeviceI
 /* Setup views - Transformed & lit if RHW, else untransformed.
        Only unlit if Normals are supplied
     Returns: Whether to restore lighting afterwards           */
-static BOOL primitiveInitState(IWineD3DDevice *iface, BOOL vtx_transformed, BOOL vtx_lit, BOOL useVS) {
+static void primitiveInitState(
+    IWineD3DDevice *iface,
+    WineDirect3DVertexStridedData* strided,
+    BOOL useVS,
+    BOOL* lighting_changed,
+    BOOL* lighting_original) {
+
+    BOOL fixed_vtx_transformed =
+       (strided->u.s.position.lpData != NULL || strided->u.s.position.VBO != 0 ||
+        strided->u.s.position2.lpData != NULL || strided->u.s.position2.VBO != 0) && 
+        strided->u.s.position_transformed;
+
+    BOOL fixed_vtx_lit = 
+        strided->u.s.normal.lpData == NULL && strided->u.s.normal.VBO == 0 &&
+        strided->u.s.normal2.lpData == NULL && strided->u.s.normal2.VBO == 0;
 
-    BOOL isLightingOn = FALSE;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
+    *lighting_changed = FALSE;
+
     /* If no normals, DISABLE lighting otherwise, don't touch lighing as it is
        set by the appropriate render state. Note Vertex Shader output is already lit */
-    if (vtx_lit || useVS) {
-        isLightingOn = glIsEnabled(GL_LIGHTING);
+    if (fixed_vtx_lit || useVS) {
+        *lighting_changed = TRUE;
+        *lighting_original = glIsEnabled(GL_LIGHTING);
         glDisable(GL_LIGHTING);
         checkGLcall("glDisable(GL_LIGHTING);");
-        TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn);
+        TRACE("Disabled lighting, old state = %d\n", *lighting_original);
     }
 
-    if (!useVS && vtx_transformed) {
+    if (!useVS && fixed_vtx_transformed) {
         d3ddevice_set_ortho(This);
 
     } else {
@@ -352,7 +344,6 @@ static BOOL primitiveInitState(IWineD3DD
             }
         }
     }
-    return isLightingOn;
 }
 
 void primitiveDeclarationConvertToStridedData(
@@ -360,7 +351,6 @@ void primitiveDeclarationConvertToStride
      BOOL useVertexShaderFunction,
      WineDirect3DVertexStridedData *strided,
      LONG BaseVertexIndex, 
-     DWORD *fvf,
      BOOL *fixup) {
 
      /* We need to deal with frequency data!*/
@@ -442,6 +432,7 @@ void primitiveDeclarationConvertToStride
                     TRACE("Set strided %s. data %p, type %d. stride %ld\n", "position2", data, element->Type, stride);
                 break;
                 }
+                strided->u.s.position_transformed = FALSE;
         break;
         case D3DDECLUSAGE_NORMAL:
                 switch (element->UsageIndex) {
@@ -461,7 +452,6 @@ void primitiveDeclarationConvertToStride
                     TRACE("Set strided %s. data %p, type %d. stride %ld\n", "normal2", data, element->Type, stride);
                 break;
                 }
-                *fvf |=  D3DFVF_NORMAL;
         break;
         case D3DDECLUSAGE_BLENDINDICES:
         /* demo @http://www.ati.com/developer/vertexblend.html
@@ -573,9 +563,7 @@ void primitiveDeclarationConvertToStride
                     TRACE("Set strided %s. data %p, type %d. stride %ld\n", "position2T", data, element->Type, stride);
                 break;
                 }
-                /* TODO: change fvf usage to a plain boolean flag */
-                *fvf |= D3DFVF_XYZRHW;
-            /* FIXME: were faking this flag so that we don't transform the data again */
+                strided->u.s.position_transformed = TRUE;
         break;
         case D3DDECLUSAGE_FOG:
         /* maybe GL_EXT_fog_coord ?
@@ -632,8 +620,10 @@ void primitiveConvertFVFtoOffset(DWORD t
         data += 3 * sizeof(float);
         if (thisFVF & D3DFVF_XYZRHW) {
             strided->u.s.position.dwType = D3DDECLTYPE_FLOAT4;
+            strided->u.s.position_transformed = TRUE;
             data += sizeof(float);
-        }
+        } else
+            strided->u.s.position_transformed = FALSE;
     }
 
     /* Blending is numBlends * FLOATs followed by a DWORD for UBYTE4 */
@@ -1318,7 +1308,7 @@ static inline void fixed_prepare_draw(
         draw->position.w = 1.0;
 
         /* Data contains rhw */
-        if (strided->u.s.position.dwType == D3DDECLTYPE_FLOAT4) {
+        if (strided->u.s.position_transformed) {
             float rhw = ptrToCoords[3];
 
             draw->is_transformed = TRUE;
@@ -1740,10 +1730,11 @@ #undef BUFFER_OR_DATA
         glDisable(GL_FRAGMENT_PROGRAM_ARB);
 }
 
-void inline drawPrimitiveTraceDataLocations(WineDirect3DVertexStridedData *dataLocations,DWORD fvf) {
+void inline drawPrimitiveTraceDataLocations(
+    WineDirect3DVertexStridedData *dataLocations) {
 
     /* Dump out what parts we have supplied */
-    TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
+    TRACE("Strided Data:\n");
     TRACE_STRIDED((dataLocations), position);
     TRACE_STRIDED((dataLocations), blendWeights);
     TRACE_STRIDED((dataLocations), blendMatrixIndices);
@@ -1950,17 +1941,16 @@ void drawPrimitive(IWineD3DDevice *iface
                    int   minIndex,
                    WineDirect3DVertexStridedData *DrawPrimStrideData) {
 
-    BOOL                          rc = FALSE;
-    DWORD                         fvf = 0;
     IWineD3DDeviceImpl           *This = (IWineD3DDeviceImpl *)iface;
     BOOL                          useVertexShaderFunction = FALSE;
     BOOL                          usePixelShaderFunction = FALSE;
-    BOOL                          isLightingOn = FALSE;
     WineDirect3DVertexStridedData *dataLocations;
     IWineD3DSwapChainImpl         *swapchain;
     int                           i;
     BOOL                          fixup = FALSE;
 
+    BOOL lighting_changed, lighting_original;
+
     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software - 
      * here simply check whether a shader was set, or the user disabled shaders */
     if (wined3d_settings.vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader && 
@@ -1971,14 +1961,6 @@ void drawPrimitive(IWineD3DDevice *iface
         ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) 
         usePixelShaderFunction = TRUE;
 
-    if (This->stateBlock->vertexDecl == NULL) {
-        /* Work out what the FVF should look like */
-        rc = initializeFVF(iface, &fvf);
-        if (rc) return;
-    } else {
-        TRACE("(%p) : using vertex declaration %p\n", iface, This->stateBlock->vertexDecl);
-    }
-
     /* Invalidate the back buffer memory so LockRect will read it the next time */
     for(i = 0; i < IWineD3DDevice_GetNumberOfSwapChains(iface); i++) {
         IWineD3DDevice_GetSwapChain(iface, i, (IWineD3DSwapChain **) &swapchain);
@@ -1991,8 +1973,6 @@ void drawPrimitive(IWineD3DDevice *iface
     /* Ok, we will be updating the screen from here onwards so grab the lock */
     ENTER_GL();
 
-    /* convert the FVF or vertexDeclaration into a strided stream (this should be done when the fvf or declaration is created) */
-
     if(DrawPrimStrideData) {
         TRACE("================ Strided Input ===================\n");
         dataLocations = DrawPrimStrideData;
@@ -2006,7 +1986,7 @@ void drawPrimitive(IWineD3DDevice *iface
             ERR("Out of memory!\n");
             return;
         }
-        primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, dataLocations, StartVertexIndex, &fvf, &fixup);
+        primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, dataLocations, StartVertexIndex, &fixup);
 
     } else {
         TRACE("================ FVF ===================\n");
@@ -2019,10 +1999,10 @@ void drawPrimitive(IWineD3DDevice *iface
     }
 
     /* write out some debug information*/
-    drawPrimitiveTraceDataLocations(dataLocations, fvf);
+    drawPrimitiveTraceDataLocations(dataLocations);
 
     /* Setup transform matrices and sort out */
-    isLightingOn = primitiveInitState(iface, fvf & D3DFVF_XYZRHW, !(fvf & D3DFVF_NORMAL), useVertexShaderFunction);
+    primitiveInitState(iface, dataLocations, useVertexShaderFunction, &lighting_changed, &lighting_original);
 
     /* Now initialize the materials state */
     init_materials(iface, (dataLocations->u.s.diffuse.lpData != NULL || dataLocations->u.s.diffuse.VBO != 0));
@@ -2049,8 +2029,8 @@ void drawPrimitive(IWineD3DDevice *iface
     if(!DrawPrimStrideData) HeapFree(GetProcessHeap(), 0, dataLocations);
 
     /* If vertex shaders or no normals, restore previous lighting state */
-    if (useVertexShaderFunction || !(fvf & D3DFVF_NORMAL)) {
-        if (isLightingOn) glEnable(GL_LIGHTING);
+    if (lighting_changed) {
+        if (lighting_original) glEnable(GL_LIGHTING);
         else glDisable(GL_LIGHTING);
         TRACE("Restored lighting to original state\n");
     }
diff --git a/dlls/wined3d/vertexbuffer.c b/dlls/wined3d/vertexbuffer.c
index b58591c..35a4d9e 100644
--- a/dlls/wined3d/vertexbuffer.c
+++ b/dlls/wined3d/vertexbuffer.c
@@ -117,7 +117,6 @@ static void     WINAPI IWineD3DVertexBuf
         BOOL useVertexShaderFunction = FALSE, fixup = FALSE;
         BYTE *data;
         UINT i;
-        DWORD declFVF;  /* Not interested */
         UINT start = 0, end = 0, stride = 0;
 
         if(This->Flags & VBFLAG_DIRTY) {
@@ -173,7 +172,6 @@ static void     WINAPI IWineD3DVertexBuf
                                                         useVertexShaderFunction,
                                                         &strided,
                                                         0,
-                                                        &declFVF,
                                                         &fixup);
                 This->Flags &= ~VBFLAG_LOAD;
 
@@ -198,7 +196,7 @@ static void     WINAPI IWineD3DVertexBuf
             }
 
             /* If any data that needs conversion has changed we have to reload the whole buffer */
-            if( ( (This->strided.u.s.position.dwType != WINED3DDECLTYPE_FLOAT4 || strided.u.s.position.dwType != WINED3DDECLTYPE_FLOAT4) &&
+            if( ( (This->strided.u.s.position_transformed || strided.u.s.position_transformed) &&
                   This->strided.u.s.position.lpData != strided.u.s.position.lpData) ||
                 !(This->strided.u.s.diffuse.lpData == strided.u.s.diffuse.lpData || strided.u.s.diffuse.VBO != This->vbo)   ||
                 !(This->strided.u.s.specular.lpData == strided.u.s.specular.lpData || strided.u.s.specular.VBO != This->vbo) ) {
@@ -240,8 +238,9 @@ static void     WINAPI IWineD3DVertexBuf
             memcpy(data, This->resource.allocatedMemory + start, end - start);
 
             for(i = 0; i < ( end - start) / stride; i++) {
-                if(strided.u.s.position.dwType == WINED3DDECLTYPE_FLOAT4 ) {
-                    float *p = (float *) (((int) This->resource.allocatedMemory + (int) strided.u.s.position.lpData) + start + i * stride);
+                if(strided.u.s.position_transformed) {
+                    float *p = (float *) (((int) This->resource.allocatedMemory + 
+                       (int) strided.u.s.position.lpData) + start + i * stride);
                     float x, y, z, w;
 
                     /* rhw conversion like in drawStridedSlow */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e70a9a0..ad872d9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -366,7 +366,6 @@ void primitiveDeclarationConvertToStride
      BOOL useVertexShaderFunction,
      WineDirect3DVertexStridedData *strided,
      LONG BaseVertexIndex, 
-     DWORD *fvf,
      BOOL *fixup);
 
 void primitiveConvertFVFtoOffset(DWORD thisFVF,
diff --git a/include/wine/wined3d_types.h b/include/wine/wined3d_types.h
index f097bf0..26d2902 100644
--- a/include/wine/wined3d_types.h
+++ b/include/wine/wined3d_types.h
@@ -905,6 +905,7 @@ typedef struct WineDirect3DVertexStrided
     union {
         struct {
              WineDirect3DStridedData  position;
+             BOOL position_transformed;
              WineDirect3DStridedData  blendWeights;
              WineDirect3DStridedData  blendMatrixIndices;
              WineDirect3DStridedData  normal;
-- 
1.4.0



More information about the wine-patches mailing list