Hi, I'm attaching test, which demonstrates incorrect behavior of SetFVF and SetVertexDeclaration. Windows converts one to the other and backwards (at least partially), and we do not such thing - this breaks at least 2 demos (dx9_hlsl_*)

I'm posting it here, because:

- I don't have Windows, and I need someone to try it on machine with pixel shader support (preferably 3.0, will need to enable pshaders and GLSL registry key). The whole first part of the test checks decl to fvf conversions, and they're almost all set to 0 in order to pass on H. Verbeet and V. Margolen's setups [ which have no pshaders ]. MSDN has a whole page on how to convert to an fvf, and the values there are definitely *not* 0, so that's why I'm suspicious.

- Secondly, I am leaving for NYC in 2 days to look for a place to live, so I have limited time to clean up the test (ok/trace usage and the like), and I have no time to implement the fix. I am hoping someone else can finish it, because afterwards I go to Denver for a month, where I will have limited computing capabilities. Then I start a full time job back at NYC, so I'll be pretty busy. Anyway, I'm sure Jave has shaders under control and will be done with sm 2, 3, 4, 5.. 10 by the end of the summer whether I help or not :)


diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
diff --git a/dlls/d3d9/tests/vertexdeclaration.c b/dlls/d3d9/tests/vertexdeclaration.c
index 229b4a0..80071ba 100644
--- a/dlls/d3d9/tests/vertexdeclaration.c
+++ b/dlls/d3d9/tests/vertexdeclaration.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005 Henri Verbeet
+ * Copyright (C) 2006 Ivan Gyurdiev
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,11 @@ #include "wine/test.h"
 
 static HMODULE d3d9_handle = 0;
 
