Example #1
0
static void test_unused_type(
    IDirect3DDevice9* device) {

    HRESULT hr;
    IDirect3DVertexDeclaration9* result_decl = NULL;
    int i;

    static const D3DVERTEXELEMENT9 test_elements[][3] =
    {
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_COLOR   , 0 },
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 0 },
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 1 },
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_TEXCOORD, 12},
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL,   0 },
            D3DDECL_END()
        },
        {
            { 0, 0,  D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 },
            { 1, 16, D3DDECLTYPE_UNUSED, 0, D3DDECLUSAGE_NORMAL,   0 },
            D3DDECL_END()
        },
    };

    for(i = 0; i < sizeof(test_elements) / sizeof(test_elements[0]); i++) {
        result_decl = NULL;
        hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &result_decl);
        ok(hr == E_FAIL, "CreateVertexDeclaration for declaration %d returned %#x, expected E_FAIL(%#x)\n",
                              i, hr, E_FAIL);
        if(result_decl) IDirect3DVertexDeclaration9_Release(result_decl);
    }
}
Example #2
0
static IDirect3DVertexDeclaration9 *test_create_vertex_declaration(IDirect3DDevice9 *device_ptr, D3DVERTEXELEMENT9 *vertex_decl)
{
    IDirect3DVertexDeclaration9 *decl_ptr = 0;
    HRESULT hret = 0;

    hret = IDirect3DDevice9_CreateVertexDeclaration(device_ptr, vertex_decl, &decl_ptr);
    ok(hret == D3D_OK && decl_ptr != NULL, "CreateVertexDeclaration returned: hret 0x%x, decl_ptr %p. "
        "Expected hret 0x%x, decl_ptr != %p. Aborting.\n", hret, decl_ptr, D3D_OK, NULL);

    return decl_ptr;
}
Example #3
0
static void createVertexBuffersD3D9()
{
    HRESULT hr;
    LPVOID ptr = NULL;
    int sizeInBytes = sizeof(float)*3*NUM_VERTICES;
    D3DVERTEXELEMENT9 decl[] = {
        { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        D3DDECL_END(),
    };

    hr = IDirect3DDevice9_CreateVertexBuffer(gDevicePtr, sizeInBytes, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &gVertexBufferPtr, NULL);
    if(FAILED(hr) || !gVertexBufferPtr) {
        fprintf(stderr, "Failed to create vertex buffer\n");
        return;
    }
    hr = IDirect3DVertexBuffer9_Lock(gVertexBufferPtr, 0, 0, &ptr, D3DLOCK_DISCARD);
    if (FAILED(hr) || !ptr) {
        fprintf(stderr, "Failed to lock vertex buffer\n");
        return;
    }
    memcpy(ptr, icosahedronVertices, sizeInBytes);
    hr = IDirect3DVertexBuffer9_Unlock(gVertexBufferPtr);
    if (FAILED(hr)) {
        fprintf(stderr, "Failed to unlock vertex buffer\n");
        return;
    }

    sizeInBytes = sizeof(unsigned short)*3*NUM_INDICES;
    hr = IDirect3DDevice9_CreateIndexBuffer(gDevicePtr, sizeInBytes, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &gIndexBufferPtr, NULL);
    if(FAILED(hr) || !gIndexBufferPtr) {
        fprintf(stderr, "Failed to create index buffer\n");
        return;
    }
    hr = IDirect3DIndexBuffer9_Lock(gIndexBufferPtr, 0, 0, &ptr, D3DLOCK_DISCARD);
    if (FAILED(hr) || !ptr) {
        fprintf(stderr, "Failed to lock index buffer\n");
        return;
    }
    memcpy(ptr, icosahedronIndices, sizeInBytes);
    hr = IDirect3DIndexBuffer9_Unlock(gIndexBufferPtr);
    if (FAILED(hr)) {
        fprintf(stderr, "Failed to unlock index buffer\n");
        return;
    }

    hr = IDirect3DDevice9_CreateVertexDeclaration(gDevicePtr, decl, &gVertexDeclPtr);
    if(FAILED(hr) || !gVertexDeclPtr) {
        fprintf(stderr, "Failed to create vertex declaration\n");
        return;
    }
}
Example #4
0
static void test_vertex_declaration_alignment(
    IDirect3DDevice9* device) {

    HRESULT hr;
    IDirect3DVertexDeclaration9* result_decl = NULL;
    int i;

    CONST D3DVERTEXELEMENT9 test_elements[5][3] =
    {
        {
            { 0, 0, D3DDECLTYPE_FLOAT3,   0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR  , 0 },
            D3DDECL_END()
        },
        {
            { 0, 0, D3DDECLTYPE_FLOAT3,   0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 17, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR  , 0 },
            D3DDECL_END()
        },
        {
            { 0, 0, D3DDECLTYPE_FLOAT3,   0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 18, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR  , 0 },
            D3DDECL_END()
        },
        {
            { 0, 0, D3DDECLTYPE_FLOAT3,   0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 19, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR  , 0 },
            D3DDECL_END()
        },
        {
            { 0, 0, D3DDECLTYPE_FLOAT3,   0, D3DDECLUSAGE_POSITION, 0 },
            { 0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR  , 0 },
            D3DDECL_END()
        }
    };
    HRESULT results[5] = {D3D_OK, E_FAIL, E_FAIL, E_FAIL, D3D_OK};

    for(i = 0; i < sizeof(test_elements) / sizeof(test_elements[0]); i++) {
        result_decl = NULL;
        hr = IDirect3DDevice9_CreateVertexDeclaration(device, test_elements[i], &result_decl);
        ok(hr == results[i], "CreateVertexDeclaration for declaration %d returned %#x, expected %#x\n",
                              i, hr, results[i]);
        if(result_decl) IDirect3DVertexDeclaration9_Release(result_decl);
    }
}
Example #5
0
static HRESULT test_decl_to_fvf(IDirect3DDevice9* device, DWORD default_fvf,
        const D3DVERTEXELEMENT9 test_decl[], DWORD test_fvf, BOOL todo)
{

    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 %#x, expected %#x\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 %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;

    /* Set the declaration */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, vdecl );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;

    /* Check the FVF */
    hr = IDirect3DDevice9_GetFVF( device, &result_fvf);
    ok(SUCCEEDED(hr), "GetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;
    if (todo) todo_wine ok(test_fvf == result_fvf, "result FVF was: %#x, expected: %#x\n", result_fvf, test_fvf);
    else ok(test_fvf == result_fvf, "result FVF was: %#x, expected: %#x\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;
}
Example #6
0
void _al_set_d3d_decl(ALLEGRO_VERTEX_DECL* ret)
{
#ifdef ALLEGRO_CFG_D3D
   int flags = al_get_display_flags();
   if (flags & ALLEGRO_DIRECT3D) {
      ALLEGRO_DISPLAY *display;
      LPDIRECT3DDEVICE9 device;
      D3DVERTEXELEMENT9 d3delements[ALLEGRO_PRIM_ATTR_NUM + 1];
      int idx = 0;
      ALLEGRO_VERTEX_ELEMENT* e;
      D3DCAPS9 caps;
      
      display = al_get_current_display();
      device = al_d3d_get_device(display);
      
      IDirect3DDevice9_GetDeviceCaps(device, &caps);
      if(caps.PixelShaderVersion < D3DPS_VERSION(3, 0)) {
         ret->d3d_decl = 0;
      } else {
         e = &ret->elements[ALLEGRO_PRIM_POSITION];
         if(e->attribute) {
            int type = 0;
            switch(e->storage) {
               case ALLEGRO_PRIM_FLOAT_2:
                  type = D3DDECLTYPE_FLOAT2;
               break;
               case ALLEGRO_PRIM_FLOAT_3:
                  type = D3DDECLTYPE_FLOAT3;
               break;
               case ALLEGRO_PRIM_SHORT_2:
                  type = D3DDECLTYPE_SHORT2;
               break;
            }
            d3delements[idx].Stream = 0;
            d3delements[idx].Offset = e->offset;
            d3delements[idx].Type = type;
            d3delements[idx].Method = D3DDECLMETHOD_DEFAULT;
            d3delements[idx].Usage = D3DDECLUSAGE_POSITION;
            d3delements[idx].UsageIndex = 0;
            idx++;
         }

         e = &ret->elements[ALLEGRO_PRIM_TEX_COORD];
         if(!e->attribute)
            e = &ret->elements[ALLEGRO_PRIM_TEX_COORD_PIXEL];
         if(e->attribute) {
            int type = 0;
            switch(e->storage) {
               case ALLEGRO_PRIM_FLOAT_2:
               case ALLEGRO_PRIM_FLOAT_3:
                  type = D3DDECLTYPE_FLOAT2;
               break;
               case ALLEGRO_PRIM_SHORT_2:
                  type = D3DDECLTYPE_SHORT2;
               break;
            }
            d3delements[idx].Stream = 0;
            d3delements[idx].Offset = e->offset;
            d3delements[idx].Type = type;
            d3delements[idx].Method = D3DDECLMETHOD_DEFAULT;
            d3delements[idx].Usage = D3DDECLUSAGE_TEXCOORD;
            d3delements[idx].UsageIndex = 0;
            idx++;
         }

         e = &ret->elements[ALLEGRO_PRIM_COLOR_ATTR];
         if(e->attribute) {
            d3delements[idx].Stream = 0;
            d3delements[idx].Offset = e->offset;
            d3delements[idx].Type = D3DDECLTYPE_D3DCOLOR;
            d3delements[idx].Method = D3DDECLMETHOD_DEFAULT;
            d3delements[idx].Usage = D3DDECLUSAGE_COLOR;
            d3delements[idx].UsageIndex = 0;
            idx++;
         }
         
         d3delements[idx].Stream = 0xFF;
         d3delements[idx].Offset = 0;
         d3delements[idx].Type = D3DDECLTYPE_UNUSED;
         d3delements[idx].Method = 0;
         d3delements[idx].Usage = 0;
         d3delements[idx].UsageIndex = 0;
         
         IDirect3DDevice9_CreateVertexDeclaration(device, d3delements, (IDirect3DVertexDeclaration9**)&ret->d3d_decl);
      }
   }
#else
   ret->d3d_decl = 0;
#endif
}
Example #7
0
static HRESULT WINAPI ID3DXSpriteImpl_Begin(ID3DXSprite *iface, DWORD flags)
{
    ID3DXSpriteImpl *This = impl_from_ID3DXSprite(iface);
    HRESULT hr;
    TRACE("(%p): relay\n", This);

    if(flags>D3DXSPRITE_FLAGLIMIT || This->ready) return D3DERR_INVALIDCALL;

    /* TODO: Implement flags:
    D3DXSPRITE_BILLBOARD: makes the sprite always face the camera
    D3DXSPRITE_DONOTMODIFY_RENDERSTATE: name says it all
    D3DXSPRITE_OBJECTSPACE: do not change device transforms
    D3DXSPRITE_SORT_DEPTH_BACKTOFRONT: sort by position
    D3DXSPRITE_SORT_DEPTH_FRONTTOBACK: sort by position
    D3DXSPRITE_SORT_TEXTURE: sort by texture (so that it doesn't change too often)
    */
    /* Seems like alpha blending is always enabled, regardless of D3DXSPRITE_ALPHABLEND flag */
    if(flags & (D3DXSPRITE_BILLBOARD |
                D3DXSPRITE_DONOTMODIFY_RENDERSTATE | D3DXSPRITE_OBJECTSPACE |
                D3DXSPRITE_SORT_DEPTH_BACKTOFRONT))
        FIXME("Flags unsupported: %#x\n", flags);
    /* These flags should only matter to performances */
    else if(flags & (D3DXSPRITE_SORT_DEPTH_FRONTTOBACK | D3DXSPRITE_SORT_TEXTURE))
        TRACE("Flags unsupported: %#x\n", flags);

    if(This->vdecl==NULL) {
        static const D3DVERTEXELEMENT9 elements[] =
        {
            { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
            { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
            { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
            D3DDECL_END()
        };
        IDirect3DDevice9_CreateVertexDeclaration(This->device, elements, &This->vdecl);
    }

    if(!(flags & D3DXSPRITE_DONOTSAVESTATE)) {
        if(This->stateblock==NULL) {
            /* Tell our state block what it must store */
            hr=IDirect3DDevice9_BeginStateBlock(This->device);
            if(hr!=D3D_OK) return hr;

            set_states(This);

            IDirect3DDevice9_SetVertexDeclaration(This->device, This->vdecl);
            IDirect3DDevice9_SetStreamSource(This->device, 0, NULL, 0, sizeof(SPRITEVERTEX));
            IDirect3DDevice9_SetIndices(This->device, NULL);
            IDirect3DDevice9_SetTexture(This->device, 0, NULL);

            IDirect3DDevice9_EndStateBlock(This->device, &This->stateblock);
        }
        IDirect3DStateBlock9_Capture(This->stateblock); /* Save current state */
    }

    /* Apply device state */
    set_states(This);

    This->flags=flags;
    This->ready=TRUE;

    return D3D_OK;
}
Example #8
0
static void test_fvf_decl_conversion(IDirect3DDevice9 *pDevice)
{

    HRESULT hr;
    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 %#x, expected %#x\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, TRUE));
    }
    {
        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, TRUE));
    }
    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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }

    /* 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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }
    {
        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, FALSE));
    }

    /* 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, FALSE));
    }

    /* 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, FALSE));
    }
    {
        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, FALSE));
    }

    /* Try empty declaration */
    {
        CONST D3DVERTEXELEMENT9 test_buffer[] = { D3DDECL_END() };
        VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE));
    }

    /* 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, FALSE));
    }

    /* 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, 1));
    }
    {
        CONST D3DVERTEXELEMENT9 test_buffer[] =
            { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() };
        VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZW, test_buffer, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0));

    cleanup:
    IDirect3DDevice9_SetVertexDeclaration ( pDevice, NULL );
    if ( default_decl ) IUnknown_Release (default_decl);
}