WINED3D: Set vertex attribute pointers defined in vertex declarations, properly

H. Verbeet hverbeet at gmail.com
Wed Mar 22 13:47:54 CST 2006


The way d3d8 and d3d9 vertexdeclaration and shaders work is slightly
different. In d3d8 the declaration specifies a register and a type, in
d3d9 the declaration just specifies a usage (and implicitly a type).
The shader in d3d8 just uses the registers, while shaders in d3d9 have
to declare the usage for the register first (dcl_position, dcl_color,
etc). The current code tries to use the vertexdeclaration to
initialise the vertex shader's arrayUsageMap in
IWineD3DVertexShaderImpl_GenerateProgramArbHW, in order to make d3d8
shaders work wih wined3d. However, that can't work, since it doesn't
properly take the register type into account. It's not neccesary
either, since the d3d8 vertex declaration contains the register the
data is meant for, so we can just use that to set a vertex attrib
pointer in primitiveDeclarationConvertToStridedData.
This fixes the issue described in
http://www.winehq.org/pipermail/wine-devel/2006-March/045468.html

Changelog:
  - Set vertex attribute pointers defined in vertex declarations, properly
-------------- next part --------------
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 6f14dff..34241bd 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -325,6 +325,7 @@ void primitiveDeclarationConvertToStride
     int i;
     WINED3DVERTEXELEMENT *element;
     DWORD stride;
+    int reg;
 
     /* Locate the vertex declaration */
     if (useVertexShaderFunction && ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration) {
@@ -350,8 +351,21 @@ void primitiveDeclarationConvertToStride
         stride  = This->stateBlock->streamStride[element->Stream];
         data += (BaseVertexIndex * stride);
         data += element->Offset;
+        reg = element->Reg;
 
         TRACE("Offset %d Stream %d UsageIndex %d\n", element->Offset, element->Stream, element->UsageIndex);
+
+        if (useVertexShaderFunction && reg != -1 && data) {
+            WINED3DGLTYPE glType = glTypeLookup[element->Type];
+
+            TRACE("(%p) : Set vertex attrib pointer: reg 0x%08x, d3d type 0x%08x, stride 0x%08lx, data %p)\n", This, reg, element->Type, stride, data);
+
+            GL_EXTCALL(glVertexAttribPointerARB(reg, glType.size, glType.glType, glType.normalized, stride, data));
+            checkGLcall("glVertexAttribPointerARB");
+            GL_EXTCALL(glEnableVertexAttribArrayARB(reg));
+            checkGLcall("glEnableVertexAttribArrayARB");
+        }
+
         switch (element->Usage) {
         case D3DDECLUSAGE_POSITION:
                 switch (element->UsageIndex) {
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index d3e3801..c4732bc 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1245,16 +1245,6 @@ inline static VOID IWineD3DVertexShaderI
     /* TODO: renumbering of attributes if the values are higher than the highest supported attribute but the total number of attributes is less than the highest supported attribute */
     This->highestConstant = -1;
 
-    /* Parse the vertex declaration and store the used elements in arrayUsageMap. */
-    if(This->vertexDeclaration) {
-        for (i = 0 ; i < ((IWineD3DVertexDeclarationImpl*)This->vertexDeclaration)->declarationWNumElements - 1; ++i) {
-            WINED3DVERTEXELEMENT *element = ((IWineD3DVertexDeclarationImpl*)This->vertexDeclaration)->pDeclarationWine + i;
-            INT usage = element->Usage | (element->UsageIndex << 16);
-            BYTE arrayNo = element->Reg;
-            parse_decl_usage(This, usage, arrayNo);
-        }
-    }
-
   /**
    * First pass to determine what we need to declare:
    *  - Temporary variables


More information about the wine-patches mailing list