+/* FIXME: this double counts all test failures */
+#define VDECL_CHECK(fcall) \
+    ok(fcall == S_OK, "Test failure on line #%d\n", __LINE__);
+
+
 static HWND create_window(void)
 {
     WNDCLASS wc = {0};
@@ -144,6 +150,469 @@ static void test_get_declaration(IDirect
     HeapFree(GetProcessHeap(), 0, decl);
 }
 
+/* FIXME: also write a test, which shows that attempting to set
+ * an invalid vertex declaration returns E_FAIL */
+
+static HRESULT test_fvf_to_decl(
+    IDirect3DDevice9* device,
+    IDirect3DVertexDeclaration9* default_decl,
+    DWORD test_fvf,
+    CONST D3DVERTEXELEMENT9 expected_elements[],
+    D3DVERTEXELEMENT9* result_elements_ptr,
+    UINT expected_size,
+    char object_should_change) 
+{
+
+    HRESULT hr;
+    IDirect3DVertexDeclaration9 *result_decl = NULL;
+    UINT result_size = 12345;
+
+    /* Set a default declaration to make sure it is changed */
+    hr = IDirect3DDevice9_SetVertexDeclaration ( device, default_decl );
+    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+
+    /* Set an FVF */
+    hr = IDirect3DDevice9_SetFVF( device, test_fvf);
+    ok(SUCCEEDED(hr), "SetFVF returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+
+    /* Check if the declaration object changed underneath */
+    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl);
+    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+    if (object_should_change) {
+       ok(result_decl != default_decl, "result declaration matches original\n");
+       if (result_decl == default_decl) goto fail;
+    } else {
+       ok(result_decl == default_decl, "result declaration does not match original\n");
+       if (result_decl != default_decl) goto fail;
+    }
+
+    /* Declaration content/size test */
+    ok(result_decl != NULL, "result declaration was null\n");
+    if (result_decl == NULL) 
+        goto fail;
+    else { 
+
+        int status;
+
+        /* Check if the size changed, and abort if it did */
+        hr = IDirect3DVertexDeclaration9_GetDeclaration( result_decl, NULL, &result_size );
+        ok(SUCCEEDED(hr), "GetDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+        if (FAILED(hr)) goto fail;
+        ok(result_size == expected_size, "result declaration size: %d, "
+            "expected: %d\n", result_size, expected_size);
+        if (result_size != expected_size) goto fail;
+
+        /* Check the actual elements. Write it them in a caller-allocated array of the correct size
+         * That's fine, since we aborted above if the size didn't match the caller's expectations */
+        hr = IDirect3DVertexDeclaration9_GetDeclaration( result_decl, result_elements_ptr, &result_size );
+        ok(SUCCEEDED(hr), "GetDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+        if (FAILED(hr)) goto fail;
+        ok(result_size == expected_size, "result declaration size: %d, "
+            "expected: %d\n", result_size, expected_size);
+        if (result_size != expected_size) goto fail;
+        
+        status = memcmp(expected_elements, result_elements_ptr, expected_size * sizeof(D3DVERTEXELEMENT9));  
+        ok(!status, "result declaration differs from expected\n");
+        if (status) {
+            unsigned int i;
+
+            for (i = 0; i < expected_size; i++) { 
+
+                 /* FIXME: Use trace here? */
+                 ok(0, "Stream = %d, Offset = %d, Type = %d, "
+                     "Method = %d, Usage = %d, UsageIndex = %d\n", 
+                     result_elements_ptr[i].Stream,
+                     result_elements_ptr[i].Offset,
+                     result_elements_ptr[i].Type,
+                     result_elements_ptr[i].Method,
+                     result_elements_ptr[i].Usage,
+                     result_elements_ptr[i].UsageIndex);
+            }
+            goto fail;
+        }
+    }
+
+    if (result_decl) IUnknown_Release( result_decl );
+    return S_OK;    
+
+    fail:
+    if (result_decl) IUnknown_Release( result_decl );
+    return E_FAIL;
+}
+
+static HRESULT test_decl_to_fvf(
+    IDirect3DDevice9* device,
+    DWORD default_fvf,
+    CONST D3DVERTEXELEMENT9 test_decl[],
+    DWORD test_fvf)
+{
+
+    HRESULT hr;
+    IDirect3DVertexDeclaration9 *vdecl = NULL;
+
+    DWORD result_fvf = 0xdeadbeef;
+
+    /* Set a default FVF of SPECULAR and DIFFUSE to make sure it is changed back to 0 */
+    hr = IDirect3DDevice9_SetFVF( device, default_fvf);
+    ok(SUCCEEDED(hr), "SetFVF returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+
+    /* Create a testing declaration */
+    hr = IDirect3DDevice9_CreateVertexDeclaration( device, test_decl, &vdecl );
+    ok(SUCCEEDED(hr), "CreateVertexDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+
+    /* Set the declaration */
+    hr = IDirect3DDevice9_SetVertexDeclaration ( device, vdecl );
+    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+
+    /* Check the FVF */
+    hr = IDirect3DDevice9_GetFVF( device, &result_fvf);
+    ok(SUCCEEDED(hr), "GetFVF returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto fail;
+    ok(test_fvf == result_fvf, "result FVF was: %#lx, expected: %#lx\n", result_fvf, test_fvf);
+    if (test_fvf != result_fvf) goto fail;
+
+    IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
+    if (vdecl) IUnknown_Release( vdecl );
+    return S_OK;
+
+    fail:
+    IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
+    if (vdecl) IUnknown_Release( vdecl );
+    return E_FAIL;
+}
+
+static void test_fvf_decl_conversion(IDirect3DDevice9 *pDevice)
+{
+
+    HRESULT hr;
+    D3DVERTEXELEMENT9 result_buffer[MAXD3DDECLLENGTH];
+    unsigned int i;
+
+    IDirect3DVertexDeclaration9* default_decl = NULL;
+    DWORD default_fvf = D3DFVF_SPECULAR | D3DFVF_DIFFUSE;
+    D3DVERTEXELEMENT9 default_elements[] =
+        { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
+          { 0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() };
+
+    /* Create a default declaration and FVF that does not match any of the tests */
+    hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, default_elements, &default_decl );
+    ok(SUCCEEDED(hr), "CreateVertexDeclaration returned %#lx, expected %#lx\n", hr, D3D_OK);
+    if (FAILED(hr)) goto cleanup;
+
+    /* Test conversions from vertex declaration to an FVF.
+     * For some reason those seem to occur only for POSITION/POSITIONT,
+     * Otherwise the FVF is forced to 0 - maybe this is configuration specific */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, D3DFVF_XYZ));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, D3DFVF_XYZRHW));
+    }
+    for (i = 0; i < 4; i++) {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1+i, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] = 
+            { { 0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* Make sure textures of different sizes work */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* Make sure the TEXCOORD index works correctly - try several textures */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 },
+              { 0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 },
+              { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2 },
+              { 0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* No FVF mapping available */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* Try empty declaration */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] = { D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* Now try a combination test */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 },
+              { 0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 },
+              { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 },
+              { 0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 },
+              { 0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1 }, D3DDECL_END() };
+        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0));
+    }
+
+    /* Test conversions from FVF to a vertex declaration 
+     * These seem to always occur internally. A new declaration object is created if necessary */
+
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZ, test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+          { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZRHW, test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4,
+            test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR,
+           test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5, test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1, test_buffer, result_buffer, 3, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4,
+            test_buffer, result_buffer, 3, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR,
+            test_buffer, result_buffer, 3, 1));
+    }
+    {
+         CONST D3DVERTEXELEMENT9 test_buffer[] =
+             { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+               { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() };
+         VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2, test_buffer, result_buffer, 3, 1));
+    }
+    {
+         CONST D3DVERTEXELEMENT9 test_buffer[] =
+             { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+               { 0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+               { 0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+         VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4,
+             test_buffer, result_buffer, 4, 1));
+     }
+     {
+         CONST D3DVERTEXELEMENT9 test_buffer[] =
+             { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+               { 0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+               { 0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+         VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR,
+             test_buffer, result_buffer, 4, 1));
+     }
+     {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3, test_buffer, result_buffer, 3, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4,
+            test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR,
+            test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4, test_buffer, result_buffer, 3, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4,
+            test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+              { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+              { 0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR,
+            test_buffer, result_buffer, 4, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_NORMAL, test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_PSIZE, test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_DIFFUSE, test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_SPECULAR, test_buffer, result_buffer, 2, 1));
+    }
+
+    /* Make sure textures of different sizes work */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1,
+           test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1,
+           test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1,
+           test_buffer, result_buffer, 2, 1));
+    }
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1,
+           test_buffer, result_buffer, 2, 1));
+    }
+
+    /* Make sure the TEXCOORD index works correctly - try several textures */
+    {
+        CONST D3DVERTEXELEMENT9 test_buffer[] =
+            { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 },
+              { 0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 },
+              { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2 },
+              { 0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3 }, D3DDECL_END() };
+        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl,
+            D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2) |
+            D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4, test_buffer, result_buffer, 5, 1));
+    }
+
+    /* Now try a combination test  */
+    {
+       CONST D3DVERTEXELEMENT9 test_buffer[] =
+                { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
+                  { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 },
+                  { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 },
+                  { 0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 },
+                  { 0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
+                  { 0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 }, D3DDECL_END() };
+       VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_SPECULAR | D3DFVF_DIFFUSE |
+           D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2, test_buffer, result_buffer, 7, 1));
+    }
+
+    /* Setting the FVF to 0 should result in no change to the default decl */
+    VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, 0, default_elements, result_buffer, 3, 0));
+
+    cleanup:
+    IDirect3DDevice9_SetVertexDeclaration ( pDevice, NULL );
+    if ( default_decl ) IUnknown_Release (default_decl);
+}
+
 START_TEST(vertexdeclaration)
 {
     static D3DVERTEXELEMENT9 simple_decl[] = {
@@ -175,6 +644,6 @@ START_TEST(vertexdeclaration)
     }
 
     test_get_set_vertex_declaration(device_ptr, decl_ptr);
-
     test_get_declaration(decl_ptr, simple_decl, simple_decl_num_elements);
+    test_fvf_decl_conversion(device_ptr);
 }


Reply via email to