Advertisement
Guest User

vertex_blend_sw-1.2-rc2.diff

a guest
Jun 7th, 2010
463
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.67 KB | None | 0 0
  1. diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
  2. index 4df04fa..41939e7 100644
  3. --- a/dlls/wined3d/directx.c
  4. +++ b/dlls/wined3d/directx.c
  5. @@ -4553,8 +4553,13 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
  6.      pCaps->MaxUserClipPlanes = gl_info->limits.clipplanes;
  7.      pCaps->MaxActiveLights = gl_info->limits.lights;
  8.  
  9. -    pCaps->MaxVertexBlendMatrices = gl_info->limits.blends;
  10. -    pCaps->MaxVertexBlendMatrixIndex   = 0;
  11. +    if (gl_info->supported[ARB_VERTEX_BLEND]) {
  12. +        pCaps->MaxVertexBlendMatrices    = gl_info->limits.blends;
  13. +        pCaps->MaxVertexBlendMatrixIndex = 0;
  14. +    } else {
  15. +        pCaps->MaxVertexBlendMatrices    = 4;
  16. +        pCaps->MaxVertexBlendMatrixIndex = 255;
  17. +    }
  18.  
  19.      pCaps->MaxAnisotropy = gl_info->limits.anisotropy;
  20.      pCaps->MaxPointSize = gl_info->limits.pointsize_max;
  21. diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
  22. index 1f904ea..adc9eca 100644
  23. --- a/dlls/wined3d/drawprim.c
  24. +++ b/dlls/wined3d/drawprim.c
  25. @@ -55,6 +55,75 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type,
  26.  }
  27.  
  28.  /*
  29. + * Emit a vertex using swoftware vertex blending
  30. + */
  31. +static void emitBlendedVertex(IWineD3DStateBlockImpl *stateBlock,
  32. +                              const float *weights, int nweights, const BYTE *indices,
  33. +                              const float *pos, const float *norm)
  34. +{
  35. +    const float *m;
  36. +    float        vec[4];
  37. +    float        mat[4*4];
  38. +    float        last = 1.f;
  39. +    int          i, j;
  40. +
  41. +    /* compute the weighted sum of the matrices */
  42. +    m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[0] : 0))].u.m[0][0];
  43. +    for (j = 0; j < 16; j++)
  44. +        mat[j] = m[j] * weights[0];
  45. +    last -= weights[0];
  46. +
  47. +    for (i = 1; i < nweights; i++) {
  48. +        if (weights[i]) {
  49. +            m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[i] : i))].u.m[0][0];
  50. +            for (j = 0; j < 16; j++)
  51. +                mat[j] += m[j] * weights[i];
  52. +            last -= weights[i];
  53. +        }
  54. +    }
  55. +
  56. +    /* do the last */
  57. +    if (last) {
  58. +        m = &stateBlock->transforms[WINED3DTS_WORLDMATRIX((indices ? indices[i] : i))].u.m[0][0];
  59. +        for (j = 0; j < 16; j++)
  60. +            mat[j] += m[j] * last;
  61. +    }
  62. +
  63. +    if (norm) {
  64. +        /* compute the resulting normal */
  65. +        vec[0] = norm[0] * mat[0] + norm[1] * mat[4] + norm[2] * mat[8];
  66. +        vec[1] = norm[0] * mat[1] + norm[1] * mat[5] + norm[2] * mat[9];
  67. +        vec[2] = norm[0] * mat[2] + norm[1] * mat[6] + norm[2] * mat[10];
  68. +        /* normalize */
  69. +        vec[3] = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
  70. +        if (vec[3]) {
  71. +            vec[3] = 1.f / sqrtf(vec[3]);
  72. +            vec[0] *= vec[3];
  73. +            vec[1] *= vec[3];
  74. +            vec[2] *= vec[3];
  75. +        }
  76. +
  77. +        glNormal3fv(vec);
  78. +    }
  79. +
  80. +    if (pos) {
  81. +        /* compute the resulting position */
  82. +        vec[0] = pos[0] * mat[0] + pos[1] * mat[4] + pos[2] * mat[8] + mat[12];
  83. +        vec[1] = pos[0] * mat[1] + pos[1] * mat[5] + pos[2] * mat[9] + mat[13];
  84. +        vec[2] = pos[0] * mat[2] + pos[1] * mat[6] + pos[2] * mat[10] + mat[14];
  85. +        vec[3] = pos[0] * mat[3] + pos[1] * mat[7] + pos[2] * mat[11] + mat[15];
  86. +        /* normalize */
  87. +        if (vec[3]) {
  88. +            vec[0] /= vec[3];
  89. +            vec[1] /= vec[3];
  90. +            vec[2] /= vec[3];
  91. +        }
  92. +
  93. +        glVertex3fv(vec);
  94. +    }
  95. +}
  96. +
  97. +/*
  98.   * Actually draw using the supplied information.
  99.   * Slower GL version which extracts info about each vertex in turn
  100.   */
  101. @@ -74,7 +74,8 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
  102.      BOOL                      pixelShader = use_ps(This->stateBlock);
  103.      BOOL specular_fog = FALSE;
  104.      const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
  105. -    const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL;
  106. +    const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL, *weights = NULL, *indices = NULL;
  107. +    int nweights = 0;
  108.      const struct wined3d_gl_info *gl_info = context->gl_info;
  109.      UINT texture_stages = gl_info->limits.texture_stages;
  110.      const struct wined3d_stream_info_element *element;
  111. @@ -166,6 +236,31 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
  112.      {
  113.          GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
  114.      }
  115. +    
  116. +    if (This->vertexBlendSW) {
  117. +        if (!si->elements[WINED3D_FFP_BLENDWEIGHT].data) {
  118. +            WARN("vertex blending enabled but blendWeights.data=NULL\n");
  119. +        } else if (si->elements[WINED3D_FFP_BLENDWEIGHT].format_desc->gl_vtx_type != GL_FLOAT) {
  120. +            FIXME("unsupported blend weights datatype (%d)\n", si->elements[WINED3D_FFP_BLENDWEIGHT].format_desc->format);
  121. +        } else if (position && si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx != WINED3D_FFP_EMIT_FLOAT3) {
  122. +            FIXME("unsupported postion datatype (%d)\n", si->elements[WINED3D_FFP_POSITION].format_desc->format);
  123. +        } else if (normal && si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx != WINED3D_FFP_EMIT_FLOAT3) {
  124. +            FIXME("unsupported normal datatype (%d)\n", si->elements[WINED3D_FFP_NORMAL].format_desc->format);
  125. +        } else {
  126. +            element = &si->elements[WINED3D_FFP_BLENDWEIGHT];
  127. +            weights = element->data + streamOffset[element->stream_idx];
  128. +            nweights = element->format_desc->gl_vtx_format;
  129. +        }
  130. +        
  131. +        if (si->elements[WINED3D_FFP_BLENDINDICES].data) {
  132. +            if (si->elements[WINED3D_FFP_BLENDINDICES].format_desc->emit_idx != WINED3D_FFP_EMIT_UBYTE4) {
  133. +                FIXME("unsupported blend indices datatype (%d)\n", si->elements[WINED3D_FFP_BLENDINDICES].format_desc->format);
  134. +            } else {
  135. +                element = &si->elements[WINED3D_FFP_BLENDINDICES];
  136. +                indices = element->data + streamOffset[element->stream_idx];
  137. +            }
  138. +        }
  139. +    }
  140.  
  141.      for (textureNo = 0; textureNo < texture_stages; ++textureNo)
  142.      {
  143. @@ -283,16 +378,24 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_context
  144.              }
  145.          }
  146.  
  147. -        /* Normal -------------------------------- */
  148. -        if (normal != NULL) {
  149. -            const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
  150. -            normal_funcs[si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx](ptrToCoords);
  151. -        }
  152. +        if (weights) {
  153. +            emitBlendedVertex(This->stateBlock,
  154. +                              (const float*)(weights + SkipnStrides * si->elements[WINED3D_FFP_BLENDWEIGHT].stride), nweights,
  155. +                              indices ? (indices + SkipnStrides * si->elements[WINED3D_FFP_BLENDINDICES].stride) : NULL,
  156. +                              (const float*)(position ? (position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride) : NULL),
  157. +                              (const float*)(normal ? (normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride) : NULL));
  158. +        } else {
  159. +            /* Normal -------------------------------- */
  160. +            if (normal != NULL) {
  161. +                const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride;
  162. +                normal_funcs[si->elements[WINED3D_FFP_NORMAL].format_desc->emit_idx](ptrToCoords);
  163. +            }
  164.  
  165. -        /* Position -------------------------------- */
  166. -        if (position) {
  167. -            const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
  168. -            position_funcs[si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx](ptrToCoords);
  169. +            /* Position -------------------------------- */
  170. +            if (position) {
  171. +                const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride;
  172. +                position_funcs[si->elements[WINED3D_FFP_POSITION].format_desc->emit_idx](ptrToCoords);
  173. +            }
  174.          }
  175.  
  176.          /* For non indexed mode, step onto next parts */
  177. @@ -680,6 +783,17 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
  178.                  }
  179.                  emulation = TRUE;
  180.              }
  181. +            else if (This->vertexBlendSW)
  182. +            {
  183. +                static BOOL warned;
  184. +                if (!warned) {
  185. +                    FIXME("Using software emulation because vertex blending is enabled\n");
  186. +                    warned = TRUE;
  187. +                } else {
  188. +                    TRACE("Using software emulation because vertex blending is enabled\n");
  189. +                }
  190. +                emulation = TRUE;
  191. +            }
  192.  
  193.              if(emulation) {
  194.                  stream_info = &stridedlcl;
  195. diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
  196. index 28de4ea..a13423b 100644
  197. --- a/dlls/wined3d/state.c
  198. +++ b/dlls/wined3d/state.c
  199. @@ -3670,7 +3670,7 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
  200.      if(context->last_was_rhw) {
  201.          glLoadIdentity();
  202.          checkGLcall("glLoadIdentity()");
  203. -    } else {
  204. +    } else if (!stateblock->device->vertexBlendSW) {
  205.          /* In the general case, the view matrix is the identity matrix */
  206.          if (stateblock->device->view_ident)
  207.          {
  208. @@ -3684,6 +3684,9 @@ static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, str
  209.              glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
  210.              checkGLcall("glMultMatrixf");
  211.          }
  212. +    } else {
  213. +        glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
  214. +        checkGLcall("glLoadMatrixf");
  215.      }
  216.  }
  217.  
  218. @@ -3769,13 +3772,33 @@ static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, s
  219.  
  220.  static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
  221.  {
  222. -    WINED3DVERTEXBLENDFLAGS f = stateblock->renderState[WINED3DRS_VERTEXBLEND];
  223. +    WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
  224.      static unsigned int once;
  225.  
  226. -    if (f == WINED3DVBF_DISABLE) return;
  227. -
  228. -    if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
  229. -    else WARN("Vertex blend flags %#x not supported.\n", f);
  230. +    switch (val) {
  231. +        case WINED3DVBF_0WEIGHTS:
  232. +        case WINED3DVBF_1WEIGHTS:
  233. +        case WINED3DVBF_2WEIGHTS:
  234. +        case WINED3DVBF_3WEIGHTS:
  235. +            if(!once) {
  236. +                once = TRUE;
  237. +                FIXME("Vertex blending enabled, but not supported by hardware. Using software emulation.\n");
  238. +            }
  239. +            if (!stateblock->device->vertexBlendSW) {
  240. +                stateblock->device->vertexBlendSW = TRUE;
  241. +                transform_world(state, stateblock, context);
  242. +            }
  243. +            break;
  244. +        case WINED3DVBF_TWEENING:
  245. +            WARN("Vertex blend flags %#x not supported.\n", val);
  246. +            /* fall through */
  247. +        default:
  248. +            if (stateblock->device->vertexBlendSW) {
  249. +                stateblock->device->vertexBlendSW = FALSE;
  250. +                transform_world(state, stateblock, context);
  251. +            }
  252. +            break;
  253. +    }
  254.  }
  255.  
  256.  static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
  257. diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
  258. index 0bc141a..9a87f7e 100644
  259. --- a/dlls/wined3d/vertexdeclaration.c
  260. +++ b/dlls/wined3d/vertexdeclaration.c
  261. @@ -125,6 +125,15 @@ static BOOL declaration_element_valid_ffp(const WINED3DVERTEXELEMENT *element)
  262.                  default:
  263.                      return FALSE;
  264.              }
  265. +            
  266. +        case WINED3DDECLUSAGE_BLENDINDICES:
  267. +            switch(element->format)
  268. +            {
  269. +                case WINED3DFMT_R8G8B8A8_UINT:
  270. +                    return TRUE;
  271. +                default:
  272. +                    return FALSE;
  273. +            }
  274.  
  275.          case WINED3DDECLUSAGE_NORMAL:
  276.              switch(element->format)
  277. diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
  278. index 179b4c4..b35ff81 100644
  279. --- a/dlls/wined3d/wined3d_private.h
  280. +++ b/dlls/wined3d/wined3d_private.h
  281. @@ -1624,6 +1624,7 @@ struct IWineD3DDeviceImpl
  282.      WORD view_ident : 1;                /* true iff view matrix is identity */
  283.      WORD untransformed : 1;
  284.      WORD vertexBlendUsed : 1;           /* To avoid needless setting of the blend matrices */
  285. +    WORD vertexBlendSW : 1;             /* vertexBlend software fallback used */
  286.      WORD isRecordingState : 1;
  287.      WORD isInDraw : 1;
  288.      WORD bCursorVisible : 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement