- sync wined3d, d3d8, d3d9, ddraw with Wine 1.1.19
authorKamil Hornicek <kamil.hornicek@reactos.org>
Wed, 15 Apr 2009 20:40:10 +0000 (20:40 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Wed, 15 Apr 2009 20:40:10 +0000 (20:40 +0000)
svn path=/trunk/; revision=40534

31 files changed:
reactos/dll/directx/wine/d3d8/d3d8_private.h
reactos/dll/directx/wine/d3d8/device.c
reactos/dll/directx/wine/d3d8/directx.c
reactos/dll/directx/wine/d3d8/indexbuffer.c
reactos/dll/directx/wine/d3d8/vertexbuffer.c
reactos/dll/directx/wine/d3d9/Makefile.in [deleted file]
reactos/dll/directx/wine/d3d9/d3d9_private.h
reactos/dll/directx/wine/d3d9/device.c
reactos/dll/directx/wine/d3d9/directx.c
reactos/dll/directx/wine/d3d9/indexbuffer.c
reactos/dll/directx/wine/d3d9/vertexbuffer.c
reactos/dll/directx/wine/ddraw/ddraw_private.h
reactos/dll/directx/wine/ddraw/device.c
reactos/dll/directx/wine/ddraw/direct3d.c
reactos/dll/directx/wine/ddraw/surface.c
reactos/dll/directx/wine/ddraw/vertexbuffer.c
reactos/dll/directx/wine/wined3d/arb_program_shader.c
reactos/dll/directx/wine/wined3d/baseshader.c
reactos/dll/directx/wine/wined3d/buffer.c
reactos/dll/directx/wine/wined3d/device.c
reactos/dll/directx/wine/wined3d/directx.c
reactos/dll/directx/wine/wined3d/drawprim.c
reactos/dll/directx/wine/wined3d/glsl_shader.c
reactos/dll/directx/wine/wined3d/pixelshader.c
reactos/dll/directx/wine/wined3d/state.c
reactos/dll/directx/wine/wined3d/stateblock.c
reactos/dll/directx/wine/wined3d/utils.c
reactos/dll/directx/wine/wined3d/vertexshader.c
reactos/dll/directx/wine/wined3d/wined3d_gl.h
reactos/dll/directx/wine/wined3d/wined3d_private.h
reactos/include/reactos/wine/wined3d.idl

index cbd6f76..c9afe17 100644 (file)
@@ -326,6 +326,8 @@ struct IDirect3DVertexBuffer8Impl
 
     /* Parent reference */
     LPDIRECT3DDEVICE8                 parentDevice;
+
+    DWORD                             fvf;
 };
 
 /* --------------------- */
@@ -347,10 +349,12 @@ struct IDirect3DIndexBuffer8Impl
     LONG                             ref;
 
     /* IDirect3DResource8 fields */
-    IWineD3DIndexBuffer             *wineD3DIndexBuffer;
+    IWineD3DBuffer                  *wineD3DIndexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE8                parentDevice;
+
+    WINED3DFORMAT                    format;
 };
 
 /* --------------------- */
index 0e8c480..985557c 100644 (file)
@@ -737,8 +737,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexBuffer(LPDIRECT3DDEVICE8
     object->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
     object->ref = 1;
     EnterCriticalSection(&d3d8_cs);
-    hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL, (IUnknown *)object);
+    hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
+            0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), NULL,
+            (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
+    object->fvf = FVF;
 
     if (D3D_OK != hrc) {
 
@@ -770,10 +773,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateIndexBuffer(LPDIRECT3DDEVICE8 i
 
     object->lpVtbl = &Direct3DIndexBuffer8_Vtbl;
     object->ref = 1;
+    object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d8_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
-            wined3dformat_from_d3dformat(Format), (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer,
+            (WINED3DPOOL) Pool, &object->wineD3DIndexBuffer,
             NULL, (IUnknown *)object);
     LeaveCriticalSection(&d3d8_cs);
 
@@ -1661,10 +1665,11 @@ static HRESULT WINAPI IDirect3DDevice8Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVI
 static HRESULT WINAPI IDirect3DDevice8Impl_ProcessVertices(LPDIRECT3DDEVICE8 iface, UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr;
+    IDirect3DVertexBuffer8Impl *dest = (IDirect3DVertexBuffer8Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer8Impl *)pDestBuffer)->wineD3DVertexBuffer, NULL, Flags);
+    hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, NULL, Flags, dest->fvf);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -2081,6 +2086,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderFunction(LPDIRECT3DDEV
 static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8* pIndexData, UINT baseVertexIndex) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
     HRESULT hr;
+    IDirect3DIndexBuffer8Impl *ib = (IDirect3DIndexBuffer8Impl *)pIndexData;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
@@ -2092,14 +2098,15 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetIndices(LPDIRECT3DDEVICE8 iface, I
      */
     IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, baseVertexIndex);
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
-            pIndexData ? ((IDirect3DIndexBuffer8Impl *)pIndexData)->wineD3DIndexBuffer : NULL);
+            ib ? ib->wineD3DIndexBuffer : NULL,
+            ib ? ib->format : WINED3DFMT_UNKNOWN);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
 
 static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-    IWineD3DIndexBuffer *retIndexData = NULL;
+    IWineD3DBuffer *retIndexData = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n", This);
@@ -2113,8 +2120,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, I
     IWineD3DDevice_GetBaseVertexIndex(This->WineD3DDevice, (INT *) pBaseVertexIndex);
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
-        IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
-        IWineD3DIndexBuffer_Release(retIndexData);
+        IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
+        IWineD3DBuffer_Release(retIndexData);
     } else {
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
index 45d914b..64fc360 100644 (file)
@@ -188,11 +188,23 @@ static HRESULT  WINAPI  IDirect3D8Impl_CheckDeviceFormat          (LPDIRECT3D8 i
                                                             DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
     IDirect3D8Impl *This = (IDirect3D8Impl *)iface;
     HRESULT hr;
+    WINED3DRESOURCETYPE WineD3DRType;
     TRACE("(%p)->(%d, %d, %d, %08x, %d, %d)\n", This, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat);
 
+    switch(RType) {
+        case D3DRTYPE_VERTEXBUFFER:
+        case D3DRTYPE_INDEXBUFFER:
+            WineD3DRType = WINED3DRTYPE_BUFFER;
+            break;
+
+        default:
+            WineD3DRType = RType;
+            break;
+    }
+
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
-            Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
+            Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
index 8a0a155..a0de5c5 100644 (file)
@@ -57,7 +57,7 @@ static ULONG WINAPI IDirect3DIndexBuffer8Impl_Release(LPDIRECT3DINDEXBUFFER8 ifa
 
     if (ref == 0) {
         EnterCriticalSection(&d3d8_cs);
-        IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -73,7 +73,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDevice(LPDIRECT3DINDEXBUFFER8
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
+    hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
@@ -89,7 +89,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_SetPrivateData(LPDIRECT3DINDEXBU
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
+    hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -100,7 +100,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetPrivateData(LPDIRECT3DINDEXBU
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -111,7 +111,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_FreePrivateData(LPDIRECT3DINDEXB
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -122,7 +122,7 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_SetPriority(LPDIRECT3DINDEXBUFFER8
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
+    ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -133,7 +133,7 @@ static DWORD WINAPI IDirect3DIndexBuffer8Impl_GetPriority(LPDIRECT3DINDEXBUFFER8
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer);
+    ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -143,19 +143,15 @@ static void WINAPI IDirect3DIndexBuffer8Impl_PreLoad(LPDIRECT3DINDEXBUFFER8 ifac
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d8_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer8Impl_GetType(LPDIRECT3DINDEXBUFFER8 iface) {
     IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
-    D3DRESOURCETYPE type;
-    TRACE("(%p) Relay\n", This);
+    TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-    type = IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
-    return type;
+    return D3DRTYPE_INDEXBUFFER;
 }
 
 /* IDirect3DIndexBuffer8 Interface follow: */
@@ -165,7 +161,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Lock(LPDIRECT3DINDEXBUFFER8 ifac
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -176,7 +172,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -184,13 +180,20 @@ static HRESULT WINAPI IDirect3DIndexBuffer8Impl_Unlock(LPDIRECT3DINDEXBUFFER8 if
 static HRESULT WINAPI IDirect3DIndexBuffer8Impl_GetDesc(LPDIRECT3DINDEXBUFFER8 iface, D3DINDEXBUFFER_DESC *pDesc) {
     IDirect3DIndexBuffer8Impl *This = (IDirect3DIndexBuffer8Impl *)iface;
     HRESULT hr;
+    WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     LeaveCriticalSection(&d3d8_cs);
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr)) {
+        pDesc->Format = d3dformat_from_wined3dformat(This->format);
+        pDesc->Type = D3DRTYPE_INDEXBUFFER;
+        pDesc->Usage = desc.Usage;
+        pDesc->Pool = desc.Pool;
+        pDesc->Size = desc.Size;
+    }
 
     return hr;
 }
index 74d6dca..a282cda 100644 (file)
@@ -151,13 +151,9 @@ static void WINAPI IDirect3DVertexBuffer8Impl_PreLoad(LPDIRECT3DVERTEXBUFFER8 if
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer8Impl_GetType(LPDIRECT3DVERTEXBUFFER8 iface) {
     IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
-    D3DRESOURCETYPE type;
-    TRACE("(%p) Relay\n", This);
+    TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d8_cs);
-    type = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d8_cs);
-    return type;
+    return D3DRTYPE_VERTEXBUFFER;
 }
 
 /* IDirect3DVertexBuffer8 Interface follow: */
@@ -186,13 +182,21 @@ static HRESULT WINAPI IDirect3DVertexBuffer8Impl_Unlock(LPDIRECT3DVERTEXBUFFER8
 static HRESULT WINAPI IDirect3DVertexBuffer8Impl_GetDesc(LPDIRECT3DVERTEXBUFFER8 iface, D3DVERTEXBUFFER_DESC *pDesc) {
     IDirect3DVertexBuffer8Impl *This = (IDirect3DVertexBuffer8Impl *)iface;
     HRESULT hr;
+    WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     LeaveCriticalSection(&d3d8_cs);
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr)) {
+        pDesc->Type = D3DRTYPE_VERTEXBUFFER;
+        pDesc->Usage = desc.Usage;
+        pDesc->Pool = desc.Pool;
+        pDesc->Size = desc.Size;
+        pDesc->FVF = This->fvf;
+        pDesc->Format = D3DFMT_VERTEXDATA;
+    }
 
     return hr;
 }
diff --git a/reactos/dll/directx/wine/d3d9/Makefile.in b/reactos/dll/directx/wine/d3d9/Makefile.in
deleted file mode 100644 (file)
index f581b68..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR    = @srcdir@
-VPATH     = @srcdir@
-MODULE    = d3d9.dll
-IMPORTLIB = d3d9
-IMPORTS   = dxguid uuid wined3d kernel32
-
-C_SRCS = \
-       basetexture.c \
-       cubetexture.c \
-       d3d9_main.c \
-       device.c \
-       directx.c \
-       indexbuffer.c \
-       pixelshader.c \
-       query.c \
-       resource.c \
-       stateblock.c \
-       surface.c \
-       swapchain.c \
-       texture.c \
-       vertexbuffer.c \
-       vertexdeclaration.c \
-       vertexshader.c \
-       volume.c \
-       volumetexture.c
-
-RC_SRCS = version.rc
-
-@MAKE_DLL_RULES@
-
-@DEPENDENCIES@  # everything below this line is overwritten by make depend
index ac6cfaa..25b6ae2 100644 (file)
@@ -329,6 +329,8 @@ typedef struct IDirect3DVertexBuffer9Impl
 
     /* Parent reference */
     LPDIRECT3DDEVICE9EX       parentDevice;
+
+    DWORD fvf;
 } IDirect3DVertexBuffer9Impl;
 
 /* --------------------- */
@@ -345,10 +347,11 @@ typedef struct IDirect3DIndexBuffer9Impl
     LONG                    ref;
 
     /* IDirect3DResource9 fields */
-    IWineD3DIndexBuffer    *wineD3DIndexBuffer;
+    IWineD3DBuffer         *wineD3DIndexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE9EX       parentDevice;
+    WINED3DFORMAT             format;
 } IDirect3DIndexBuffer9Impl;
 
 /* --------------------- */
index a917884..8d88e52 100644 (file)
@@ -428,17 +428,18 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
     HRESULT ret = S_OK;
     WINED3DSURFACE_DESC surface_desc;
     WINED3DVOLUME_DESC volume_desc;
-    WINED3DINDEXBUFFER_DESC index_desc;
-    WINED3DVERTEXBUFFER_DESC vertex_desc;
+    D3DINDEXBUFFER_DESC index_desc;
+    D3DVERTEXBUFFER_DESC vertex_desc;
     WINED3DFORMAT dummy_format;
     WINED3DMULTISAMPLE_TYPE dummy_multisampletype;
     DWORD dummy_dword;
     WINED3DPOOL pool = WINED3DPOOL_SCRATCH; /* a harmless pool */
-    IUnknown *parent;
+    IDirect3DResource9 *parent;
 
-    type = IWineD3DResource_GetType(resource);
+    IWineD3DResource_GetParent(resource, (IUnknown **) &parent);
+    type = IDirect3DResource9_GetType(parent);
     switch(type) {
-        case WINED3DRTYPE_SURFACE:
+        case D3DRTYPE_SURFACE:
             surface_desc.Format = &dummy_format;
             surface_desc.Type = &type;
             surface_desc.Usage = &dummy_dword;
@@ -452,7 +453,7 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
             IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
             break;
 
-        case WINED3DRTYPE_VOLUME:
+        case D3DRTYPE_VOLUME:
             volume_desc.Format = &dummy_format;
             volume_desc.Type = &type;
             volume_desc.Usage = &dummy_dword;
@@ -464,13 +465,13 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
             IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
             break;
 
-        case WINED3DRTYPE_INDEXBUFFER:
-            IWineD3DIndexBuffer_GetDesc((IWineD3DIndexBuffer *) resource, &index_desc);
+        case D3DRTYPE_INDEXBUFFER:
+            IDirect3DIndexBuffer9_GetDesc((IDirect3DIndexBuffer9 *) parent, &index_desc);
             pool = index_desc.Pool;
             break;
 
-        case WINED3DRTYPE_VERTEXBUFFER:
-            IWineD3DBuffer_GetDesc((IWineD3DBuffer *)resource, &vertex_desc);
+        case D3DRTYPE_VERTEXBUFFER:
+            IDirect3DVertexBuffer9_GetDesc((IDirect3DVertexBuffer9 *)parent, &vertex_desc);
             pool = vertex_desc.Pool;
             break;
 
@@ -482,7 +483,6 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
     }
 
     if(pool == WINED3DPOOL_DEFAULT) {
-        IWineD3DResource_GetParent(resource, &parent);
         if(IUnknown_Release(parent) == 0) {
             TRACE("Parent %p is an implicit resource with ref 0\n", parent);
         } else {
@@ -490,6 +490,8 @@ static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data
             ret = S_FALSE;
             *resources_ok = FALSE;
         }
+    } else {
+        IUnknown_Release(parent);
     }
     IWineD3DResource_Release(resource);
 
@@ -514,8 +516,7 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3
      * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
      */
     EnterCriticalSection(&d3d9_cs);
-
-    IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL);
+    IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
     for(i = 0; i < 16; i++) {
         IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
     }
@@ -1447,10 +1448,11 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
     HRESULT hr;
+    IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
     TRACE("(%p) Relay\n" , This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, ((IDirect3DVertexBuffer9Impl *)pDestBuffer)->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags);
+    hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -1636,18 +1638,20 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVIC
 static HRESULT  WINAPI  IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9* pIndexData) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
+    IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
-            pIndexData ? ((IDirect3DIndexBuffer9Impl *)pIndexData)->wineD3DIndexBuffer : NULL);
+            ib ? ib->wineD3DIndexBuffer : NULL,
+            ib ? ib->format : WINED3DFMT_UNKNOWN);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
 
 static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9 **ppIndexData) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    IWineD3DIndexBuffer *retIndexData = NULL;
+    IWineD3DBuffer *retIndexData = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n", This);
@@ -1659,8 +1663,8 @@ static HRESULT  WINAPI  IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX ifac
     EnterCriticalSection(&d3d9_cs);
     rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
     if (SUCCEEDED(rc) && retIndexData) {
-        IWineD3DIndexBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
-        IWineD3DIndexBuffer_Release(retIndexData);
+        IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
+        IWineD3DBuffer_Release(retIndexData);
     } else {
         if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
         *ppIndexData = NULL;
index 96fea01..229368a 100644 (file)
@@ -194,11 +194,23 @@ static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9EX iface,
                                                  DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) {
     IDirect3D9Impl *This = (IDirect3D9Impl *)iface;
     HRESULT hr;
+    WINED3DRESOURCETYPE WineD3DRType;
     TRACE("%p\n", This);
 
+    switch(RType) {
+        case D3DRTYPE_VERTEXBUFFER:
+        case D3DRTYPE_INDEXBUFFER:
+            WineD3DRType = WINED3DRTYPE_BUFFER;
+            break;
+
+        default:
+            WineD3DRType = RType;
+            break;
+    }
+
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3D_CheckDeviceFormat(This->WineD3D, Adapter, DeviceType, wined3dformat_from_d3dformat(AdapterFormat),
-            Usage, RType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
+            Usage, WineD3DRType, wined3dformat_from_d3dformat(CheckFormat), SURFACE_OPENGL);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
index 2f3ca64..161ff64 100644 (file)
@@ -58,7 +58,7 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa
 
     if (ref == 0) {
         EnterCriticalSection(&d3d9_cs);
-        IWineD3DIndexBuffer_Release(This->wineD3DIndexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DIndexBuffer);
         LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -74,7 +74,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetDevice(LPDIRECT3DINDEXBUFFER9
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
+    hr = IWineD3DBuffer_GetDevice(This->wineD3DIndexBuffer, &wined3d_device);
     if (SUCCEEDED(hr))
     {
         IWineD3DDevice_GetParent(wined3d_device, (IUnknown **)ppDevice);
@@ -90,7 +90,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_SetPrivateData(LPDIRECT3DINDEXBU
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
+    hr = IWineD3DBuffer_SetPrivateData(This->wineD3DIndexBuffer, refguid, pData, SizeOfData, Flags);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -101,7 +101,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_GetPrivateData(LPDIRECT3DINDEXBU
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DIndexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -112,7 +112,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_FreePrivateData(LPDIRECT3DINDEXB
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DIndexBuffer, refguid);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -123,7 +123,7 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_SetPriority(LPDIRECT3DINDEXBUFFER9
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DIndexBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
+    ret = IWineD3DBuffer_SetPriority(This->wineD3DIndexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
@@ -134,7 +134,7 @@ static DWORD WINAPI IDirect3DIndexBuffer9Impl_GetPriority(LPDIRECT3DINDEXBUFFER9
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DIndexBuffer_GetPriority(This->wineD3DIndexBuffer);
+    ret = IWineD3DBuffer_GetPriority(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
@@ -144,19 +144,15 @@ static void WINAPI IDirect3DIndexBuffer9Impl_PreLoad(LPDIRECT3DINDEXBUFFER9 ifac
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    IWineD3DIndexBuffer_PreLoad(This->wineD3DIndexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d9_cs);
 }
 
 static D3DRESOURCETYPE WINAPI IDirect3DIndexBuffer9Impl_GetType(LPDIRECT3DINDEXBUFFER9 iface) {
     IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface;
-    D3DRESOURCETYPE ret;
-    TRACE("(%p) Relay\n", This);
+    TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DIndexBuffer_GetType(This->wineD3DIndexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
-    return ret;
+    return D3DRTYPE_INDEXBUFFER;
 }
 
 /* IDirect3DIndexBuffer9 Interface follow: */
@@ -166,7 +162,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Lock(LPDIRECT3DINDEXBUFFER9 ifac
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_Lock(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DIndexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -177,7 +173,7 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_Unlock(This->wineD3DIndexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DIndexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -185,13 +181,20 @@ static HRESULT WINAPI IDirect3DIndexBuffer9Impl_Unlock(LPDIRECT3DINDEXBUFFER9 if
 static HRESULT  WINAPI        IDirect3DIndexBuffer9Impl_GetDesc(LPDIRECT3DINDEXBUFFER9 iface, D3DINDEXBUFFER_DESC *pDesc) {
     IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface;
     HRESULT hr;
+    WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DIndexBuffer_GetDesc(This->wineD3DIndexBuffer, (WINED3DINDEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DIndexBuffer, &desc);
     LeaveCriticalSection(&d3d9_cs);
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr)) {
+        pDesc->Format = d3dformat_from_wined3dformat(This->format);
+        pDesc->Usage = desc.Usage;
+        pDesc->Pool = desc.Pool;
+        pDesc->Size = desc.Size;
+        pDesc->Type = D3DRTYPE_INDEXBUFFER;
+    }
 
     return hr;
 }
@@ -238,10 +241,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(LPDIRECT3DDEVICE9EX iface,
 
     object->lpVtbl = &Direct3DIndexBuffer9_Vtbl;
     object->ref = 1;
+    object->format = wined3dformat_from_d3dformat(Format);
     TRACE("Calling wined3d create index buffer\n");
     EnterCriticalSection(&d3d9_cs);
     hrc = IWineD3DDevice_CreateIndexBuffer(This->WineD3DDevice, Length, Usage & WINED3DUSAGE_MASK,
-            wined3dformat_from_d3dformat(Format), (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
+            (WINED3DPOOL)Pool, &object->wineD3DIndexBuffer,
             pSharedHandle, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     if (hrc != D3D_OK) {
index 1a41c01..8c65a88 100644 (file)
@@ -154,13 +154,9 @@ static void WINAPI IDirect3DVertexBuffer9Impl_PreLoad(LPDIRECT3DVERTEXBUFFER9 if
 
 static D3DRESOURCETYPE WINAPI IDirect3DVertexBuffer9Impl_GetType(LPDIRECT3DVERTEXBUFFER9 iface) {
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
-    D3DRESOURCETYPE ret;
-    TRACE("(%p) Relay\n", This);
+    TRACE("(%p)\n", This);
 
-    EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
-    LeaveCriticalSection(&d3d9_cs);
-    return ret;
+    return D3DRTYPE_VERTEXBUFFER;
 }
 
 /* IDirect3DVertexBuffer9 Interface follow: */
@@ -189,13 +185,22 @@ static HRESULT WINAPI IDirect3DVertexBuffer9Impl_Unlock(LPDIRECT3DVERTEXBUFFER9
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetDesc(LPDIRECT3DVERTEXBUFFER9 iface, D3DVERTEXBUFFER_DESC* pDesc) {
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
     HRESULT hr;
+    WINED3DBUFFER_DESC desc;
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &desc);
     LeaveCriticalSection(&d3d9_cs);
 
-    if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
+    if (SUCCEEDED(hr)) {
+        pDesc->Format = D3DFMT_VERTEXDATA;
+        pDesc->Usage = desc.Usage;
+        pDesc->Pool = desc.Pool;
+        pDesc->Size = desc.Size;
+        pDesc->Type = D3DRTYPE_VERTEXBUFFER;
+        pDesc->FVF = This->fvf;
+    }
+
 
     return hr;
 }
@@ -240,8 +245,11 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(LPDIRECT3DDEVICE9EX iface
 
     object->lpVtbl = &Direct3DVertexBuffer9_Vtbl;
     object->ref = 1;
+    object->fvf = FVF;
     EnterCriticalSection(&d3d9_cs);
-    hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK, FVF, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer), pSharedHandle, (IUnknown *)object);
+    hrc = IWineD3DDevice_CreateVertexBuffer(This->WineD3DDevice, Size, Usage & WINED3DUSAGE_MASK,
+            0 /* fvf for ddraw only */, (WINED3DPOOL) Pool, &(object->wineD3DVertexBuffer),
+            pSharedHandle, (IUnknown *)object);
     LeaveCriticalSection(&d3d9_cs);
     
     if (hrc != D3D_OK) {
index c266c68..cd05e16 100644 (file)
@@ -378,7 +378,7 @@ struct IDirect3DDeviceImpl
     /* Other object connections */
     IWineD3DDevice          *wineD3DDevice;
     IDirectDrawImpl         *ddraw;
-    IWineD3DIndexBuffer     *indexbuffer;
+    IWineD3DBuffer          *indexbuffer;
     IDirectDrawSurfaceImpl  *target;
     BOOL                    OffScreenTarget;
 
@@ -680,6 +680,7 @@ struct IDirect3DVertexBufferImpl
 
     /*** Storage for D3D7 specific things ***/
     DWORD                Caps;
+    DWORD                fvf;
 };
 
 /* The Vtables */
index 1192e45..7c8e222 100644 (file)
@@ -316,9 +316,9 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
 
         EnterCriticalSection(&ddraw_cs);
         /* Free the index buffer. */
-        IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
-        IWineD3DIndexBuffer_GetParent(This->indexbuffer,
-                                      (IUnknown **) &IndexBufferParent);
+        IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
+        IWineD3DBuffer_GetParent(This->indexbuffer,
+                                 (IUnknown **) &IndexBufferParent);
         IParent_Release(IndexBufferParent); /* Once for the getParent */
         if( IParent_Release(IndexBufferParent) != 0)  /* And now to destroy it */
         {
@@ -4104,7 +4104,6 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
     IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
     HRESULT hr;
     DWORD stride;
-    WINED3DVERTEXBUFFER_DESC Desc;
 
     TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
 
@@ -4114,18 +4113,9 @@ IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
         ERR("(%p) No Vertex buffer specified\n", This);
         return DDERR_INVALIDPARAMS;
     }
+    stride = get_flexible_vertex_size(vb->fvf);
 
-    /* Get the FVF of the vertex buffer, and its stride */
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc);
-    if(hr != D3D_OK)
-    {
-        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
-        LeaveCriticalSection(&ddraw_cs);
-        return hr;
-    }
-    stride = get_flexible_vertex_size(Desc.FVF);
-
     hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
                                              vb->wineD3DVertexDeclaration);
     if(FAILED(hr))
@@ -4229,32 +4219,20 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
 {
     IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
     IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
-    DWORD stride;
+    DWORD stride = get_flexible_vertex_size(vb->fvf);
     WORD *LockedIndices;
     HRESULT hr;
-    WINED3DVERTEXBUFFER_DESC Desc;
 
     TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
 
     /* Steps:
-     * 1) Calculate some things: stride, ...
-     * 2) Upload the Indices to the index buffer
-     * 3) Set the index source
-     * 4) Set the Vertex Buffer as the Stream source
-     * 5) Call IWineD3DDevice::DrawIndexedPrimitive
+     * 1) Upload the Indices to the index buffer
+     * 2) Set the index source
+     * 3) Set the Vertex Buffer as the Stream source
+     * 4) Call IWineD3DDevice::DrawIndexedPrimitive
      */
 
     EnterCriticalSection(&ddraw_cs);
-    /* Get the FVF of the vertex buffer, and its stride */
-    hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc);
-    if(hr != D3D_OK)
-    {
-        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
-        LeaveCriticalSection(&ddraw_cs);
-        return hr;
-    }
-    stride = get_flexible_vertex_size(Desc.FVF);
-    TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
 
     hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
                                              vb->wineD3DVertexDeclaration);
@@ -4271,30 +4249,31 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
      * or a SetData-Method for the index buffer, which
      * overrides the index buffer data with our pointer.
      */
-    hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
-                                  0 /* OffSetToLock */,
-                                  IndexCount * sizeof(WORD),
-                                  (BYTE **) &LockedIndices,
-                                  0 /* Flags */);
+    hr = IWineD3DBuffer_Map(This->indexbuffer,
+                            0 /* OffSetToLock */,
+                            IndexCount * sizeof(WORD),
+                            (BYTE **) &LockedIndices,
+                            0 /* Flags */);
     assert(IndexCount < 0x100000);
     if(hr != D3D_OK)
     {
-        ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
+        ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
     memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
-    hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
+    hr = IWineD3DBuffer_Unmap(This->indexbuffer);
     if(hr != D3D_OK)
     {
-        ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
+        ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
 
     /* Set the index stream */
     IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
-    hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
+    hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer,
+                                   WINED3DFMT_R16_UINT);
 
     /* Set the vertex stream source */
     hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
index 2a051d0..aeba55b 100644 (file)
@@ -820,11 +820,11 @@ IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface,
 
     /* Create an Index Buffer. WineD3D needs one for Drawing indexed primitives
      * Create a (hopefully) long enough buffer, and copy the indices into it
-     * Ideally, a IWineD3DIndexBuffer::SetData method could be created, which
+     * Ideally, a IWineD3DBuffer::SetData method could be created, which
      * takes the pointer and avoids the memcpy
      */
     hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, 0x40000 /* Length. Don't know how long it should be */,
-            WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DFMT_R16_UINT /* Format. D3D7 uses WORDS */, WINED3DPOOL_DEFAULT,
+            WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT,
             &object->indexbuffer, 0 /* Handle */, (IUnknown *)IndexBufferParent);
 
     if(FAILED(hr))
@@ -1017,6 +1017,7 @@ IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface,
 
     object->Caps = Desc->dwCaps;
     object->ddraw = This;
+    object->fvf = Desc->dwFVF;
 
     EnterCriticalSection(&ddraw_cs);
     hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice,
index 7254e7c..14fc721 100644 (file)
@@ -310,7 +310,7 @@ IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface)
                 TRACE("(%p) Destroying the render target, uninitializing D3D\n", This);
 
                 /* Unset any index buffer, just to be sure */
-                IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL);
+                IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
                 IWineD3DDevice_SetDepthStencilSurface(ddraw->wineD3DDevice, NULL);
                 IWineD3DDevice_SetVertexDeclaration(ddraw->wineD3DDevice, NULL);
                 for(i = 0; i < ddraw->numConvertedDecls; i++)
index 277591c..df7528b 100644 (file)
@@ -234,7 +234,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
                                DWORD *Size)
 {
     IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface;
-    WINED3DVERTEXBUFFER_DESC Desc;
+    WINED3DBUFFER_DESC Desc;
     HRESULT hr;
     TRACE("(%p)->(%08x,%p,%p)\n", This, Flags, Data, Size);
 
@@ -245,7 +245,7 @@ IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface,
         hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &Desc);
         if(hr != D3D_OK)
         {
-            ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr);
+            ERR("(%p) IWineD3DBuffer::GetDesc failed with hr=%08x\n", This, hr);
             LeaveCriticalSection(&ddraw_cs);
             return hr;
         }
@@ -340,7 +340,6 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
     IDirect3DDeviceImpl *D3D = (IDirect3DDeviceImpl *)D3DDevice;
     BOOL oldClip, doClip;
     HRESULT hr;
-    WINED3DVERTEXBUFFER_DESC Desc;
 
     TRACE("(%p)->(%08x,%d,%d,%p,%d,%p,%08x)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags);
 
@@ -372,12 +371,11 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
                                       doClip);
     }
 
-    IWineD3DBuffer_GetDesc(Src->wineD3DVertexBuffer, &Desc);
     IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice,
                                    0, /* Stream No */
                                    Src->wineD3DVertexBuffer,
                                    0, /* Offset */
-                                   get_flexible_vertex_size(Desc.FVF));
+                                   get_flexible_vertex_size(Src->fvf));
     IWineD3DDevice_SetVertexDeclaration(D3D->wineD3DDevice,
                                         Src->wineD3DVertexDeclaration);
     hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice,
@@ -386,7 +384,8 @@ IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface,
                                         Count,
                                         This->wineD3DVertexBuffer,
                                         NULL /* Output vdecl */,
-                                        Flags);
+                                        Flags,
+                                        This->fvf);
 
     /* Restore the states if needed */
     if(doClip != oldClip)
@@ -435,7 +434,7 @@ IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface,
                                               D3DVERTEXBUFFERDESC *Desc)
 {
     IDirect3DVertexBufferImpl *This = (IDirect3DVertexBufferImpl *)iface;
-    WINED3DVERTEXBUFFER_DESC WDesc;
+    WINED3DBUFFER_DESC WDesc;
     HRESULT hr;
     TRACE("(%p)->(%p)\n", This, Desc);
 
@@ -445,15 +444,15 @@ IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface,
     hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &WDesc);
     if(hr != D3D_OK)
     {
-        ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr);
+        ERR("(%p) IWineD3DBuffer::GetDesc failed with hr=%08x\n", This, hr);
         LeaveCriticalSection(&ddraw_cs);
         return hr;
     }
 
     /* Now fill the Desc structure */
     Desc->dwCaps = This->Caps;
-    Desc->dwFVF = WDesc.FVF;
-    Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(WDesc.FVF);
+    Desc->dwFVF = This->fvf;
+    Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(This->fvf);
     LeaveCriticalSection(&ddraw_cs);
 
     return D3D_OK;
index bca567d..b5b5ad4 100644 (file)
@@ -40,10 +40,20 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 
 #define GLINFO_LOCATION      (*gl_info)
 
+/* We have to subtract any other PARAMs that we might use in our shader programs.
+ * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
+ * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
+#define ARB_SHADER_RESERVED_VS_CONSTS 3
+
+/* The arb shader only loads the bump mapping environment matrix into the shader if it finds
+ * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
+ */
+#define ARB_SHADER_RESERVED_PS_CONSTS 2
+
 /* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1,
  * so upload them above that
  */
-#define ARB_SHADER_PRIVCONST_BASE GL_LIMITS(vshader_constantsF)
+#define ARB_SHADER_PRIVCONST_BASE (GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS)
 #define ARB_SHADER_PRIVCONST_POS ARB_SHADER_PRIVCONST_BASE + 0
 
 /* ARB_program_shader private data */
@@ -163,6 +173,16 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con
     }
 }
 
+/**
+ * Loads the texture dimensions for NP2 fixup into the currently set ARB_[vertex/fragment]_programs.
+ */
+static void shader_arb_load_np2fixup_constants(
+    IWineD3DDevice* device,
+    char usePixelShader,
+    char useVertexShader) {
+    /* not implemented */
+}
+
 /**
  * Loads the app-supplied constants into the currently set ARB_[vertex/fragment]_programs.
  * 
@@ -258,7 +278,8 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
     DWORD i, cur;
     char pshader = shader_is_pshader_version(reg_maps->shader_version);
     unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
-            (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
+            (pshader ? GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS :
+                       GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS));
     UINT extra_constants_needed = 0;
     const local_constant *lconst;
 
@@ -300,13 +321,13 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
          * the stateblock into the shader. If no constant is available don't load, texbem will then just sample the texture without applying
          * bump mapping.
          */
-        if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
+        if(max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) {
             ps->bumpenvmatconst[cur].const_num = max_constantsF + extra_constants_needed;
             shader_addline(buffer, "PARAM bumpenvmat%d = program.env[%d];\n",
                            i, ps->bumpenvmatconst[cur].const_num);
             extra_constants_needed++;
 
-            if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF)) {
+            if(reg_maps->luminanceparams && max_constantsF + extra_constants_needed < GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS) {
                 ((IWineD3DPixelShaderImpl *)This)->luminanceconst[cur].const_num = max_constantsF + extra_constants_needed;
                 shader_addline(buffer, "PARAM luminance%d = program.env[%d];\n",
                                i, ps->luminanceconst[cur].const_num);
@@ -383,20 +404,23 @@ static const char * const shift_tab[] = {
 };
 
 static void shader_arb_get_write_mask(const struct wined3d_shader_instruction *ins,
-        const DWORD param, char *write_mask)
+        const struct wined3d_shader_dst_param *dst, char *write_mask)
 {
     char *ptr = write_mask;
     char vshader = shader_is_vshader_version(ins->reg_maps->shader_version);
 
-    if(vshader && shader_get_regtype(param) == WINED3DSPR_ADDR) {
+    if (vshader && dst->register_type == WINED3DSPR_ADDR)
+    {
         *ptr++ = '.';
         *ptr++ = 'x';
-    } else if ((param & WINED3DSP_WRITEMASK_ALL) != WINED3DSP_WRITEMASK_ALL) {
+    }
+    else if (dst->write_mask != WINED3DSP_WRITEMASK_ALL)
+    {
         *ptr++ = '.';
-        if (param & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
-        if (param & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
-        if (param & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
-        if (param & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
+        if (dst->write_mask & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
+        if (dst->write_mask & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
+        if (dst->write_mask & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
+        if (dst->write_mask & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
     }
 
     *ptr = '\0';
@@ -433,141 +457,131 @@ static void shader_arb_get_swizzle(const DWORD param, BOOL fixup, char *swizzle_
     *ptr = '\0';
 }
 
-static void pshader_get_register_name(IWineD3DBaseShader* iface,
-    const DWORD param, char* regstr) {
+static void shader_arb_get_register_name(IWineD3DBaseShader *iface, WINED3DSHADER_PARAM_REGISTER_TYPE register_type,
+        UINT register_idx, BOOL rel_addr, char *register_name, BOOL *is_color)
+{
+    /* oPos, oFog and oPts in D3D */
+    static const char * const rastout_reg_names[] = {"TMP_OUT", "result.fogcoord", "result.pointsize"};
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
+    DWORD shader_version = This->baseShader.reg_maps.shader_version;
+    BOOL pshader = shader_is_pshader_version(shader_version);
 
-    DWORD reg = param & WINED3DSP_REGNUM_MASK;
-    DWORD regtype = shader_get_regtype(param);
-    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
+    *is_color = FALSE;
 
-    switch (regtype) {
-    case WINED3DSPR_TEMP:
-        sprintf(regstr, "R%u", reg);
-    break;
-    case WINED3DSPR_INPUT:
-        if (reg==0) {
-            strcpy(regstr, "fragment.color.primary");
-        } else {
-            strcpy(regstr, "fragment.color.secondary");
-        }
-    break;
-    case WINED3DSPR_CONST:
-        if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) {
-            sprintf(regstr, "C[%u]", reg);
-        } else {
-            sprintf(regstr, "C%u", reg);
-        }
-    break;
-    case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
-        sprintf(regstr,"T%u", reg);
-    break;
-    case WINED3DSPR_COLOROUT:
-        if (reg == 0)
-            sprintf(regstr, "TMP_COLOR");
-        else {
-            /* TODO: See GL_ARB_draw_buffers */
-            FIXME("Unsupported write to render target %u\n", reg);
-            sprintf(regstr, "unsupported_register");
-        }
-    break;
-    case WINED3DSPR_DEPTHOUT:
-        sprintf(regstr, "result.depth");
-    break;
-    case WINED3DSPR_ATTROUT:
-        sprintf(regstr, "oD[%u]", reg);
-    break;
-    case WINED3DSPR_TEXCRDOUT:
-        sprintf(regstr, "oT[%u]", reg);
-    break;
-    default:
-        FIXME("Unhandled register name Type(%d)\n", regtype);
-        sprintf(regstr, "unrecognized_register");
-    break;
+    switch (register_type)
+    {
+        case WINED3DSPR_TEMP:
+            sprintf(register_name, "R%u", register_idx);
+            break;
+
+        case WINED3DSPR_INPUT:
+            if (pshader)
+            {
+                if (register_idx == 0) strcpy(register_name, "fragment.color.primary");
+                else strcpy(register_name, "fragment.color.secondary");
+            }
+            else
+            {
+                if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
+                sprintf(register_name, "vertex.attrib[%u]", register_idx);
+            }
+            break;
+
+        case WINED3DSPR_CONST:
+            if (!pshader && rel_addr)
+            {
+                UINT rel_offset = ((IWineD3DVertexShaderImpl *)This)->rel_offset;
+                if (register_idx >= rel_offset)
+                    sprintf(register_name, "C[A0.x + %u]", register_idx - rel_offset);
+                else
+                    sprintf(register_name, "C[A0.x - %u]", -register_idx + rel_offset);
+            }
+            else
+            {
+                if (This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF))
+                    sprintf(register_name, "C[%u]", register_idx);
+                else
+                    sprintf(register_name, "C%u", register_idx);
+            }
+            break;
+
+        case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
+            if (pshader) sprintf(register_name, "T%u", register_idx);
+            else  sprintf(register_name, "A%u", register_idx);
+            break;
+
+        case WINED3DSPR_COLOROUT:
+            if (register_idx == 0)
+            {
+                strcpy(register_name, "TMP_COLOR");
+            }
+            else
+            {
+                /* TODO: See GL_ARB_draw_buffers */
+                FIXME("Unsupported write to render target %u\n", register_idx);
+                sprintf(register_name, "unsupported_register");
+            }
+            break;
+
+        case WINED3DSPR_RASTOUT:
+            sprintf(register_name, "%s", rastout_reg_names[register_idx]);
+            break;
+
+        case WINED3DSPR_DEPTHOUT:
+            strcpy(register_name, "result.depth");
+            break;
+
+        case WINED3DSPR_ATTROUT:
+            if (pshader) sprintf(register_name, "oD[%u]", register_idx);
+            else if (register_idx == 0) strcpy(register_name, "result.color.primary");
+            else strcpy(register_name, "result.color.secondary");
+            break;
+
+        case WINED3DSPR_TEXCRDOUT:
+            if (pshader) sprintf(register_name, "oT[%u]", register_idx);
+            else sprintf(register_name, "result.texcoord[%u]", register_idx);
+            break;
+
+        default:
+            FIXME("Unhandled register type %#x[%u]\n", register_type, register_idx);
+            sprintf(register_name, "unrecognized_register[%u]", register_idx);
+            break;
     }
 }
 
-/* TODO: merge with pixel shader */
-static void vshader_program_add_param(const struct wined3d_shader_instruction *ins,
-        const DWORD param, BOOL is_input, char *hwLine)
+static void shader_arb_add_src_param(const struct wined3d_shader_instruction *ins,
+        DWORD param, char *str)
 {
-  IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)ins->shader;
+    char register_name[255];
+    char swizzle[6];
+    BOOL is_color;
 
-  /* oPos, oFog and oPts in D3D */
-  static const char * const hwrastout_reg_names[] = { "TMP_OUT", "result.fogcoord", "result.pointsize" };
+    if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) strcat(str, " -");
+    else strcat(str, " ");
 
-  DWORD reg = param & WINED3DSP_REGNUM_MASK;
-  DWORD regtype = shader_get_regtype(param);
-  char  tmpReg[255];
-  BOOL is_color = FALSE;
+    shader_arb_get_register_name(ins->shader, shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
+            param & WINED3DSHADER_ADDRMODE_RELATIVE, register_name, &is_color);
+    strcat(str, register_name);
 
-  if ((param & WINED3DSP_SRCMOD_MASK) == WINED3DSPSM_NEG) {
-      strcat(hwLine, " -");
-  } else {
-      strcat(hwLine, " ");
-  }
-
-  switch (regtype) {
-  case WINED3DSPR_TEMP:
-    sprintf(tmpReg, "R%u", reg);
-    strcat(hwLine, tmpReg);
-    break;
-  case WINED3DSPR_INPUT:
-
-    if (This->cur_args->swizzle_map & (1 << reg)) is_color = TRUE;
-
-    sprintf(tmpReg, "vertex.attrib[%u]", reg);
-    strcat(hwLine, tmpReg);
-    break;
-  case WINED3DSPR_CONST:
-      if(param & WINED3DSHADER_ADDRMODE_RELATIVE) {
-          if(reg >= This->rel_offset) {
-              sprintf(tmpReg, "C[A0.x + %u]", reg - This->rel_offset);
-          } else {
-              sprintf(tmpReg, "C[A0.x - %u]", -reg + This->rel_offset);
-          }
-      } else {
-          if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) {
-              sprintf(tmpReg, "C[%u]", reg);
-          } else {
-              sprintf(tmpReg, "C%u", reg);
-          }
-      }
-    strcat(hwLine, tmpReg);
-    break;
-  case WINED3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/
-    sprintf(tmpReg, "A%u", reg);
-    strcat(hwLine, tmpReg);
-    break;
-  case WINED3DSPR_RASTOUT:
-    sprintf(tmpReg, "%s", hwrastout_reg_names[reg]);
-    strcat(hwLine, tmpReg);
-    break;
-  case WINED3DSPR_ATTROUT:
-    if (reg==0) {
-       strcat(hwLine, "result.color.primary");
-    } else {
-       strcat(hwLine, "result.color.secondary");
-    }
-    break;
-  case WINED3DSPR_TEXCRDOUT:
-    sprintf(tmpReg, "result.texcoord[%u]", reg);
-    strcat(hwLine, tmpReg);
-    break;
-  default:
-    FIXME("Unknown reg type %d %d\n", regtype, reg);
-    strcat(hwLine, "unrecognized_register");
-    break;
-  }
+    shader_arb_get_swizzle(param, is_color, swizzle);
+    strcat(str, swizzle);
+}
 
-  if (!is_input) {
+static void shader_arb_add_dst_param(const struct wined3d_shader_instruction *ins,
+        const struct wined3d_shader_dst_param *wined3d_dst, char *str)
+{
+    char register_name[255];
     char write_mask[6];
-    shader_arb_get_write_mask(ins, param, write_mask);
-    strcat(hwLine, write_mask);
-  } else {
-    char swizzle[6];
-    shader_arb_get_swizzle(param, is_color, swizzle);
-    strcat(hwLine, swizzle);
-  }
+    BOOL is_color;
+
+    strcat(str, " ");
+
+    shader_arb_get_register_name(ins->shader, wined3d_dst->register_type,
+            wined3d_dst->register_idx, wined3d_dst->has_rel_addr, register_name, &is_color);
+    strcat(str, register_name);
+
+    shader_arb_get_write_mask(ins, wined3d_dst, write_mask);
+    strcat(str, write_mask);
 }
 
 static const char *shader_arb_get_fixup_swizzle(enum fixup_channel_source channel_source)
@@ -659,6 +673,12 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
             } else {
                 tex_type = "2D";
             }
+            if(shader_is_pshader_version(ins->reg_maps->shader_version)) {
+               const IWineD3DPixelShaderImpl* const ps = (const IWineD3DPixelShaderImpl*)This;
+               if(ps->cur_args->np2_fixup & (1 << sampler_idx)) {
+                   FIXME("NP2 texcoord fixup is currently not implemented in ARB mode (use GLSL instead).\n");
+               }
+            }
             break;
 
         case WINED3DSTT_VOLUME:
@@ -688,7 +708,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
     if (shader_is_pshader_version(ins->reg_maps->shader_version))
     {
         IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)ins->shader;
-        gen_color_correction(buffer, dst_str, ins->dst[0].token & WINED3DSP_WRITEMASK_ALL,
+        gen_color_correction(buffer, dst_str, ins->dst[0].write_mask,
                 "one", "coefmul.x", ps->cur_args->color_fixup[sampler_idx]);
     }
 }
@@ -701,6 +721,7 @@ static void pshader_gen_input_modifier_line (
     char *outregstr) {
 
     /* Generate a line that does the input modifier computation and return the input register to use */
+    BOOL is_color = FALSE;
     char regstr[256];
     char swzstr[20];
     int insert_line;
@@ -709,8 +730,9 @@ static void pshader_gen_input_modifier_line (
     insert_line = 1;
 
     /* Get register name */
-    pshader_get_register_name(iface, instr, regstr);
-    shader_arb_get_swizzle(instr, FALSE, swzstr);
+    shader_arb_get_register_name(iface, shader_get_regtype(instr), instr & WINED3DSP_REGNUM_MASK,
+            instr & WINED3DSHADER_ADDRMODE_RELATIVE, regstr, &is_color);
+    shader_arb_get_swizzle(instr, is_color, swzstr);
 
     switch (instr & WINED3DSP_SRCMOD_MASK) {
     case WINED3DSPSM_NONE:
@@ -771,12 +793,14 @@ static inline void pshader_gen_output_modifier_line(SHADER_BUFFER *buffer, int s
 static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_name[50];
     char src_name[2][50];
     char dst_wmask[20];
-    DWORD sampler_code = ins->dst[0].register_idx;
+    DWORD sampler_code = dst->register_idx;
     BOOL has_bumpmat = FALSE;
+    BOOL is_color;
     int i;
 
     for(i = 0; i < This->numbumpenvmatconsts; i++) {
@@ -788,8 +812,9 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
         }
     }
 
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
     strcat(dst_name, dst_wmask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
@@ -810,18 +835,21 @@ static void pshader_hw_bem(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
-    BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE;
-    DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    DWORD shift = dst->shift;
+    BOOL is_color;
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     /* Generate input register names (with modifiers) */
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
@@ -843,18 +871,21 @@ static void pshader_hw_cnd(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
-    DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE;
+    DWORD shift = dst->shift;
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    BOOL is_color;
 
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     /* Generate input register names (with modifiers) */
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
@@ -872,15 +903,18 @@ static void pshader_hw_cmp(const struct wined3d_shader_instruction *ins)
  * dst = dot2(src0, src1) + src2 */
 static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_wmask[20];
     char dst_name[50];
     char src_name[3][50];
-    DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE;
+    DWORD shift = dst->shift;
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    BOOL is_color;
 
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name[0]);
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[1], 1, src_name[1]);
@@ -900,7 +934,6 @@ static void pshader_hw_dp2add(const struct wined3d_shader_instruction *ins)
 static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
 {
     SHADER_BUFFER *buffer = ins->buffer;
-    DWORD dst = ins->dst[0].token;
     const DWORD *src = ins->src;
     const char *instruction;
     char arguments[256];
@@ -939,6 +972,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
     if (shader_is_pshader_version(ins->reg_maps->shader_version))
     {
         /* Output token related */
+        const struct wined3d_shader_dst_param *dst;
         char output_rname[256];
         char output_wmask[20];
         char operands[4][100];
@@ -946,6 +980,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         BOOL centroid = FALSE;
         BOOL partialprecision = FALSE;
         const char *modifier;
+        BOOL is_color;
         DWORD shift;
 
         if (!(ins->dst_count + ins->src_count))
@@ -953,11 +988,12 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
             ERR("Opcode \"%#x\" has no parameters\n", ins->handler_idx);
             return;
         }
+        dst = &ins->dst[0];
 
         /* Process modifiers */
-        if (dst & WINED3DSP_DSTMOD_MASK)
+        if (dst->modifiers)
         {
-            DWORD mask = dst & WINED3DSP_DSTMOD_MASK;
+            DWORD mask = dst->modifiers;
 
             saturate = mask & WINED3DSPDM_SATURATE;
             centroid = mask & WINED3DSPDM_MSAMPCENTROID;
@@ -969,7 +1005,7 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
             if (centroid)
                 FIXME("Unhandled modifier(%#x)\n", mask >> WINED3DSP_DSTMOD_SHIFT);
         }
-        shift = (dst & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
+        shift = dst->shift;
         modifier = (saturate && !shift) ? "_SAT" : "";
 
         /* Generate input register names (with modifiers) */
@@ -979,7 +1015,8 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         }
 
         /* Handle output register */
-        pshader_get_register_name(ins->shader, dst, output_rname);
+        shader_arb_get_register_name(ins->shader, dst->register_type,
+                dst->register_idx, dst->has_rel_addr, output_rname, &is_color);
         strcpy(operands[0], output_rname);
         shader_arb_get_write_mask(ins, dst, output_wmask);
         strcat(operands[0], output_wmask);
@@ -996,16 +1033,16 @@ static void shader_hw_map2gl(const struct wined3d_shader_instruction *ins)
         /* A shift requires another line. */
         if (shift) pshader_gen_output_modifier_line(buffer, saturate, output_wmask, shift, output_rname);
     } else {
-        /* Note that vshader_program_add_param() adds spaces. */
+        /* Note that shader_arb_add_*_param() adds spaces. */
 
         arguments[0] = '\0';
         if (ins->dst_count)
         {
-            vshader_program_add_param(ins, dst, FALSE, arguments);
+            shader_arb_add_dst_param(ins, &ins->dst[0], arguments);
             for (i = 0; i < ins->src_count; ++i)
             {
                 strcat(arguments, ",");
-                vshader_program_add_param(ins, src[i], TRUE, arguments);
+                shader_arb_add_src_param(ins, src[i], arguments);
             }
         }
         shader_addline(buffer, "%s%s;\n", instruction, arguments);
@@ -1018,7 +1055,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 
     if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
             && !shader_is_pshader_version(ins->reg_maps->shader_version)
-            && shader_get_regtype(ins->dst[0].token) == WINED3DSPR_ADDR)
+            && ins->dst[0].register_type == WINED3DSPR_ADDR)
             || ins->handler_idx == WINED3DSIH_MOVA)
     {
         SHADER_BUFFER *buffer = ins->buffer;
@@ -1030,7 +1067,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
-            vshader_program_add_param(ins, ins->src[0], TRUE, src0_param);
+            shader_arb_add_src_param(ins, ins->src[0], src0_param);
             shader_addline(buffer, "ADD TMP.x, %s, helper_const.z;\n", src0_param);
             shader_addline(buffer, "ARL A0.x, TMP.x;\n");
         }
@@ -1049,7 +1086,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
                 parm |= WINED3DVS_X_Y | WINED3DVS_Y_Y | WINED3DVS_Z_Y | WINED3DVS_W_Y;
             else if((ins->src[0] & WINED3DVS_X_X) == WINED3DVS_X_X)
                 parm |= WINED3DVS_X_X | WINED3DVS_Y_X | WINED3DVS_Z_X | WINED3DVS_W_X;
-            vshader_program_add_param(ins, parm, TRUE, src0_param);
+            shader_arb_add_src_param(ins, parm, src0_param);
             shader_addline(buffer, "ARL A0.x, %s;\n", src0_param);
         }
     }
@@ -1061,14 +1098,17 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     DWORD shader_version = ins->reg_maps->shader_version;
     SHADER_BUFFER *buffer = ins->buffer;
     char reg_dest[40];
+    BOOL is_color;
 
     /* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
      * but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit)
      */
-    pshader_get_register_name(ins->shader, ins->dst[0].token, reg_dest);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
 
     if (shader_version >= WINED3DPS_VERSION(2,0))
     {
@@ -1088,8 +1128,9 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
+    BOOL is_color;
 
-    DWORD dst = ins->dst[0].token;
     const DWORD *src = ins->src;
     SHADER_BUFFER* buffer = ins->buffer;
     DWORD shader_version = ins->reg_maps->shader_version;
@@ -1097,12 +1138,11 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 
     char reg_dest[40];
     char reg_coord[40];
-    DWORD reg_dest_code;
     DWORD reg_sampler_code;
 
     /* All versions have a destination register */
-    reg_dest_code = ins->dst[0].register_idx;
-    pshader_get_register_name(ins->shader, dst, reg_dest);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, reg_dest, &is_color);
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
@@ -1114,7 +1154,7 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
   /* 1.0-1.4: Use destination register number as texture code.
      2.0+: Use provided sampler number as texure code. */
   if (shader_version < WINED3DPS_VERSION(2,0))
-     reg_sampler_code = reg_dest_code;
+     reg_sampler_code = dst->register_idx;
   else
      reg_sampler_code = src[1] & WINED3DSP_REGNUM_MASK;
 
@@ -1150,21 +1190,20 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins)
 {
-    DWORD dst = ins->dst[0].token;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
 
     char tmp[20];
     shader_arb_get_write_mask(ins, dst, tmp);
     if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
     {
-        DWORD reg = ins->dst[0].register_idx;
+        DWORD reg = dst->register_idx;
         shader_addline(buffer, "MOV_SAT T%u%s, fragment.texcoord[%u];\n", reg, tmp, reg);
     } else {
-        DWORD reg1 = ins->dst[0].register_idx;
         char reg_src[40];
 
         pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, reg_src);
-        shader_addline(buffer, "MOV R%u%s, %s;\n", reg1, tmp, reg_src);
+        shader_addline(buffer, "MOV R%u%s, %s;\n", dst->register_idx, tmp, reg_src);
    }
 }
 
@@ -1217,11 +1256,12 @@ static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
 static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->shader;
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     BOOL has_bumpmat = FALSE;
     BOOL has_luminance = FALSE;
+    BOOL is_color;
     int i;
 
-    DWORD dst = ins->dst[0].token;
     DWORD src = ins->src[0] & WINED3DSP_REGNUM_MASK;
     SHADER_BUFFER* buffer = ins->buffer;
 
@@ -1229,9 +1269,10 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins)
     DWORD reg_dest_code;
 
     /* All versions have a destination register */
-    reg_dest_code = ins->dst[0].register_idx;
+    reg_dest_code = dst->register_idx;
     /* Can directly use the name because texbem is only valid for <= 1.3 shaders */
-    pshader_get_register_name(ins->shader, dst, reg_coord);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, reg_coord, &is_color);
 
     for(i = 0; i < This->numbumpenvmatconsts; i++) {
         if (This->bumpenvmatconst[i].const_num != WINED3D_CONST_NUM_UNUSED
@@ -1427,15 +1468,18 @@ static void pshader_hw_texm3x3spec(const struct wined3d_shader_instruction *ins)
 
 static void pshader_hw_texdepth(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_name[50];
+    BOOL is_color;
 
     /* texdepth has an implicit destination, the fragment depth value. It's only parameter,
      * which is essentially an input, is the destination register because it is the first
      * parameter. According to the msdn, this must be register r5, but let's keep it more flexible
      * here
      */
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
 
     /* According to the msdn, the source register(must be r5) is unusable after
      * the texdepth instruction, so we're free to modify it
@@ -1474,18 +1518,20 @@ static void pshader_hw_texdp3tex(const struct wined3d_shader_instruction *ins)
  * Take a 3-component dot product of the TexCoord[dstreg] and src. */
 static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     char src0[50];
     char dst_str[50];
     char dst_mask[6];
-    DWORD dstreg = ins->dst[0].register_idx;
     SHADER_BUFFER *buffer = ins->buffer;
+    BOOL is_color;
 
     /* Handle output register */
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_str);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_mask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_mask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dstreg, src0);
+    shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dst->register_idx, src0);
 
     /* TODO: Handle output modifiers */
 }
@@ -1494,17 +1540,19 @@ static void pshader_hw_texdp3(const struct wined3d_shader_instruction *ins)
  * Perform the 3rd row of a 3x3 matrix multiply */
 static void pshader_hw_texm3x3(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_str[50];
     char dst_mask[6];
     char src0[50];
-    DWORD dst_reg = ins->dst[0].register_idx;
+    BOOL is_color;
 
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_str);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_mask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_str, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_mask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src0);
-    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst_reg, src0);
+    shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst->register_idx, src0);
     shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask);
 
     /* TODO: Handle output modifiers */
@@ -1583,9 +1631,9 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
             break;
     }
 
+    tmp_dst = ins->dst[0];
     for (i = 0; i < nComponents; i++) {
-        tmp_dst.register_idx = ins->dst[0].register_idx;
-        tmp_dst.token = ((ins->dst[0].token) & ~WINED3DSP_WRITEMASK_ALL) | (WINED3DSP_WRITEMASK_0 << i);
+        tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
         tmp_ins.src[1] = ins->src[1]+i;
         shader_hw_map2gl(&tmp_ins);
     }
@@ -1594,7 +1642,6 @@ static void shader_hw_mnxn(const struct wined3d_shader_instruction *ins)
 static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
 {
     SHADER_BUFFER *buffer = ins->buffer;
-    DWORD dst = ins->dst[0].token;
     DWORD src = ins->src[0];
     DWORD swizzle = (src & WINED3DSP_SWIZZLE_MASK) >> WINED3DSP_SWIZZLE_SHIFT;
     const char *instruction;
@@ -1611,9 +1658,9 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
     }
 
     strcpy(tmpLine, instruction);
-    vshader_program_add_param(ins, dst, FALSE, tmpLine); /* Destination */
+    shader_arb_add_dst_param(ins, &ins->dst[0], tmpLine); /* Destination */
     strcat(tmpLine, ",");
-    vshader_program_add_param(ins, src, TRUE, tmpLine);
+    shader_arb_add_src_param(ins, src, tmpLine);
     if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) == swizzle) {
         /* Dx sdk says .x is used if no swizzle is given, but our test shows that
          * .w is used
@@ -1626,15 +1673,18 @@ static void vshader_hw_rsq_rcp(const struct wined3d_shader_instruction *ins)
 
 static void shader_hw_nrm(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
-    DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE;
+    DWORD shift = dst->shift;
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    BOOL is_color;
 
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name);
     shader_addline(buffer, "DP3 TMP, %s, %s;\n", src_name, src_name);
@@ -1653,15 +1703,18 @@ static void shader_hw_sincos(const struct wined3d_shader_instruction *ins)
      * must contain fixed constants. So we need a separate function to filter those constants and
      * can't use map2gl
      */
+    const struct wined3d_shader_dst_param *dst = &ins->dst[0];
     SHADER_BUFFER *buffer = ins->buffer;
     char dst_name[50];
     char src_name[50];
     char dst_wmask[20];
-    DWORD shift = (ins->dst[0].token & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-    BOOL sat = (ins->dst[0].token & WINED3DSP_DSTMOD_MASK) & WINED3DSPDM_SATURATE;
+    DWORD shift = dst->shift;
+    BOOL sat = dst->modifiers & WINED3DSPDM_SATURATE;
+    BOOL is_color;
 
-    pshader_get_register_name(ins->shader, ins->dst[0].token, dst_name);
-    shader_arb_get_write_mask(ins, ins->dst[0].token, dst_wmask);
+    shader_arb_get_register_name(ins->shader, dst->register_type,
+            dst->register_idx, dst->has_rel_addr, dst_name, &is_color);
+    shader_arb_get_write_mask(ins, dst, dst_wmask);
 
     pshader_gen_input_modifier_line(ins->shader, buffer, ins->src[0], 0, src_name);
     shader_addline(buffer, "SCS%s %s%s, %s;\n", sat ? "_SAT" : "", dst_name, dst_wmask,
@@ -2145,13 +2198,14 @@ static void shader_arb_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *g
     if(GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(1,1);
         TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
-        pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
+        pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - ARB_SHADER_RESERVED_VS_CONSTS;
     }
 
     if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
         pCaps->PixelShaderVersion    = WINED3DPS_VERSION(1,4);
         pCaps->PixelShader1xMaxValue = 8.0;
         TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
+        pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - ARB_SHADER_RESERVED_PS_CONSTS;
     }
 }
 
@@ -2269,6 +2323,7 @@ const shader_backend_t arb_program_shader_backend = {
     shader_arb_update_float_vertex_constants,
     shader_arb_update_float_pixel_constants,
     shader_arb_load_constants,
+    shader_arb_load_np2fixup_constants,
     shader_arb_destroy,
     shader_arb_alloc,
     shader_arb_free,
index 39120d4..08415c2 100644 (file)
@@ -212,11 +212,24 @@ static void shader_delete_constant_list(struct list* clist) {
     list_init(clist);
 }
 
+static void shader_parse_dst_param(DWORD param, DWORD addr_param, struct wined3d_shader_dst_param *dst)
+{
+    dst->register_type = ((param & WINED3DSP_REGTYPE_MASK) >> WINED3DSP_REGTYPE_SHIFT)
+            | ((param & WINED3DSP_REGTYPE_MASK2) >> WINED3DSP_REGTYPE_SHIFT2);
+    dst->register_idx = param & WINED3DSP_REGNUM_MASK;
+    dst->write_mask = param & WINED3DSP_WRITEMASK_ALL;
+    dst->modifiers = param & WINED3DSP_DSTMOD_MASK;
+    dst->shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
+    dst->has_rel_addr = param & WINED3DSHADER_ADDRMODE_RELATIVE;
+    dst->addr_token = addr_param;
+}
+
 /* Note that this does not count the loop register
  * as an address register. */
 
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
-        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code)
+        struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
+        const DWORD *byte_code)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
@@ -285,14 +298,19 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_m
                 else
                     reg_maps->packed_input[regnum] = 1;
 
-                semantics_in[regnum].usage = usage;
-                semantics_in[regnum].reg = param;
+                semantics_in[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
+                semantics_in[regnum].usage_idx =
+                        (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+                shader_parse_dst_param(param, 0, &semantics_in[regnum].reg);
 
             /* Vshader: mark 3.0 output registers used, save token */
             } else if (WINED3DSPR_OUTPUT == regtype) {
                 reg_maps->packed_output[regnum] = 1;
-                semantics_out[regnum].usage = usage;
-                semantics_out[regnum].reg = param;
+                semantics_out[regnum].usage = (usage & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
+                semantics_out[regnum].usage_idx =
+                        (usage & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+                shader_parse_dst_param(param, 0, &semantics_out[regnum].reg);
+
                 if (usage & (WINED3DDECLUSAGE_FOG << WINED3DSP_DCL_USAGE_SHIFT))
                     reg_maps->fog = 1;
 
@@ -848,9 +866,9 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer,
         ins.dst_count = curOpcode->dst_token ? 1 : 0;
         if (ins.dst_count)
         {
-            dst_param.addr_token = 0;
-            pToken += shader_get_param(pToken, shader_version, &dst_param.token, &dst_param.addr_token);
-            dst_param.register_idx = dst_param.token & WINED3DSP_REGNUM_MASK;
+            DWORD param, addr_param = 0;
+            pToken += shader_get_param(pToken, shader_version, &param, &addr_param);
+            shader_parse_dst_param(param, addr_param, &dst_param);
         }
 
         /* Predication token */
@@ -1075,6 +1093,7 @@ static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_update_float_vertex_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_update_float_pixel_constants(IWineD3DDevice *iface, UINT start, UINT count) {}
 static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
+static void shader_none_load_np2fixup_constants(IWineD3DDevice *iface, char usePS, char useVS) {}
 static void shader_none_destroy(IWineD3DBaseShader *iface) {}
 static HRESULT shader_none_alloc(IWineD3DDevice *iface) {return WINED3D_OK;}
 static void shader_none_free(IWineD3DDevice *iface) {}
@@ -1124,6 +1143,7 @@ const shader_backend_t none_shader_backend = {
     shader_none_update_float_vertex_constants,
     shader_none_update_float_pixel_constants,
     shader_none_load_constants,
+    shader_none_load_np2fixup_constants,
     shader_none_destroy,
     shader_none_alloc,
     shader_none_free,
index 9e2abeb..b68dcf7 100644 (file)
@@ -54,11 +54,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
     while (glGetError() != GL_NO_ERROR);
 
     /* Basically the FVF parameter passed to CreateVertexBuffer is no good
-    * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with
-    * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer
-    * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified
-    * to check if the rhw and color values are in the correct format.
-    */
+     * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with
+     * IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer
+     * look like. This means that on each DrawPrimitive call the vertex buffer has to be verified
+     * to check if the rhw and color values are in the correct format.
+     */
 
     GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
     error = glGetError();
@@ -68,7 +68,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
         goto fail;
     }
 
-    GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+    if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+    {
+        IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
+    }
+    GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
     error = glGetError();
     if (error != GL_NO_ERROR)
     {
@@ -96,10 +100,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
     }
 
     /* Reserve memory for the buffer. The amount of data won't change
-    * so we are safe with calling glBufferData once with a NULL ptr and
-    * calling glBufferSubData on updates
-    */
-    GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, This->resource.size, NULL, gl_usage));
+     * so we are safe with calling glBufferData once and
+     * calling glBufferSubData on updates. Upload the actual data in case
+     * we're not double buffering, so we can release the heap mem afterwards
+     */
+    GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, This->resource.allocatedMemory, gl_usage));
     error = glGetError();
     if (error != GL_NO_ERROR)
     {
@@ -113,7 +118,18 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
     This->buffer_object_usage = gl_usage;
     This->dirty_start = 0;
     This->dirty_end = This->resource.size;
-    This->flags |= WINED3D_BUFFER_DIRTY;
+
+    if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)
+    {
+        This->flags |= WINED3D_BUFFER_DIRTY;
+    }
+    else
+    {
+        HeapFree(GetProcessHeap(), 0, This->resource.heapMemory);
+        This->resource.allocatedMemory = NULL;
+        This->resource.heapMemory = NULL;
+        This->flags &= ~WINED3D_BUFFER_DIRTY;
+    }
 
     return;
 
@@ -298,9 +314,14 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
     unsigned int i;
 
     /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
-     * Once we have our declaration there is no need to look it up again.
+     * Once we have our declaration there is no need to look it up again. Index buffers also never need
+     * conversion, so once the (empty) conversion structure is created don't bother checking again
      */
-    if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->flags & WINED3D_BUFFER_HASDESC) return FALSE;
+    if (This->flags & WINED3D_BUFFER_HASDESC)
+    {
+        if(((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 ||
+             This->resource.format_desc->format != WINED3DFMT_VERTEXDATA) return FALSE;
+    }
 
     TRACE("Finding vertex buffer conversion information\n");
     /* Certain declaration types need some fixups before we can pass them to
@@ -308,11 +329,15 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
      * processing, FLOAT4 POSITIONT with fixed function, and FLOAT16 if
      * GL_NV_half_float is not supported.
      *
+     * Note for d3d8 and d3d9:
      * The vertex buffer FVF doesn't help with finding them, we have to use
      * the decoded vertex declaration and pick the things that concern the
      * current buffer. A problem with this is that this can change between
      * draws, so we have to validate the information and reprocess the buffer
      * if it changes, and avoid false positives for performance reasons.
+     * WineD3D doesn't even know the vertex buffer any more, it is managed
+     * by the client libraries and passed to SetStreamSource and ProcessVertices
+     * as needed.
      *
      * We have to distinguish between vertex shaders and fixed function to
      * pick the way we access the strided vertex information.
@@ -439,10 +464,22 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
     if (This->buffer_object_size != size)
     {
         TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size);
+
+        if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+        {
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
+        }
+
+        /* Rescue the data before resizing the buffer object if we do not have our backup copy */
+        if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+        {
+            buffer_get_sysmem(This);
+        }
+
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+        GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->buffer_object_usage));
+        GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, size, NULL, This->buffer_object_usage));
         This->buffer_object_size = size;
         checkGLcall("glBufferDataARB");
         LEAVE_GL();
@@ -551,21 +588,40 @@ static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface)
     return refcount;
 }
 
+const BYTE *buffer_get_sysmem(struct wined3d_buffer *This)
+{
+    if(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) return This->resource.allocatedMemory;
+
+    This->resource.heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->resource.size + RESOURCE_ALIGNMENT);
+    This->resource.allocatedMemory = (BYTE *)(((ULONG_PTR)This->resource.heapMemory + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
+    ENTER_GL();
+    GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+    GL_EXTCALL(glGetBufferSubDataARB(This->buffer_type_hint, 0, This->resource.size, This->resource.allocatedMemory));
+    LEAVE_GL();
+    This->flags |= WINED3D_BUFFER_DOUBLEBUFFER;
+
+    return This->resource.allocatedMemory;
+}
+
 static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 
     TRACE("iface %p\n", iface);
 
-    /* This is easy: The whole content is shadowed in This->resource.allocatedMemory,
-     * so we only have to destroy the vbo. Only do it if we have a vbo, which implies
-     * that vbos are supported
-     */
     if (This->buffer_object)
     {
         IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
         ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+
+        /* Download the buffer, but don't permanently enable double buffering */
+        if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+        {
+            buffer_get_sysmem(This);
+            This->flags &= ~WINED3D_BUFFER_DOUBLEBUFFER;
+        }
+
         ENTER_GL();
         GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
         checkGLcall("glDeleteBuffersARB");
@@ -734,6 +790,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
     This->dirty_start = 0;
     This->dirty_end = 0;
 
+    if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+    {
+        IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
+    }
+
     if (!This->conversion_map)
     {
         /* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory
@@ -742,19 +803,27 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
          */
         TRACE("No conversion needed\n");
 
+        /* Nothing to do because we locked directly into the vbo */
+        if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) return;
+
         if (!device->isInDraw)
         {
             ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         }
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+        GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start));
+        GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end-start, This->resource.allocatedMemory + start));
         checkGLcall("glBufferSubDataARB");
         LEAVE_GL();
         return;
     }
 
+    if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
+    {
+        buffer_get_sysmem(This);
+    }
+
     /* Now for each vertex in the buffer that needs conversion */
     vertices = This->resource.size / This->stride;
 
@@ -793,9 +862,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+        GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conversion_stride, data));
+        GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, 0, vertices * This->conversion_stride, data));
         checkGLcall("glBufferSubDataARB");
         LEAVE_GL();
     }
@@ -832,9 +901,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+        GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data + start));
+        GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end - start, data + start));
         checkGLcall("glBufferSubDataARB");
         LEAVE_GL();
     }
@@ -852,10 +921,11 @@ static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *ifac
 static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+    LONG count;
 
     TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags);
 
-    InterlockedIncrement(&This->lock_count);
+    count = InterlockedIncrement(&This->lock_count);
 
     if (This->flags & WINED3D_BUFFER_DIRTY)
     {
@@ -877,7 +947,22 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
         else This->dirty_end = This->resource.size;
     }
 
-    This->flags |= WINED3D_BUFFER_DIRTY;
+    if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
+    {
+        if(count == 1)
+        {
+            if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+            {
+                IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
+            }
+            GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+            This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
+        }
+    }
+    else
+    {
+        This->flags |= WINED3D_BUFFER_DIRTY;
+    }
 
     *data = This->resource.allocatedMemory + offset;
 
@@ -900,7 +985,17 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
         return WINED3D_OK;
     }
 
-    if (This->flags & WINED3D_BUFFER_HASDESC)
+    if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
+    {
+        if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
+        {
+            IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
+        }
+        GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
+        GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
+        This->resource.allocatedMemory = NULL;
+    }
+    else if (This->flags & WINED3D_BUFFER_HASDESC)
     {
         buffer_PreLoad(iface);
     }
@@ -908,18 +1003,16 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
     return WINED3D_OK;
 }
 
-static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DVERTEXBUFFER_DESC *desc)
+static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DBUFFER_DESC *desc)
 {
     struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 
     TRACE("(%p)\n", This);
 
-    desc->Format = This->resource.format_desc->format;
     desc->Type = This->resource.resourceType;
     desc->Usage = This->resource.usage;
     desc->Pool = This->resource.pool;
     desc->Size = This->resource.size;
-    desc->FVF = This->fvf;
 
     return WINED3D_OK;
 }
@@ -947,253 +1040,3 @@ const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
     buffer_Unmap,
     buffer_GetDesc,
 };
-
-/* IUnknown methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface,
-        REFIID riid, void **object)
-{
-    TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
-
-    if (IsEqualGUID(riid, &IID_IWineD3DIndexBuffer)
-            || IsEqualGUID(riid, &IID_IWineD3DResource)
-            || IsEqualGUID(riid, &IID_IWineD3DBase)
-            || IsEqualGUID(riid, &IID_IUnknown))
-    {
-        IUnknown_AddRef(iface);
-        *object = iface;
-        return S_OK;
-    }
-
-    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
-
-    *object = NULL;
-
-    return E_NOINTERFACE;
-}
-
-static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_AddRef(IWineD3DIndexBuffer *iface)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
-    ULONG refcount = InterlockedIncrement(&This->resource.ref);
-
-    TRACE("%p increasing refcount to %u\n", This, refcount);
-
-    return refcount;
-}
-
-static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
-    ULONG refcount = InterlockedDecrement(&This->resource.ref);
-
-    TRACE("%p decreasing refcount to %u\n", This, refcount);
-
-    if (!refcount)
-    {
-        if (This->vbo)
-        {
-            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-            ENTER_GL();
-            /* No need to manually unset the buffer. glDeleteBuffers unsets it for the current context,
-             * but not for other contexts. However, because the d3d buffer is destroyed the app has to
-             * unset it before doing the next draw, thus dirtifying the index buffer state and forcing
-             * binding a new buffer
-             */
-            GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
-            checkGLcall("glDeleteBuffersARB");
-            LEAVE_GL();
-        }
-
-        resource_cleanup((IWineD3DResource *)iface);
-        HeapFree(GetProcessHeap(), 0, This);
-    }
-
-    return refcount;
-}
-
-/* IWineD3DBase methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetParent(IWineD3DIndexBuffer *iface, IUnknown **parent)
-{
-    return resource_get_parent((IWineD3DResource *)iface, parent);
-}
-
-/* IWineD3DResource methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDevice(IWineD3DIndexBuffer *iface, IWineD3DDevice **device)
-{
-    return resource_get_device((IWineD3DResource *)iface, device);
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPrivateData(IWineD3DIndexBuffer *iface,
-        REFGUID guid, const void *data, DWORD data_size, DWORD flags)
-{
-    return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags);
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPrivateData(IWineD3DIndexBuffer *iface,
-        REFGUID guid, void *data, DWORD *data_size)
-{
-    return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size);
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_FreePrivateData(IWineD3DIndexBuffer *iface, REFGUID guid)
-{
-    return resource_free_private_data((IWineD3DResource *)iface, guid);
-}
-
-static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPriority(IWineD3DIndexBuffer *iface, DWORD priority)
-{
-    return resource_set_priority((IWineD3DResource *)iface, priority);
-}
-
-static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *iface)
-{
-    return resource_get_priority((IWineD3DResource *)iface);
-}
-
-static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface)
-{
-    TRACE("iface %p\n", iface);
-}
-
-static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *) iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-
-    TRACE("(%p)\n", This);
-
-    /* This is easy: The whole content is shadowed in This->resource.allocatedMemory,
-     * so we only have to destroy the vbo. Only do it if we have a vbo, which implies
-     * that vbos are supported.
-     * (TODO: Make a IWineD3DBuffer base class for index and vertex buffers and share
-     * this code. Also needed for D3D10)
-     */
-    if (This->vbo)
-    {
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        ENTER_GL();
-        GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
-        checkGLcall("glDeleteBuffersARB");
-        LEAVE_GL();
-        This->vbo = 0;
-    }
-}
-
-static WINED3DRESOURCETYPE STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetType(IWineD3DIndexBuffer *iface)
-{
-    return resource_get_type((IWineD3DResource *)iface);
-}
-
-/* IWineD3DIndexBuffer methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Lock(IWineD3DIndexBuffer *iface,
-        UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
-
-    TRACE("(%p) : offset %d, size %d, Flags=%x\n", This, OffsetToLock, SizeToLock, Flags);
-
-    InterlockedIncrement(&This->lockcount);
-    *ppbData = This->resource.allocatedMemory + OffsetToLock;
-
-    if (Flags & (WINED3DLOCK_READONLY | WINED3DLOCK_NO_DIRTY_UPDATE) || !This->vbo)
-    {
-        return WINED3D_OK;
-    }
-
-    if (This->dirtystart != This->dirtyend)
-    {
-        if (This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
-        if (SizeToLock)
-        {
-            if (This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
-        }
-        else
-        {
-            This->dirtyend = This->resource.size;
-        }
-    }
-    else
-    {
-        This->dirtystart = OffsetToLock;
-        if (SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
-        else This->dirtyend = This->resource.size;
-    }
-
-    return WINED3D_OK;
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Unlock(IWineD3DIndexBuffer *iface)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
-    ULONG locks = InterlockedDecrement(&This->lockcount);
-
-    TRACE("(%p)\n", This);
-
-    /* For now load in unlock */
-    if (!locks && This->vbo && (This->dirtyend - This->dirtystart) > 0)
-    {
-        IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-
-        ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->vbo));
-        checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->dirtystart,
-                This->dirtyend - This->dirtystart, This->resource.allocatedMemory + This->dirtystart));
-        checkGLcall("glBufferSubDataARB");
-        LEAVE_GL();
-        This->dirtystart = 0;
-        This->dirtyend = 0;
-        /* TODO: Move loading into preload when the buffer is used, that avoids dirtifying the state */
-        IWineD3DDeviceImpl_MarkStateDirty(device, STATE_INDEXBUFFER);
-    }
-
-    return WINED3D_OK;
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDesc(IWineD3DIndexBuffer *iface,
-        WINED3DINDEXBUFFER_DESC *pDesc)
-{
-    IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
-
-    TRACE("(%p)\n", This);
-
-    pDesc->Format = This->resource.format_desc->format;
-    pDesc->Type   = This->resource.resourceType;
-    pDesc->Usage  = This->resource.usage;
-    pDesc->Pool   = This->resource.pool;
-    pDesc->Size   = This->resource.size;
-
-    return WINED3D_OK;
-}
-
-const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl =
-{
-    /* IUnknown methods */
-    IWineD3DIndexBufferImpl_QueryInterface,
-    IWineD3DIndexBufferImpl_AddRef,
-    IWineD3DIndexBufferImpl_Release,
-    /* IWineD3DBase methods */
-    IWineD3DIndexBufferImpl_GetParent,
-    /* IWineD3DResource methods */
-    IWineD3DIndexBufferImpl_GetDevice,
-    IWineD3DIndexBufferImpl_SetPrivateData,
-    IWineD3DIndexBufferImpl_GetPrivateData,
-    IWineD3DIndexBufferImpl_FreePrivateData,
-    IWineD3DIndexBufferImpl_SetPriority,
-    IWineD3DIndexBufferImpl_GetPriority,
-    IWineD3DIndexBufferImpl_PreLoad,
-    IWineD3DIndexBufferImpl_UnLoad,
-    IWineD3DIndexBufferImpl_GetType,
-    /* IWineD3DIndexBuffer methods */
-    IWineD3DIndexBufferImpl_Lock,
-    IWineD3DIndexBufferImpl_Unlock,
-    IWineD3DIndexBufferImpl_GetDesc,
-};
index ecc00d6..1099872 100644 (file)
@@ -352,6 +352,8 @@ void device_stream_info_from_strided(IWineD3DDeviceImpl *This,
 
     for (i = 0; i < sizeof(stream_info->elements) / sizeof(*stream_info->elements); ++i)
     {
+        if (!stream_info->elements[i].format_desc) continue;
+
         if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && stream_info->elements[i].format_desc->format == WINED3DFMT_A8R8G8B8)
         {
             stream_info->swizzle_map |= 1 << i;
@@ -463,6 +465,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
         HeapFree(GetProcessHeap(), 0, object);
         return hr;
     }
+    object->buffer_type_hint = GL_ARRAY_BUFFER_ARB;
 
     TRACE("Created resource %p\n", object);
 
@@ -532,7 +535,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     }
 
     object->vtbl = &wined3d_buffer_vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_VERTEXBUFFER, This, Size, Usage, format_desc, Pool, parent);
+    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Size, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -540,6 +543,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
         *ppVertexBuffer = NULL;
         return hr;
     }
+    object->buffer_type_hint = GL_ARRAY_BUFFER_ARB;
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
@@ -548,8 +552,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     TRACE("(%p) : Size=%d, Usage=0x%08x, FVF=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Size, Usage, FVF, Pool, object->resource.allocatedMemory, object);
     *ppVertexBuffer = (IWineD3DBuffer *)object;
 
-    object->fvf = FVF;
-
     /* Observations show that drawStridedSlow is faster on dynamic VBs than converting +
      * drawStridedFast (half-life 2).
      *
@@ -580,62 +582,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
     return WINED3D_OK;
 }
 
-static void CreateIndexBufferVBO(IWineD3DDeviceImpl *This, IWineD3DIndexBufferImpl *object) {
-    GLenum error, glUsage;
-    TRACE("Creating VBO for Index Buffer %p\n", object);
-
-    /* The following code will modify the ELEMENT_ARRAY_BUFFER binding, make sure it is
-     * restored on the next draw
-     */
-    IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
-
-    /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
-    ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-    ENTER_GL();
-
-    while(glGetError());
-
-    GL_EXTCALL(glGenBuffersARB(1, &object->vbo));
-    error = glGetError();
-    if(error != GL_NO_ERROR || object->vbo == 0) {
-        ERR("Creating a vbo failed with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error);
-        goto out;
-    }
-
-    GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->vbo));
-    error = glGetError();
-    if(error != GL_NO_ERROR) {
-        ERR("Failed to bind index buffer with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error);
-        goto out;
-    }
-
-    /* Use static write only usage for now. Dynamic index buffers stay in sysmem, and due to the sysmem
-        * copy no readback will be needed
-        */
-    glUsage = GL_STATIC_DRAW_ARB;
-    GL_EXTCALL(glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->resource.size, NULL, glUsage));
-    error = glGetError();
-    if(error != GL_NO_ERROR) {
-        ERR("Failed to initialize the index buffer with error %s (%#x)\n", debug_glerror(error), error);
-        goto out;
-    }
-    LEAVE_GL();
-    TRACE("Successfully created vbo %d for index buffer %p\n", object->vbo, object);
-    return;
-
-out:
-    GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
-    GL_EXTCALL(glDeleteBuffersARB(1, &object->vbo));
-    LEAVE_GL();
-    object->vbo = 0;
-}
-
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage, 
-                                                    WINED3DFORMAT Format, WINED3DPOOL Pool, IWineD3DIndexBuffer** ppIndexBuffer,
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage,
+                                                    WINED3DPOOL Pool, IWineD3DBuffer** ppIndexBuffer,
                                                     HANDLE *sharedHandle, IUnknown *parent) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
-    IWineD3DIndexBufferImpl *object;
+    const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, &This->adapter->gl_info);
+    struct wined3d_buffer *object;
     HRESULT hr;
 
     TRACE("(%p) Creating index buffer\n", This);
@@ -649,8 +601,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
-    object->lpVtbl = &IWineD3DIndexBuffer_Vtbl;
-    hr = resource_init(&object->resource, WINED3DRTYPE_INDEXBUFFER, This, Length, Usage, format_desc, Pool, parent);
+    object->vtbl = &wined3d_buffer_vtbl;
+    hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -658,18 +610,19 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
         *ppIndexBuffer = NULL;
         return hr;
     }
+    object->buffer_type_hint = GL_ELEMENT_ARRAY_BUFFER_ARB;
 
     TRACE("(%p) : Created resource %p\n", This, object);
 
     IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
 
     if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
-        CreateIndexBufferVBO(This, object);
+        object->flags |= WINED3D_BUFFER_CREATEBO;
     }
 
-    TRACE("(%p) : Len=%d, Use=%x, Format=(%u,%s), Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage, Format, 
-                           debug_d3dformat(Format), Pool, object, object->resource.allocatedMemory);
-    *ppIndexBuffer = (IWineD3DIndexBuffer *) object;
+    TRACE("(%p) : Len=%d, Use=%x, Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage,
+            Pool, object, object->resource.allocatedMemory);
+    *ppIndexBuffer = (IWineD3DBuffer *) object;
 
     return WINED3D_OK;
 }
@@ -799,7 +752,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateStateBlock(IWineD3DDevice* iface,
             }
         }
         if(object->pIndexData) {
-            IWineD3DIndexBuffer_AddRef(object->pIndexData);
+            IWineD3DBuffer_AddRef(object->pIndexData);
         }
         if(object->vertexShader) {
             IWineD3DVertexShader_AddRef(object->vertexShader);
@@ -3684,40 +3637,48 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetMaterial(IWineD3DDevice *iface, WINE
 /*****
  * Get / Set Indices
  *****/
-static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWineD3DIndexBuffer* pIndexData) {
+static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWineD3DBuffer* pIndexData, WINED3DFORMAT fmt) {
     IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DIndexBuffer *oldIdxs;
+    IWineD3DBuffer *oldIdxs;
 
     TRACE("(%p) : Setting to %p\n", This, pIndexData);
     oldIdxs = This->updateStateBlock->pIndexData;
 
     This->updateStateBlock->changed.indices = TRUE;
     This->updateStateBlock->pIndexData = pIndexData;
+    This->updateStateBlock->IndexFmt = fmt;
 
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
         TRACE("Recording... not performing anything\n");
-        if(pIndexData) IWineD3DIndexBuffer_AddRef(pIndexData);
-        if(oldIdxs) IWineD3DIndexBuffer_Release(oldIdxs);
+        if(pIndexData) IWineD3DBuffer_AddRef(pIndexData);
+        if(oldIdxs) IWineD3DBuffer_Release(oldIdxs);
         return WINED3D_OK;
     }
 
     if(oldIdxs != pIndexData) {
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
-        if(pIndexData) IWineD3DIndexBuffer_AddRef(pIndexData);
-        if(oldIdxs) IWineD3DIndexBuffer_Release(oldIdxs);
+        if(pIndexData) {
+            InterlockedIncrement(&((struct wined3d_buffer *)pIndexData)->bind_count);
+            IWineD3DBuffer_AddRef(pIndexData);
+        }
+        if(oldIdxs) {
+            InterlockedDecrement(&((struct wined3d_buffer *)oldIdxs)->bind_count);
+            IWineD3DBuffer_Release(oldIdxs);
+        }
     }
+
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_GetIndices(IWineD3DDevice *iface, IWineD3DIndexBuffer** ppIndexData) {
+static HRESULT WINAPI IWineD3DDeviceImpl_GetIndices(IWineD3DDevice *iface, IWineD3DBuffer** ppIndexData) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     *ppIndexData = This->stateBlock->pIndexData;
 
     /* up ref count on ppindexdata */
     if (*ppIndexData) {
-        IWineD3DIndexBuffer_AddRef(*ppIndexData);
+        IWineD3DBuffer_AddRef(*ppIndexData);
         TRACE("(%p) index data set to %p\n", This, ppIndexData);
     }else{
         TRACE("(%p) No index data set\n", This);
@@ -4109,7 +4070,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetVertexShaderConstantF(
             iface, srcData, start, count);
 
     /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
-    if (srcData == NULL || start + count > GL_LIMITS(vshader_constantsF) || start > GL_LIMITS(vshader_constantsF))
+    if (srcData == NULL || start + count > This->d3d_vshader_constantF || start > This->d3d_vshader_constantF)
         return WINED3DERR_INVALIDCALL;
 
     memcpy(&This->updateStateBlock->vertexShaderConstantF[start * 4], srcData, count * sizeof(float) * 4);
@@ -4138,7 +4099,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetVertexShaderConstantF(
     UINT count) {
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    int cnt = min(count, GL_LIMITS(vshader_constantsF) - start);
+    int cnt = min(count, This->d3d_vshader_constantF - start);
 
     TRACE("(iface %p, dstData %p, start %d, count %d)\n",
             iface, dstData, start, count);
@@ -4501,7 +4462,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShaderConstantF(
             iface, srcData, start, count);
 
     /* Specifically test start > limit to catch MAX_UINT overflows when adding start + count */
-    if (srcData == NULL || start + count > GL_LIMITS(pshader_constantsF) || start > GL_LIMITS(pshader_constantsF))
+    if (srcData == NULL || start + count > This->d3d_pshader_constantF || start > This->d3d_pshader_constantF)
         return WINED3DERR_INVALIDCALL;
 
     memcpy(&This->updateStateBlock->pixelShaderConstantF[start * 4], srcData, count * sizeof(float) * 4);
@@ -4530,7 +4491,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
     UINT count) {
 
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    int cnt = min(count, GL_LIMITS(pshader_constantsF) - start);
+    int cnt = min(count, This->d3d_pshader_constantF - start);
 
     TRACE("(iface %p, dstData %p, start %d, count %d)\n",
             iface, dstData, start, count);
@@ -4544,11 +4505,11 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF(
 
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
 static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount,
-        const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags)
+        const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags,
+        DWORD DestFVF)
 {
     char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL;
     unsigned int i;
-    DWORD DestFVF = dest->fvf;
     WINED3DVIEWPORT vp;
     WINED3DMATRIX mat, proj_mat, view_mat, world_mat;
     BOOL doClip;
@@ -4637,7 +4598,7 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
            FIXME("Clipping is broken and disabled for now\n");
         }
     } else doClip = FALSE;
-    dest_ptr = ((char *) dest->resource.allocatedMemory) + dwDestIndex * get_flexible_vertex_size(DestFVF);
+    dest_ptr = ((char *) buffer_get_sysmem(dest)) + dwDestIndex * get_flexible_vertex_size(DestFVF);
 
     IWineD3DDevice_GetTransform( (IWineD3DDevice *) This,
                                  WINED3DTS_VIEW,
@@ -4904,7 +4865,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn
 #undef copy_and_next
 
 static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex,
-        UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags)
+        UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags,
+        DWORD DestFVF)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     struct wined3d_stream_info stream_info;
@@ -4939,7 +4901,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
             {
                 struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
                 e->buffer_object = 0;
-                e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory);
+                e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
                 ENTER_GL();
                 GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object));
                 vb->buffer_object = 0;
@@ -4950,7 +4912,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
     }
 
     return process_vertices_strided(This, DestIndex, VertexCount, &stream_info,
-            (struct wined3d_buffer *)pDestBuffer, Flags);
+            (struct wined3d_buffer *)pDestBuffer, Flags, DestFVF);
 }
 
 /*****
@@ -5677,8 +5639,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
 {
     IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;
     UINT                 idxStride = 2;
-    IWineD3DIndexBuffer *pIB;
-    WINED3DINDEXBUFFER_DESC  IdxBufDsc;
+    IWineD3DBuffer *pIB;
     GLuint vbo;
 
     pIB = This->stateBlock->pIndexData;
@@ -5700,13 +5661,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
         IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
         This->stateBlock->streamIsUP = FALSE;
     }
-    vbo = ((IWineD3DIndexBufferImpl *) pIB)->vbo;
+    vbo = ((struct wined3d_buffer *) pIB)->buffer_object;
 
     TRACE("(%p) : min %u, vertex count %u, startIdx %u, index count %u\n",
             This, minIndex, NumVertices, startIndex, index_count);
 
-    IWineD3DIndexBuffer_GetDesc(pIB, &IdxBufDsc);
-    if (IdxBufDsc.Format == WINED3DFMT_R16_UINT) {
+    if (This->stateBlock->IndexFmt == WINED3DFMT_R16_UINT) {
         idxStride = 2;
     } else {
         idxStride = 4;
@@ -5718,7 +5678,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
     }
 
     drawPrimitive(iface, index_count, NumVertices, startIndex, idxStride,
-            vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex);
+            vbo ? NULL : ((struct wined3d_buffer *) pIB)->resource.allocatedMemory, minIndex);
 
     return WINED3D_OK;
 }
@@ -5769,7 +5729,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
     int                 idxStride;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     IWineD3DBuffer *vb;
-    IWineD3DIndexBuffer *ib;
+    IWineD3DBuffer *ib;
 
     TRACE("(%p) : MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u\n",
             This, MinVertexIndex, NumVertices, index_count, pIndexData,
@@ -5809,7 +5769,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveUP(IWineD3DDevice *
     This->stateBlock->streamStride[0] = 0;
     ib = This->stateBlock->pIndexData;
     if(ib) {
-        IWineD3DIndexBuffer_Release(ib);
+        IWineD3DBuffer_Release(ib);
         This->stateBlock->pIndexData = NULL;
     }
     /* No need to mark the stream source state dirty here. Either the app calls UP drawing again, or it has to call
@@ -6496,7 +6456,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawRectPatch(IWineD3DDevice *iface, UI
     This->currentPatch = patch;
     old_primitive_type = This->stateBlock->gl_primitive_type;
     This->stateBlock->gl_primitive_type = GL_TRIANGLES;
-    IWineD3DDevice_DrawPrimitiveStrided(iface, patch->numSegs[0] * patch->numSegs[1] * 2, &patch->strided);
+    IWineD3DDevice_DrawPrimitiveStrided(iface, patch->numSegs[0] * patch->numSegs[1] * 2 * 3, &patch->strided);
     This->stateBlock->gl_primitive_type = old_primitive_type;
     This->currentPatch = NULL;
 
@@ -7905,7 +7865,7 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
         case WINED3DRTYPE_VOLUME:
         /* TODO: nothing really? */
         break;
-        case WINED3DRTYPE_VERTEXBUFFER:
+        case WINED3DRTYPE_BUFFER:
         {
             int streamNumber;
             TRACE("Cleaning up stream pointers\n");
@@ -7928,25 +7888,20 @@ static void WINAPI IWineD3DDeviceImpl_ResourceReleased(IWineD3DDevice *iface, IW
                     }
                 }
             }
-        }
-        break;
-        case WINED3DRTYPE_INDEXBUFFER:
-        if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */
-            if (This->updateStateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) {
-                This->updateStateBlock->pIndexData =  NULL;
+
+            if (This->updateStateBlock != NULL ) { /* ==NULL when device is being destroyed */
+                if (This->updateStateBlock->pIndexData == (IWineD3DBuffer *)resource) {
+                    This->updateStateBlock->pIndexData =  NULL;
+                }
             }
-        }
-        if (This->stateBlock != NULL ) { /* ==NULL when device is being destroyed */
-            if (This->stateBlock->pIndexData == (IWineD3DIndexBuffer *)resource) {
-                This->stateBlock->pIndexData =  NULL;
+            if (This->stateBlock != NULL ) { /* ==NULL when device is being destroyed */
+                if (This->stateBlock->pIndexData == (IWineD3DBuffer *)resource) {
+                    This->stateBlock->pIndexData =  NULL;
+                }
             }
         }
         break;
 
-        case WINED3DRTYPE_BUFFER:
-            /* Nothing to do, yet.*/
-            break;
-
         default:
         FIXME("(%p) unknown resource type %p %u\n", This, resource, IWineD3DResource_GetType(resource));
         break;
index a1bb3da..7c6cc3b 100644 (file)
@@ -425,14 +425,10 @@ static void select_shader_max_constants(
 
     switch (vs_selected_mode) {
         case SHADER_GLSL:
-            /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
-            gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
+            gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF;
             break;
         case SHADER_ARB:
-            /* We have to subtract any other PARAMs that we might use in our shader programs.
-             * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
-             * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
-            gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
+            gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF;
             break;
         default:
             gl_info->max_vshader_constantsF = 0;
@@ -441,18 +437,10 @@ static void select_shader_max_constants(
 
     switch (ps_selected_mode) {
         case SHADER_GLSL:
-            /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
-             * In theory the texbem instruction may need one more shader constant too. But lets assume
-             * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
-             * and lets not take away a uniform needlessly from all other shaders.
-             */
-            gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+            gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF;
             break;
         case SHADER_ARB:
-            /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
-             * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
-             */
-            gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
+            gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
             break;
         default:
             gl_info->max_pshader_constantsF = 0;
@@ -1089,13 +1077,29 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
              * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
              */
             if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
-                /* Geforce GTX - highend */
-                if(strstr(gl_info->gl_renderer, "GTX 280")) {
+                /* Geforce 200 - highend */
+                if(strstr(gl_info->gl_renderer, "GTX 280") ||
+                   strstr(gl_info->gl_renderer, "GTX 285") ||
+                   strstr(gl_info->gl_renderer, "GTX 295"))
+                {
                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280;
                     vidmem = 1024;
                 }
-                /* Geforce9 - highend */
-                else if(strstr(gl_info->gl_renderer, "9800")) {
+                /* Geforce 200 - midend high */
+                if(strstr(gl_info->gl_renderer, "GTX 275")) {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX275;
+                    vidmem = 896;
+                }
+                /* Geforce 200 - midend */
+                if(strstr(gl_info->gl_renderer, "GTX 260")) {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX260;
+                    vidmem = 1024;
+                }
+                /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
+                else if(strstr(gl_info->gl_renderer, "9800") ||
+                        strstr(gl_info->gl_renderer, "GTS 150") ||
+                        strstr(gl_info->gl_renderer, "GTS 250"))
+                {
                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT;
                     vidmem = 512;
                 }
@@ -1104,6 +1108,28 @@ static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_9600GT;
                     vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
                 }
+                /* Geforce9 - midend low / Geforce 200 - low*/
+                else if(strstr(gl_info->gl_renderer, "9500") ||
+                        strstr(gl_info->gl_renderer, "GT 120") ||
+                        strstr(gl_info->gl_renderer, "GT 130"))
+                {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9500GT;
+                    vidmem = 256; /* The 9500GT has 256-1024MB */
+                }
+                /* Geforce9 - lowend */
+                else if(strstr(gl_info->gl_renderer, "9400")) {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9400GT;
+                    vidmem = 256; /* The 9400GT has 256-1024MB */
+                }
+                /* Geforce9 - lowend low */
+                else if(strstr(gl_info->gl_renderer, "9100") ||
+                        strstr(gl_info->gl_renderer, "9200") ||
+                        strstr(gl_info->gl_renderer, "9300") ||
+                        strstr(gl_info->gl_renderer, "G 100"))
+                {
+                    gl_info->gl_card = CARD_NVIDIA_GEFORCE_9200;
+                    vidmem = 256; /* The 9100-9300 cards have 256MB */
+                }
                 /* Geforce8 - highend */
                 else if (strstr(gl_info->gl_renderer, "8800")) {
                     gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
@@ -1683,7 +1709,10 @@ static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier(IWineD3D *iface, UINT Ad
     /* Return the information requested */
     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
     strcpy(pIdentifier->Driver, This->adapters[Adapter].driver);
-    strcpy(pIdentifier->Description, This->adapters[Adapter].description);
+    if(This->adapters[Adapter].gl_info.driver_description)
+        strcpy(pIdentifier->Description, This->adapters[Adapter].gl_info.driver_description);
+    else /* Copy default description "Direct3D HAL" */
+        strcpy(pIdentifier->Description, This->adapters[Adapter].description);
 
     /* Note dx8 doesn't supply a DeviceName */
     if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
@@ -3010,7 +3039,7 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapt
                 /* Do nothing, continue with checking the format below */
                 break;
         }
-    } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
+    } else if(RType == WINED3DRTYPE_BUFFER){
         /* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
         TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
         return WINED3DERR_NOTAVAILABLE;
@@ -3697,6 +3726,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
     const struct fragment_pipeline *frag_pipeline = NULL;
     int i;
     struct fragment_caps ffp_caps;
+    struct shader_caps shader_caps;
     HRESULT hr;
 
     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
@@ -3752,6 +3782,11 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
             &object->ps_selected_mode, &object->vs_selected_mode);
     object->shader_backend = select_shader_backend(adapter, DeviceType);
 
+    memset(&shader_caps, 0, sizeof(shader_caps));
+    object->shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
+    object->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
+    object->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
+
     memset(&ffp_caps, 0, sizeof(ffp_caps));
     frag_pipeline = select_fragment_implementation(adapter, DeviceType);
     object->frag_pipe = frag_pipeline;
@@ -3913,41 +3948,59 @@ static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
 struct driver_version_information {
     WORD vendor;                        /* reported PCI card vendor ID  */
     WORD card;                          /* reported PCI card device ID  */
+    const char *description;                  /* Description of the card e.g. NVIDIA RIVA TNT */
     WORD hipart_hi, hipart_lo;          /* driver hiword to report      */
     WORD lopart_hi, lopart_lo;          /* driver loword to report      */
 };
 
 static const struct driver_version_information driver_version_table[] = {
-    /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (177.x)*/
-    /* GeforceFX support is up to 173.x, Geforce2MX/3/4 up to 96.x, TNT/Geforce1/2 up to 71.x */
-    /* Note that version numbers >100 lets say 123.45 use >= x.y.11.2345 and not x.y.10.12345 */
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    7,  15, 11, 7341   },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     7,  15, 11, 7341    },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     7,  15, 11, 7341    },
-    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     7,  15, 11, 7341    },
+    /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
+     * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
+     * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
+     * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
+     *
+     * All version numbers used below are from the Linux nvidia drivers.
+     */
+    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        9,  6,  4,  3      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", 7,  1,  8,  6      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  9,  6,  4,  3      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           9,  6,  4,  3      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          9,  6,  4,  3      },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           7,  15, 11, 7341   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           7,  15, 11, 7341   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           7,  15, 11, 7341   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           7,  15, 11, 8044   },
+    {VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           7,  15, 11, 8044   },
 
     /* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
-    {VENDOR_ATI,        CARD_ATI_RADEON_9500,           6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_X700,           6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         6,  14, 10, 6764    },
-    {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         6,  14, 10, 6764    },
-
-    /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
+    {VENDOR_ATI,        CARD_ATI_RADEON_9500,           "ATI Radeon 9500",                  6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_X700,           "ATI Radeon X700 SE",               6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_X1600,          "ATI Radeon X1600 Series",          6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2300,         "ATI Mobility Radeon HD 2300",      6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      6,  14, 10, 6764    },
+    {VENDOR_ATI,        CARD_ATI_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            6,  14, 10, 6764    },
+
+    /* TODO: Add information about legacy ATI hardware, Intel and other cards */
 };
 
 static void fixup_extensions(WineD3D_GL_Info *gl_info) {
@@ -4049,6 +4102,7 @@ static void fixup_extensions(WineD3D_GL_Info *gl_info) {
                                                                driver_version_table[i].lopart_lo);
             gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
                                                                driver_version_table[i].hipart_lo);
+            strcpy(gl_info->driver_description, driver_version_table[i].description);
             break;
         }
     }
index 80d366a..c96b975 100644 (file)
@@ -95,7 +95,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
          * idxData will be != NULL
          */
         if(idxData == NULL) {
-            idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory;
+            idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData);
         }
 
         if (idxSize == 2) pIdxBufS = idxData;
@@ -413,7 +413,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream
          * idxData will be != NULL
          */
         if(idxData == NULL) {
-            idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory;
+            idxData = buffer_get_sysmem((struct wined3d_buffer *) This->stateBlock->pIndexData);
         }
 
         if (idxSize == 2) pIdxBufS = idxData;
@@ -512,7 +512,7 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wine
             {
                 struct wined3d_buffer *vb =
                         (struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx];
-                ptr += (long) vb->resource.allocatedMemory;
+                ptr += (long) buffer_get_sysmem(vb);
             }
 
             send_attribute(This, si->elements[instancedData[j]].format_desc->format, instancedData[j], ptr);
@@ -535,7 +535,7 @@ static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_i
         {
             struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
             e->buffer_object = 0;
-            e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory);
+            e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
         }
     }
 }
@@ -744,7 +744,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
     {
         struct wined3d_buffer *vb;
         vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx];
-        e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory);
+        e->data = (BYTE *)((unsigned long)e->data + (unsigned long)buffer_get_sysmem(vb));
     }
     vtxStride = e->stride;
     data = e->data +
index 9ea193e..61c5701 100644 (file)
@@ -100,7 +100,7 @@ struct glsl_shader_prog_link {
     GLint                       vuniformI_locations[MAX_CONST_I];
     GLint                       puniformI_locations[MAX_CONST_I];
     GLint                       posFixup_location;
-    GLint                       rectFixup_location[MAX_FRAGMENT_SAMPLERS];
+    GLint                       np2Fixup_location[MAX_FRAGMENT_SAMPLERS];
     GLint                       bumpenvmat_location[MAX_TEXTURES];
     GLint                       luminancescale_location[MAX_TEXTURES];
     GLint                       luminanceoffset_location[MAX_TEXTURES];
@@ -482,6 +482,48 @@ static void reset_program_constant_version(void *value, void *context)
     entry->constant_version = 0;
 }
 
+/**
+ * Loads the texture dimensions for NP2 fixup into the currently set GLSL program.
+ */
+static void shader_glsl_load_np2fixup_constants(
+    IWineD3DDevice* device,
+    char usePixelShader,
+    char useVertexShader) {
+
+    const IWineD3DDeviceImpl* deviceImpl = (const IWineD3DDeviceImpl*) device;
+    const struct glsl_shader_prog_link* prog = ((struct shader_glsl_priv *)(deviceImpl->shader_priv))->glsl_program;
+
+    if (!prog) {
+        /* No GLSL program set - nothing to do. */
+        return;
+    }
+
+    if (!usePixelShader) {
+        /* NP2 texcoord fixup is (currently) only done for pixelshaders. */
+        return;
+    }
+
+    if (prog->ps_args.np2_fixup) {
+        UINT i;
+        UINT fixup = prog->ps_args.np2_fixup;
+        const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
+        const IWineD3DStateBlockImpl* stateBlock = (const IWineD3DStateBlockImpl*) deviceImpl->stateBlock;
+
+        for (i = 0; fixup; fixup >>= 1, ++i) {
+            if (-1 != prog->np2Fixup_location[i]) {
+                const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
+                if (!tex) {
+                    FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n");
+                    continue;
+                } else {
+                    const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
+                    GL_EXTCALL(glUniform2fvARB(prog->np2Fixup_location[i], 1, tex_dim));
+                }
+            }
+        }
+    }
+}
+
 /**
  * Loads the app-supplied constants into the currently set GLSL program.
  */
@@ -588,24 +630,6 @@ static void shader_glsl_load_constants(
             }
             GL_EXTCALL(glUniform4fvARB(prog->ycorrection_location, 1, correction_params));
         }
-
-        /* Constant loading for texture rect coord fixup. */
-        if (prog->ps_args.texrect_fixup) {
-            UINT fixup = prog->ps_args.texrect_fixup;
-
-            for (i = 0; fixup; fixup >>= 1, ++i) {
-                if (-1 != prog->rectFixup_location[i]) {
-                    const IWineD3DBaseTextureImpl* const tex = (const IWineD3DBaseTextureImpl*) stateBlock->textures[i];
-                    if (!tex) {
-                        FIXME("Non-existant texture is flagged for NP2 texcoord fixup\n");
-                        continue;
-                    } else {
-                        const float tex_dim[2] = {tex->baseTexture.pow2Matrix[0], tex->baseTexture.pow2Matrix[5]};
-                        GL_EXTCALL(glUniform2fvARB(prog->rectFixup_location[i], 1, tex_dim));
-                    }
-                }
-            }
-        }
     }
 
     if (priv->next_constant_version == UINT_MAX)
@@ -698,8 +722,15 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
 
     /* Declare the constants (aka uniforms) */
     if (This->baseShader.limits.constant_float > 0) {
-        unsigned max_constantsF = min(This->baseShader.limits.constant_float, 
-                (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF)));
+        unsigned max_constantsF;
+        if(pshader) {
+            max_constantsF = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+            max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+        } else {
+            /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
+            max_constantsF = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
+            max_constantsF = min(This->baseShader.limits.constant_float, max_constantsF);
+        }
         shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
     }
 
@@ -794,12 +825,12 @@ static void shader_generate_glsl_declarations(IWineD3DBaseShader *iface, const s
                         shader_addline(buffer, "uniform sampler2D %csampler%u;\n", prefix, i);
                     }
 
-                    if(ps_args->texrect_fixup & (1 << i)) {
-                        /* RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
+                    if(ps_args->np2_fixup & (1 << i)) {
+                        /* NP2/RECT textures in OpenGL use texcoords in the range [0,width]x[0,height]
                          * while D3D has them in the (normalized) [0,1]x[0,1] range.
-                         * samplerRectFixup stores texture dimensions and is updated through
-                         * shader_glsl_load_constants when the sampler changes. */
-                        shader_addline(buffer, "uniform vec2 %csamplerRectFixup%u;\n", prefix, i);
+                         * samplerNP2Fixup stores texture dimensions and is updated through
+                         * shader_glsl_load_np2fixup_constants when the sampler changes. */
+                        shader_addline(buffer, "uniform vec2 %csamplerNP2Fixup%u;\n", prefix, i);
                     }
                     break;
                 case WINED3DSTT_CUBE:
@@ -989,26 +1020,25 @@ static void shader_glsl_gen_modifier (
 
 /** Writes the GLSL variable name that corresponds to the register that the
  * DX opcode parameter is trying to access */
-static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_token,
-        char *regstr, BOOL *is_color, const struct wined3d_shader_instruction *ins)
+static void shader_glsl_get_register_name(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx,
+        BOOL rel_addr, const DWORD addr_token, char *register_name, BOOL *is_color,
+        const struct wined3d_shader_instruction *ins)
 {
     /* oPos, oFog and oPts in D3D */
     static const char * const hwrastout_reg_names[] = { "gl_Position", "gl_FogFragCoord", "gl_PointSize" };
 
-    DWORD reg = param & WINED3DSP_REGNUM_MASK;
-    DWORD regtype = shader_get_regtype(param);
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)ins->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     const WineD3D_GL_Info* gl_info = &deviceImpl->adapter->gl_info;
     DWORD shader_version = This->baseShader.reg_maps.shader_version;
     char pshader = shader_is_pshader_version(shader_version);
-    char tmpStr[150];
 
-    *is_color = FALSE;   
-    switch (regtype) {
+    *is_color = FALSE;
+
+    switch (register_type)
+    {
     case WINED3DSPR_TEMP:
-        sprintf(tmpStr, "R%u", reg);
+        sprintf(register_name, "R%u", register_idx);
     break;
     case WINED3DSPR_INPUT:
         if (pshader) {
@@ -1017,84 +1047,90 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
             {
                 DWORD in_count = GL_LIMITS(glsl_varyings) / 4;
 
-                if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
+                if (rel_addr)
+                {
                     glsl_src_param_t rel_param;
                     shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
 
                     /* Removing a + 0 would be an obvious optimization, but macos doesn't see the NOP
                      * operation there
                      */
-                    if(((IWineD3DPixelShaderImpl *) This)->input_reg_map[reg]) {
+                    if (((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx])
+                    {
                         if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
-                            sprintf(tmpStr, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg], in_count - 1,
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg], in_count,
-                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg]);
+                            sprintf(register_name, "((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
+                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count - 1,
+                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx], in_count,
+                                    rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
                         } else {
-                            sprintf(tmpStr, "IN[%s + %u]", rel_param.param_str, ((IWineD3DPixelShaderImpl *)This)->input_reg_map[reg]);
+                            sprintf(register_name, "IN[%s + %u]", rel_param.param_str,
+                                    ((IWineD3DPixelShaderImpl *)This)->input_reg_map[register_idx]);
                         }
                     } else {
                         if (((IWineD3DPixelShaderImpl *)This)->declared_in_count > in_count) {
-                            sprintf(tmpStr, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
+                            sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
                                     rel_param.param_str, in_count - 1,
                                     rel_param.param_str, in_count,
                                     rel_param.param_str);
                         } else {
-                            sprintf(tmpStr, "IN[%s]", rel_param.param_str);
+                            sprintf(register_name, "IN[%s]", rel_param.param_str);
                         }
                     }
                 } else {
-                    DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[reg];
+                    DWORD idx = ((IWineD3DPixelShaderImpl *) This)->input_reg_map[register_idx];
                     if (idx == in_count) {
-                        sprintf(tmpStr, "gl_Color");
+                        sprintf(register_name, "gl_Color");
                     } else if (idx == in_count + 1) {
-                        sprintf(tmpStr, "gl_SecondaryColor");
+                        sprintf(register_name, "gl_SecondaryColor");
                     } else {
-                        sprintf(tmpStr, "IN[%u]", idx);
+                        sprintf(register_name, "IN[%u]", idx);
                     }
                 }
             } else {
-                if (reg==0)
-                    strcpy(tmpStr, "gl_Color");
+                if (register_idx == 0)
+                    strcpy(register_name, "gl_Color");
                 else
-                    strcpy(tmpStr, "gl_SecondaryColor");
+                    strcpy(register_name, "gl_SecondaryColor");
             }
         } else {
-            if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << reg)) *is_color = TRUE;
-            sprintf(tmpStr, "attrib%u", reg);
-        } 
+            if (((IWineD3DVertexShaderImpl *)This)->cur_args->swizzle_map & (1 << register_idx)) *is_color = TRUE;
+            sprintf(register_name, "attrib%u", register_idx);
+        }
         break;
     case WINED3DSPR_CONST:
     {
         const char prefix = pshader? 'P':'V';
 
         /* Relative addressing */
-        if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
-
+        if (rel_addr)
+        {
            /* Relative addressing on shaders 2.0+ have a relative address token, 
             * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
            if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 2)
            {
                glsl_src_param_t rel_param;
                shader_glsl_add_src_param(ins, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
-               if(reg) {
-                   sprintf(tmpStr, "%cC[%s + %u]", prefix, rel_param.param_str, reg);
+               if (register_idx)
+               {
+                   sprintf(register_name, "%cC[%s + %u]", prefix, rel_param.param_str, register_idx);
                } else {
-                   sprintf(tmpStr, "%cC[%s]", prefix, rel_param.param_str);
+                   sprintf(register_name, "%cC[%s]", prefix, rel_param.param_str);
                }
            } else {
-               if(reg) {
-                   sprintf(tmpStr, "%cC[A0.x + %u]", prefix, reg);
+               if (register_idx)
+               {
+                   sprintf(register_name, "%cC[A0.x + %u]", prefix, register_idx);
                } else {
-                   sprintf(tmpStr, "%cC[A0.x]", prefix);
+                   sprintf(register_name, "%cC[A0.x]", prefix);
                }
            }
 
         } else {
-            if(shader_constant_is_local(This, reg)) {
-                sprintf(tmpStr, "%cLC%u", prefix, reg);
+            if (shader_constant_is_local(This, register_idx))
+            {
+                sprintf(register_name, "%cLC%u", prefix, register_idx);
             } else {
-                sprintf(tmpStr, "%cC[%u]", prefix, reg);
+                sprintf(register_name, "%cC[%u]", prefix, register_idx);
             }
         }
 
@@ -1102,99 +1138,109 @@ static void shader_glsl_get_register_name(const DWORD param, const DWORD addr_to
     }
     case WINED3DSPR_CONSTINT:
         if (pshader)
-            sprintf(tmpStr, "PI[%u]", reg);
+            sprintf(register_name, "PI[%u]", register_idx);
         else
-            sprintf(tmpStr, "VI[%u]", reg);
+            sprintf(register_name, "VI[%u]", register_idx);
         break;
     case WINED3DSPR_CONSTBOOL:
         if (pshader)
-            sprintf(tmpStr, "PB[%u]", reg);
+            sprintf(register_name, "PB[%u]", register_idx);
         else
-            sprintf(tmpStr, "VB[%u]", reg);
+            sprintf(register_name, "VB[%u]", register_idx);
         break;
     case WINED3DSPR_TEXTURE: /* case WINED3DSPR_ADDR: */
         if (pshader) {
-            sprintf(tmpStr, "T%u", reg);
+            sprintf(register_name, "T%u", register_idx);
         } else {
-            sprintf(tmpStr, "A%u", reg);
+            sprintf(register_name, "A%u", register_idx);
         }
     break;
     case WINED3DSPR_LOOP:
-        sprintf(tmpStr, "aL%u", This->baseShader.cur_loop_regno - 1);
+        sprintf(register_name, "aL%u", This->baseShader.cur_loop_regno - 1);
     break;
     case WINED3DSPR_SAMPLER:
         if (pshader)
-            sprintf(tmpStr, "Psampler%u", reg);
+            sprintf(register_name, "Psampler%u", register_idx);
         else
-            sprintf(tmpStr, "Vsampler%u", reg);
+            sprintf(register_name, "Vsampler%u", register_idx);
     break;
     case WINED3DSPR_COLOROUT:
-        if (reg >= GL_LIMITS(buffers)) {
-            WARN("Write to render target %u, only %d supported\n", reg, 4);
-        }
+        if (register_idx >= GL_LIMITS(buffers))
+            WARN("Write to render target %u, only %d supported\n", register_idx, 4);
+
         if (GL_SUPPORT(ARB_DRAW_BUFFERS)) {
-            sprintf(tmpStr, "gl_FragData[%u]", reg);
+            sprintf(register_name, "gl_FragData[%u]", register_idx);
         } else { /* On older cards with GLSL support like the GeforceFX there's only one buffer. */
-            sprintf(tmpStr, "gl_FragColor");
+            sprintf(register_name, "gl_FragColor");
         }
     break;
     case WINED3DSPR_RASTOUT:
-        sprintf(tmpStr, "%s", hwrastout_reg_names[reg]);
+        sprintf(register_name, "%s", hwrastout_reg_names[register_idx]);
     break;
     case WINED3DSPR_DEPTHOUT:
-        sprintf(tmpStr, "gl_FragDepth");
+        sprintf(register_name, "gl_FragDepth");
     break;
     case WINED3DSPR_ATTROUT:
-        if (reg == 0) {
-            sprintf(tmpStr, "gl_FrontColor");
+        if (register_idx == 0)
+        {
+            sprintf(register_name, "gl_FrontColor");
         } else {
-            sprintf(tmpStr, "gl_FrontSecondaryColor");
+            sprintf(register_name, "gl_FrontSecondaryColor");
         }
     break;
     case WINED3DSPR_TEXCRDOUT:
         /* Vertex shaders >= 3.0: WINED3DSPR_OUTPUT */
-        if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(tmpStr, "OUT[%u]", reg);
-        else sprintf(tmpStr, "gl_TexCoord[%u]", reg);
+        if (WINED3DSHADER_VERSION_MAJOR(shader_version) >= 3) sprintf(register_name, "OUT[%u]", register_idx);
+        else sprintf(register_name, "gl_TexCoord[%u]", register_idx);
     break;
     case WINED3DSPR_MISCTYPE:
-        if (reg == 0) {
+        if (register_idx == 0)
+        {
             /* vPos */
-            sprintf(tmpStr, "vpos");
-        } else if (reg == 1){
+            sprintf(register_name, "vpos");
+        }
+        else if (register_idx == 1)
+        {
             /* Note that gl_FrontFacing is a bool, while vFace is
              * a float for which the sign determines front/back
              */
-            sprintf(tmpStr, "(gl_FrontFacing ? 1.0 : -1.0)");
+            sprintf(register_name, "(gl_FrontFacing ? 1.0 : -1.0)");
         } else {
-            FIXME("Unhandled misctype register %d\n", reg);
-            sprintf(tmpStr, "unrecognized_register");
+            FIXME("Unhandled misctype register %d\n", register_idx);
+            sprintf(register_name, "unrecognized_register");
         }
         break;
     default:
-        FIXME("Unhandled register name Type(%d)\n", regtype);
-        sprintf(tmpStr, "unrecognized_register");
+        FIXME("Unhandled register name Type(%d)\n", register_type);
+        sprintf(register_name, "unrecognized_register");
     break;
     }
+}
 
-    strcat(regstr, tmpStr);
+static void shader_glsl_write_mask_to_str(DWORD write_mask, char *str)
+{
+    *str++ = '.';
+    if (write_mask & WINED3DSP_WRITEMASK_0) *str++ = 'x';
+    if (write_mask & WINED3DSP_WRITEMASK_1) *str++ = 'y';
+    if (write_mask & WINED3DSP_WRITEMASK_2) *str++ = 'z';
+    if (write_mask & WINED3DSP_WRITEMASK_3) *str++ = 'w';
+    *str = '\0';
 }
 
 /* Get the GLSL write mask for the destination register */
-static DWORD shader_glsl_get_write_mask(const DWORD param, char *write_mask) {
-    char *ptr = write_mask;
-    DWORD mask = param & WINED3DSP_WRITEMASK_ALL;
+static DWORD shader_glsl_get_write_mask(const struct wined3d_shader_dst_param *param, char *write_mask)
+{
+    DWORD mask = param->write_mask;
 
-    if (shader_is_scalar(param)) {
+    if (shader_is_scalar(param->register_type, param->register_idx))
+    {
         mask = WINED3DSP_WRITEMASK_0;
-    } else {
-        *ptr++ = '.';
-        if (param & WINED3DSP_WRITEMASK_0) *ptr++ = 'x';
-        if (param & WINED3DSP_WRITEMASK_1) *ptr++ = 'y';
-        if (param & WINED3DSP_WRITEMASK_2) *ptr++ = 'z';
-        if (param & WINED3DSP_WRITEMASK_3) *ptr++ = 'w';
+        *write_mask = '\0';
+    }
+    else
+    {
+        shader_glsl_write_mask_to_str(mask, write_mask);
     }
-
-    *ptr = '\0';
 
     return mask;
 }
@@ -1218,7 +1264,8 @@ static void shader_glsl_get_swizzle(const DWORD param, BOOL fixup, DWORD mask, c
     const char *swizzle_chars = fixup ? "zyxw" : "xyzw";
     char *ptr = swizzle_str;
 
-    if (!shader_is_scalar(param)) {
+    if (!shader_is_scalar(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK))
+    {
         *ptr++ = '.';
         /* swizzle bits fields: wwzzyyxx */
         if (mask & WINED3DSP_WRITEMASK_0) *ptr++ = swizzle_chars[swizzle & 0x03];
@@ -1243,7 +1290,8 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i
     src_param->param_str[0] = '\0';
     swizzle_str[0] = '\0';
 
-    shader_glsl_get_register_name(param, addr_token, src_param->reg_name, &is_color, ins);
+    shader_glsl_get_register_name(shader_get_regtype(param), param & WINED3DSP_REGNUM_MASK,
+            param & WINED3DSHADER_ADDRMODE_RELATIVE, addr_token, src_param->reg_name, &is_color, ins);
 
     shader_glsl_get_swizzle(param, is_color, mask, swizzle_str);
     shader_glsl_gen_modifier(param, src_param->reg_name, swizzle_str, src_param->param_str);
@@ -1253,31 +1301,27 @@ static void shader_glsl_add_src_param(const struct wined3d_shader_instruction *i
  * Also, return the actual register name and swizzle in case the
  * caller needs this information as well. */
 static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *ins,
-        const DWORD param, const DWORD addr_token, glsl_dst_param_t *dst_param)
+        const struct wined3d_shader_dst_param *wined3d_dst, glsl_dst_param_t *glsl_dst)
 {
     BOOL is_color = FALSE;
 
-    dst_param->mask_str[0] = '\0';
-    dst_param->reg_name[0] = '\0';
+    glsl_dst->mask_str[0] = '\0';
+    glsl_dst->reg_name[0] = '\0';
 
-    shader_glsl_get_register_name(param, addr_token, dst_param->reg_name, &is_color, ins);
-    return shader_glsl_get_write_mask(param, dst_param->mask_str);
+    shader_glsl_get_register_name(wined3d_dst->register_type, wined3d_dst->register_idx,
+            wined3d_dst->has_rel_addr, wined3d_dst->addr_token, glsl_dst->reg_name, &is_color, ins);
+    return shader_glsl_get_write_mask(wined3d_dst, glsl_dst->mask_str);
 }
 
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer,
-        const struct wined3d_shader_instruction *ins, const DWORD param)
+        const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst)
 {
-    glsl_dst_param_t dst_param;
+    glsl_dst_param_t glsl_dst;
     DWORD mask;
-    int shift;
-
-    mask = shader_glsl_add_dst_param(ins, param, ins->dst[0].addr_token, &dst_param);
 
-    if(mask) {
-        shift = (param & WINED3DSP_DSTSHIFT_MASK) >> WINED3DSP_DSTSHIFT_SHIFT;
-        shader_addline(buffer, "%s%s = %s(", dst_param.reg_name, dst_param.mask_str, shift_glsl_tab[shift]);
-    }
+    mask = shader_glsl_add_dst_param(ins, dst, &glsl_dst);
+    if (mask) shader_addline(buffer, "%s%s = %s(", glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
 
     return mask;
 }
@@ -1285,35 +1329,35 @@ static DWORD shader_glsl_append_dst_ext(SHADER_BUFFER *buffer,
 /* Append the destination part of the instruction to the buffer, return the effective write mask */
 static DWORD shader_glsl_append_dst(SHADER_BUFFER *buffer, const struct wined3d_shader_instruction *ins)
 {
-    return shader_glsl_append_dst_ext(buffer, ins, ins->dst[0].token);
+    return shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0]);
 }
 
 /** Process GLSL instruction modifiers */
 void shader_glsl_add_instruction_modifiers(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
-    DWORD mask;
+    DWORD modifiers;
 
     if (!ins->dst_count) return;
 
-    mask = ins->dst[0].token & WINED3DSP_DSTMOD_MASK;
-    if (!mask) return;
+    modifiers = ins->dst[0].modifiers;
+    if (!modifiers) return;
 
-    shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param);
+    shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
-    if (mask & WINED3DSPDM_SATURATE)
+    if (modifiers & WINED3DSPDM_SATURATE)
     {
         /* _SAT means to clamp the value of the register to between 0 and 1 */
         shader_addline(ins->buffer, "%s%s = clamp(%s%s, 0.0, 1.0);\n", dst_param.reg_name,
                 dst_param.mask_str, dst_param.reg_name, dst_param.mask_str);
     }
 
-    if (mask & WINED3DSPDM_MSAMPCENTROID)
+    if (modifiers & WINED3DSPDM_MSAMPCENTROID)
     {
         FIXME("_centroid modifier not handled\n");
     }
 
-    if (mask & WINED3DSPDM_PARTIALPRECISION)
+    if (modifiers & WINED3DSPDM_PARTIALPRECISION)
     {
         /* MSDN says this modifier can be safely ignored, so that's what we'll do. */
     }
@@ -1435,18 +1479,18 @@ static void shader_glsl_append_fixup_arg(char *arguments, const char *reg_name,
 
 static void shader_glsl_color_correction(const struct wined3d_shader_instruction *ins, struct color_fixup_desc fixup)
 {
+    struct wined3d_shader_dst_param dst;
     unsigned int mask_size, remaining;
     glsl_dst_param_t dst_param;
     char arguments[256];
     DWORD mask;
-    BOOL dummy;
 
     mask = 0;
     if (fixup.x_sign_fixup || fixup.x_source != CHANNEL_SOURCE_X) mask |= WINED3DSP_WRITEMASK_0;
     if (fixup.y_sign_fixup || fixup.y_source != CHANNEL_SOURCE_Y) mask |= WINED3DSP_WRITEMASK_1;
     if (fixup.z_sign_fixup || fixup.z_source != CHANNEL_SOURCE_Z) mask |= WINED3DSP_WRITEMASK_2;
     if (fixup.w_sign_fixup || fixup.w_source != CHANNEL_SOURCE_W) mask |= WINED3DSP_WRITEMASK_3;
-    mask &= ins->dst[0].token;
+    mask &= ins->dst[0].write_mask;
 
     if (!mask) return; /* Nothing to do */
 
@@ -1459,11 +1503,9 @@ static void shader_glsl_color_correction(const struct wined3d_shader_instruction
 
     mask_size = shader_glsl_get_write_mask_size(mask);
 
-    dst_param.mask_str[0] = '\0';
-    shader_glsl_get_write_mask(mask, dst_param.mask_str);
-
-    dst_param.reg_name[0] = '\0';
-    shader_glsl_get_register_name(ins->dst[0].token, ins->dst[0].addr_token, dst_param.reg_name, &dummy, ins);
+    dst = ins->dst[0];
+    dst.write_mask = mask;
+    shader_glsl_add_dst_param(ins, &dst, &dst_param);
 
     arguments[0] = '\0';
     remaining = mask_size;
@@ -1506,10 +1548,10 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
     const char *sampler_base;
     char dst_swizzle[6];
     struct color_fixup_desc fixup;
-    BOOL rect_fixup = FALSE;
+    BOOL np2_fixup = FALSE;
     va_list args;
 
-    shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].token, dst_swizzle);
+    shader_glsl_get_swizzle(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle);
 
     if (shader_is_pshader_version(ins->reg_maps->shader_version))
     {
@@ -1517,11 +1559,11 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
         fixup = This->cur_args->color_fixup[sampler];
         sampler_base = "Psampler";
 
-        if(This->cur_args->texrect_fixup & (1 << sampler)) {
+        if(This->cur_args->np2_fixup & (1 << sampler)) {
             if(bias) {
-                FIXME("Biased sampling from RECT textures is unsupported\n");
+                FIXME("Biased sampling from NP2 textures is unsupported\n");
             } else {
-                rect_fixup = TRUE;
+                np2_fixup = TRUE;
             }
         }
     } else {
@@ -1540,8 +1582,8 @@ static void PRINTF_ATTR(6, 7) shader_glsl_gen_sample_code(const struct wined3d_s
     if(bias) {
         shader_addline(ins->buffer, ", %s)%s);\n", bias, dst_swizzle);
     } else {
-        if (rect_fixup) {
-            shader_addline(ins->buffer, " * PsamplerRectFixup%u)%s);\n", sampler, dst_swizzle);
+        if (np2_fixup) {
+            shader_addline(ins->buffer, " * PsamplerNP2Fixup%u)%s);\n", sampler, dst_swizzle);
         } else {
             shader_addline(ins->buffer, ")%s);\n", dst_swizzle);
         }
@@ -1599,7 +1641,7 @@ static void shader_glsl_mov(const struct wined3d_shader_instruction *ins)
      * shader versions WINED3DSIO_MOVA is used for this. */
     if ((WINED3DSHADER_VERSION_MAJOR(ins->reg_maps->shader_version) == 1
             && !shader_is_pshader_version(ins->reg_maps->shader_version)
-            && shader_get_regtype(ins->dst[0].token) == WINED3DSPR_ADDR))
+            && ins->dst[0].register_type == WINED3DSPR_ADDR))
     {
         /* This is a simple floor() */
         unsigned int mask_size = shader_glsl_get_write_mask_size(write_mask);
@@ -1662,7 +1704,7 @@ static void shader_glsl_cross(const struct wined3d_shader_instruction *ins)
     glsl_src_param_t src1_param;
     char dst_mask[6];
 
-    shader_glsl_get_write_mask(ins->dst[0].token, dst_mask);
+    shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
     shader_glsl_append_dst(ins->buffer, ins);
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
     shader_glsl_add_src_param(ins, ins->src[1], ins->src_addr[1], src_mask, &src1_param);
@@ -1785,7 +1827,7 @@ static void shader_glsl_expp(const struct wined3d_shader_instruction *ins)
         shader_addline(ins->buffer, "tmp0.w = 1.0;\n");
 
         shader_glsl_append_dst(ins->buffer, ins);
-        shader_glsl_get_write_mask(ins->dst[0].token, dst_mask);
+        shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
         shader_addline(ins->buffer, "tmp0%s);\n", dst_mask);
     } else {
         DWORD write_mask;
@@ -1900,7 +1942,7 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
     char mask_char[6];
     BOOL temp_destination = FALSE;
 
-    if (shader_is_scalar(ins->src[0]))
+    if (shader_is_scalar(shader_get_regtype(ins->src[0]), ins->src[0] & WINED3DSP_REGNUM_MASK))
     {
         write_mask = shader_glsl_append_dst(ins->buffer, ins);
 
@@ -1918,7 +1960,9 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
         DWORD src1regtype = shader_get_regtype(ins->src[1]);
         DWORD src2regtype = shader_get_regtype(ins->src[2]);
         DWORD dstreg = ins->dst[0].register_idx;
-        DWORD dstregtype = shader_get_regtype(ins->dst[0].token);
+        DWORD dstregtype = ins->dst[0].register_type;
+        DWORD dst_mask = ins->dst[0].write_mask;
+        struct wined3d_shader_dst_param dst = ins->dst[0];
 
         /* Cycle through all source0 channels */
         for (i=0; i<4; i++) {
@@ -1931,23 +1975,22 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
                     cmp_channel = WINED3DSP_WRITEMASK_0 << j;
                 }
             }
+            dst.write_mask = dst_mask & write_mask;
 
             /* Splitting the cmp instruction up in multiple lines imposes a problem:
             * The first lines may overwrite source parameters of the following lines.
             * Deal with that by using a temporary destination register if needed
             */
-            if((src0reg == dstreg && src0regtype == dstregtype) ||
-            (src1reg == dstreg && src1regtype == dstregtype) ||
-            (src2reg == dstreg && src2regtype == dstregtype)) {
-
-                write_mask = shader_glsl_get_write_mask(ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask),
-                        mask_char);
+            if ((src0reg == dstreg && src0regtype == dstregtype)
+                    || (src1reg == dstreg && src1regtype == dstregtype)
+                    || (src2reg == dstreg && src2regtype == dstregtype))
+            {
+                write_mask = shader_glsl_get_write_mask(&dst, mask_char);
                 if (!write_mask) continue;
                 shader_addline(ins->buffer, "tmp0%s = (", mask_char);
                 temp_destination = TRUE;
             } else {
-                write_mask = shader_glsl_append_dst_ext(ins->buffer, ins,
-                        ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask));
+                write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
                 if (!write_mask) continue;
             }
 
@@ -1960,8 +2003,8 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
         }
 
         if(temp_destination) {
-            shader_glsl_get_write_mask(ins->dst[0].token, mask_char);
-            shader_glsl_append_dst_ext(ins->buffer, ins, ins->dst[0].token);
+            shader_glsl_get_write_mask(&ins->dst[0], mask_char);
+            shader_glsl_append_dst(ins->buffer, ins);
             shader_addline(ins->buffer, "tmp0%s);\n", mask_char);
         }
     }
@@ -1973,11 +2016,13 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
  * the compare is done per component of src0. */
 static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
 {
+    struct wined3d_shader_dst_param dst;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
     glsl_src_param_t src2_param;
     DWORD write_mask, cmp_channel = 0;
     unsigned int i, j;
+    DWORD dst_mask;
 
     if (ins->reg_maps->shader_version < WINED3DPS_VERSION(1, 4))
     {
@@ -1997,6 +2042,8 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
         return;
     }
     /* Cycle through all source0 channels */
+    dst_mask = ins->dst[0].write_mask;
+    dst = ins->dst[0];
     for (i=0; i<4; i++) {
         write_mask = 0;
         /* Find the destination channels which use the current source0 channel */
@@ -2007,8 +2054,9 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
                 cmp_channel = WINED3DSP_WRITEMASK_0 << j;
             }
         }
-        write_mask = shader_glsl_append_dst_ext(ins->buffer, ins,
-                ins->dst[0].token & (~WINED3DSP_SWIZZLE_MASK | write_mask));
+
+        dst.write_mask = dst_mask & write_mask;
+        write_mask = shader_glsl_append_dst_ext(ins->buffer, ins, &dst);
         if (!write_mask) continue;
 
         shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], cmp_channel, &src0_param);
@@ -2084,10 +2132,10 @@ static void shader_glsl_mnxn(const struct wined3d_shader_instruction *ins)
             break;
     }
 
+    tmp_dst = ins->dst[0];
     for (i = 0; i < nComponents; ++i)
     {
-        tmp_dst.register_idx = ins->dst[0].register_idx;
-        tmp_dst.token = ((ins->dst[0].token) & ~WINED3DSP_WRITEMASK_ALL) | (WINED3DSP_WRITEMASK_0 << i);
+        tmp_dst.write_mask = WINED3DSP_WRITEMASK_0 << i;
         tmp_ins.src[1] = ins->src[1] + i;
         shader_glsl_dot(&tmp_ins);
     }
@@ -2130,7 +2178,7 @@ static void shader_glsl_lit(const struct wined3d_shader_instruction *ins)
     char dst_mask[6];
 
     shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_get_write_mask(ins->dst[0].token, dst_mask);
+    shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src1_param);
@@ -2177,7 +2225,7 @@ static void shader_glsl_dst(const struct wined3d_shader_instruction *ins)
     char dst_mask[6];
 
     shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_get_write_mask(ins->dst[0].token, dst_mask);
+    shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
 
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_1, &src0y_param);
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &src0z_param);
@@ -2451,7 +2499,7 @@ static void pshader_glsl_tex(const struct wined3d_shader_instruction *ins)
     if (shader_version < WINED3DPS_VERSION(1,4))
     {
         char coord_mask[6];
-        shader_glsl_get_write_mask(mask, coord_mask);
+        shader_glsl_write_mask_to_str(mask, coord_mask);
         shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, swizzle, NULL,
                 "T%u%s", sampler_idx, coord_mask);
     } else {
@@ -2506,16 +2554,15 @@ static void pshader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
 {
     /* FIXME: Make this work for more than just 2D textures */
     SHADER_BUFFER *buffer = ins->buffer;
-    DWORD write_mask;
-    char dst_mask[6];
-
-    write_mask = shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_get_write_mask(write_mask, dst_mask);
+    DWORD write_mask = shader_glsl_append_dst(ins->buffer, ins);
 
     if (ins->reg_maps->shader_version != WINED3DPS_VERSION(1,4))
     {
-        DWORD reg = ins->dst[0].register_idx;
-        shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n", reg, dst_mask);
+        char dst_mask[6];
+
+        shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
+        shader_addline(buffer, "clamp(gl_TexCoord[%u], 0.0, 1.0)%s);\n",
+                ins->dst[0].register_idx, dst_mask);
     } else {
         DWORD reg = ins->src[0] & WINED3DSP_REGNUM_MASK;
         DWORD src_mod = ins->src[0] & WINED3DSP_SRCMOD_MASK;
@@ -2621,7 +2668,7 @@ static void pshader_glsl_texdepth(const struct wined3d_shader_instruction *ins)
 {
     glsl_dst_param_t dst_param;
 
-    shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param);
+    shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
     /* Tests show that texdepth never returns anything below 0.0, and that r5.y is clamped to 1.0.
      * Negative input is accepted, -0.25 / -0.5 returns 0.5. GL should clamp gl_FragDepth to [0;1], but
@@ -2735,7 +2782,7 @@ static void pshader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
     shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], src_mask, &src0_param);
 
     shader_glsl_append_dst(ins->buffer, ins);
-    shader_glsl_get_write_mask(ins->dst[0].token, dst_mask);
+    shader_glsl_get_write_mask(&ins->dst[0], dst_mask);
     shader_addline(ins->buffer, "vec4(tmp0.xy, dot(T%u.xyz, %s), 1.0)%s);\n", reg, src0_param.param_str, dst_mask);
 
     current_state->current_row = 0;
@@ -2828,7 +2875,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
     shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
     mask = sample_function.coord_mask;
 
-    shader_glsl_get_write_mask(mask, coord_mask);
+    shader_glsl_write_mask_to_str(mask, coord_mask);
 
     /* with projective textures, texbem only divides the static texture coord, not the displacement,
          * so we can't let the GL handle this.
@@ -2843,7 +2890,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
             case WINED3DTTFF_COUNT4:
             case WINED3DTTFF_DISABLE: div_mask = WINED3DSP_WRITEMASK_3; break;
         }
-        shader_glsl_get_write_mask(div_mask, coord_div_mask);
+        shader_glsl_write_mask_to_str(div_mask, coord_div_mask);
         shader_addline(ins->buffer, "T%u%s /= T%u%s;\n", sampler_idx, coord_mask, sampler_idx, coord_div_mask);
     }
 
@@ -2860,7 +2907,7 @@ static void pshader_glsl_texbem(const struct wined3d_shader_instruction *ins)
         glsl_dst_param_t dst_param;
 
         shader_glsl_add_src_param(ins, ins->src[0], ins->src_addr[0], WINED3DSP_WRITEMASK_2, &luminance_param);
-        shader_glsl_add_dst_param(ins, ins->dst[0].token, ins->dst[0].addr_token, &dst_param);
+        shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
 
         shader_addline(ins->buffer, "%s%s *= (%s * luminancescale%d + luminanceoffset%d);\n",
                 dst_param.reg_name, dst_param.mask_str,
@@ -2939,7 +2986,7 @@ static void pshader_glsl_texkill(const struct wined3d_shader_instruction *ins)
     glsl_dst_param_t dst_param;
 
     /* The argument is a destination parameter, and no writemasks are allowed */
-    shader_glsl_add_dst_param(ins, ins->dst[0].token, 0, &dst_param);
+    shader_glsl_add_dst_param(ins, &ins->dst[0], &dst_param);
     if ((ins->reg_maps->shader_version >= WINED3DPS_VERSION(2,0)))
     {
         /* 2.0 shaders compare all 4 components in texkill */
@@ -2982,52 +3029,52 @@ static void pshader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
     }
 }
 
-static void pshader_glsl_input_pack(SHADER_BUFFER* buffer, const struct semantic* semantics_in,
-        IWineD3DPixelShader *iface, enum vertexprocessing_mode vertexprocessing)
+static void pshader_glsl_input_pack(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer,
+        const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps,
+        enum vertexprocessing_mode vertexprocessing)
 {
-   unsigned int i;
-   IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *) iface;
+    unsigned int i;
+    IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
+
+    for (i = 0; i < MAX_REG_INPUT; ++i)
+    {
+        DWORD usage, usage_idx;
+        char reg_mask[6];
 
-   for (i = 0; i < MAX_REG_INPUT; i++) {
+        /* Unused */
+        if (!reg_maps->packed_input[i]) continue;
 
-       DWORD usage_token = semantics_in[i].usage;
-       DWORD register_token = semantics_in[i].reg;
-       DWORD usage, usage_idx;
-       char reg_mask[6];
+        usage = semantics_in[i].usage;
+        usage_idx = semantics_in[i].usage_idx;
+        shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask);
 
-       /* Uninitialized */
-       if (!usage_token) continue;
-       usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-       usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-       shader_glsl_get_write_mask(register_token, reg_mask);
+        switch (usage)
+        {
+            case WINED3DDECLUSAGE_TEXCOORD:
+                if (usage_idx < 8 && vertexprocessing == pretransformed)
+                    shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
+                            This->input_reg_map[i], reg_mask, usage_idx, reg_mask);
+                else
+                    shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                            This->input_reg_map[i], reg_mask, reg_mask);
+                break;
 
-       switch(usage) {
+            case WINED3DDECLUSAGE_COLOR:
+                if (usage_idx == 0)
+                    shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n",
+                            This->input_reg_map[i], reg_mask, reg_mask);
+                else if (usage_idx == 1)
+                    shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n",
+                            This->input_reg_map[i], reg_mask, reg_mask);
+                else
+                    shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                            This->input_reg_map[i], reg_mask, reg_mask);
+                break;
 
-           case WINED3DDECLUSAGE_TEXCOORD:
-               if(usage_idx < 8 && vertexprocessing == pretransformed) {
-                   shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
-                                  This->input_reg_map[i], reg_mask, usage_idx, reg_mask);
-               } else {
-                   shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                                  This->input_reg_map[i], reg_mask, reg_mask);
-               }
-               break;
-
-           case WINED3DDECLUSAGE_COLOR:
-               if (usage_idx == 0)
-                   shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n",
-                       This->input_reg_map[i], reg_mask, reg_mask);
-               else if (usage_idx == 1)
-                   shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n",
-                       This->input_reg_map[i], reg_mask, reg_mask);
-               else
-                   shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                       This->input_reg_map[i], reg_mask, reg_mask);
-               break;
-
-           default:
-               shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
-                   This->input_reg_map[i], reg_mask, reg_mask);
+            default:
+                shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
+                        This->input_reg_map[i], reg_mask, reg_mask);
+                break;
         }
     }
 }
@@ -3081,12 +3128,11 @@ static void delete_glsl_program_entry(struct shader_glsl_priv *priv, const WineD
     HeapFree(GetProcessHeap(), 0, entry);
 }
 
-static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *semantics_in,
-        const struct semantic *semantics_out, const WineD3D_GL_Info *gl_info, const DWORD *map)
+static void handle_ps3_input(SHADER_BUFFER *buffer, const WineD3D_GL_Info *gl_info, const DWORD *map,
+        const struct wined3d_shader_semantic *semantics_in, const struct shader_reg_maps *reg_maps_in,
+        const struct wined3d_shader_semantic *semantics_out, const struct shader_reg_maps *reg_maps_out)
 {
     unsigned int i, j;
-    DWORD usage_token, usage_token_out;
-    DWORD register_token, register_token_out;
     DWORD usage, usage_idx, usage_out, usage_idx_out;
     DWORD *set;
     DWORD in_idx;
@@ -3103,8 +3149,7 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman
     }
 
     for(i = 0; i < MAX_REG_INPUT; i++) {
-        usage_token = semantics_in[i].usage;
-        if (!usage_token) continue;
+        if (!reg_maps_in->packed_input[i]) continue;
 
         in_idx = map[i];
         if (in_idx >= (in_count + 2)) {
@@ -3125,11 +3170,9 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman
             sprintf(destination, "IN[%u]", in_idx);
         }
 
-        register_token = semantics_in[i].reg;
-
-        usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-        usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-        set[map[i]] = shader_glsl_get_write_mask(register_token, reg_mask);
+        usage = semantics_in[i].usage;
+        usage_idx = semantics_in[i].usage_idx;
+        set[map[i]] = shader_glsl_get_write_mask(&semantics_in[i].reg, reg_mask);
 
         if(!semantics_out) {
             switch(usage) {
@@ -3167,13 +3210,11 @@ static void handle_ps3_input(SHADER_BUFFER *buffer, const struct semantic *seman
         } else {
             BOOL found = FALSE;
             for(j = 0; j < MAX_REG_OUTPUT; j++) {
-                usage_token_out = semantics_out[j].usage;
-                if (!usage_token_out) continue;
-                register_token_out = semantics_out[j].reg;
+                if (!reg_maps_out->packed_output[j]) continue;
 
-                usage_out = (usage_token_out & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-                usage_idx_out = (usage_token_out & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-                shader_glsl_get_write_mask(register_token_out, reg_mask_out);
+                usage_out = semantics_out[j].usage;
+                usage_idx_out = semantics_out[j].usage_idx;
+                shader_glsl_get_write_mask(&semantics_out[j].reg, reg_mask_out);
 
                 if(usage == usage_out &&
                    usage_idx == usage_idx_out) {
@@ -3244,11 +3285,9 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
     DWORD ps_major = ps ? WINED3DSHADER_VERSION_MAJOR(ps->baseShader.reg_maps.shader_version) : 0;
     unsigned int i;
     SHADER_BUFFER buffer;
-    DWORD usage_token;
-    DWORD register_token;
     DWORD usage, usage_idx, writemask;
     char reg_mask[6];
-    const struct semantic *semantics_out, *semantics_in;
+    const struct wined3d_shader_semantic *semantics_out;
 
     shader_buffer_init(&buffer);
 
@@ -3278,13 +3317,11 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
 
         shader_addline(&buffer, "void order_ps_input(in vec4 OUT[%u]) {\n", MAX_REG_OUTPUT);
         for(i = 0; i < MAX_REG_OUTPUT; i++) {
-            usage_token = semantics_out[i].usage;
-            if (!usage_token) continue;
-            register_token = semantics_out[i].reg;
+            if (!vs->baseShader.reg_maps.packed_output[i]) continue;
 
-            usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-            usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-            writemask = shader_glsl_get_write_mask(register_token, reg_mask);
+            usage = semantics_out[i].usage;
+            usage_idx = semantics_out[i].usage_idx;
+            writemask = shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask);
 
             switch(usage) {
                 case WINED3DDECLUSAGE_COLOR:
@@ -3326,7 +3363,6 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
 
     } else if(ps_major >= 3 && vs_major >= 3) {
         semantics_out = vs->semantics_out;
-        semantics_in = ps->semantics_in;
 
         /* This one is tricky: a 3.0 pixel shader reads from a 3.0 vertex shader */
         shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
@@ -3334,13 +3370,11 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
 
         /* First, sort out position and point size. Those are not passed to the pixel shader */
         for(i = 0; i < MAX_REG_OUTPUT; i++) {
-            usage_token = semantics_out[i].usage;
-            if (!usage_token) continue;
-            register_token = semantics_out[i].reg;
+            if (!vs->baseShader.reg_maps.packed_output[i]) continue;
 
-            usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-            usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
-            shader_glsl_get_write_mask(register_token, reg_mask);
+            usage = semantics_out[i].usage;
+            usage_idx = semantics_out[i].usage_idx;
+            shader_glsl_get_write_mask(&semantics_out[i].reg, reg_mask);
 
             switch(usage) {
                 case WINED3DDECLUSAGE_POSITION:
@@ -3357,19 +3391,18 @@ static GLhandleARB generate_param_reorder_function(IWineD3DVertexShader *vertexs
         }
 
         /* Then, fix the pixel shader input */
-        handle_ps3_input(&buffer, semantics_in, semantics_out, gl_info, ps->input_reg_map);
+        handle_ps3_input(&buffer, gl_info, ps->input_reg_map,
+                ps->semantics_in, &ps->baseShader.reg_maps, semantics_out, &vs->baseShader.reg_maps);
 
         shader_addline(&buffer, "}\n");
     } else if(ps_major >= 3 && vs_major < 3) {
-        semantics_in = ps->semantics_in;
-
         shader_addline(&buffer, "varying vec4 IN[%u];\n", GL_LIMITS(glsl_varyings) / 4);
         shader_addline(&buffer, "void order_ps_input() {\n");
         /* The vertex shader wrote to the builtin varyings. There is no need to figure out position and
          * point size, but we depend on the optimizers kindness to find out that the pixel shader doesn't
          * read gl_TexCoord and gl_ColorX, otherwise we'll run out of varyings
          */
-        handle_ps3_input(&buffer, semantics_in, NULL, gl_info, ps->input_reg_map);
+        handle_ps3_input(&buffer, gl_info, ps->input_reg_map, ps->semantics_in, &ps->baseShader.reg_maps, NULL, NULL);
         shader_addline(&buffer, "}\n");
     } else {
         ERR("Unexpected vertex and pixel shader version condition: vs: %d, ps: %d\n", vs_major, ps_major);
@@ -3557,14 +3590,14 @@ static void set_glsl_shader_program(IWineD3DDevice *iface, BOOL use_ps, BOOL use
         }
     }
 
-    if (use_ps && ps_compile_args.texrect_fixup) {
+    if (use_ps && ps_compile_args.np2_fixup) {
         char name[32];
         for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
-            if (ps_compile_args.texrect_fixup & (1 << i)) {
-                sprintf(name, "PsamplerRectFixup%u", i);
-                entry->rectFixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
+            if (ps_compile_args.np2_fixup & (1 << i)) {
+                sprintf(name, "PsamplerNP2Fixup%u", i);
+                entry->np2Fixup_location[i] = GL_EXTCALL(glGetUniformLocationARB(programId, name));
             } else {
-                entry->rectFixup_location[i] = -1;
+                entry->np2Fixup_location[i] = -1;
             }
         }
     }
@@ -3766,9 +3799,13 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
     if(pshader) {
         ps = (IWineD3DPixelShaderImpl *) This;
         if(ps->num_gl_shaders == 0) return;
+        if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
+            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
     } else {
         vs = (IWineD3DVertexShaderImpl *) This;
         if(vs->num_gl_shaders == 0) return;
+        if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
+            shader_glsl_select(This->baseShader.device, FALSE, FALSE);
     }
 
     linked_programs = &This->baseShader.linked_programs;
@@ -3960,7 +3997,7 @@ static GLuint shader_glsl_generate_pshader(IWineD3DPixelShader *iface, SHADER_BU
 
     /* Pack 3.0 inputs */
     if (reg_maps->shader_version >= WINED3DPS_VERSION(3,0) && args->vp_mode != vertexshader) {
-        pshader_glsl_input_pack(buffer, This->semantics_in, iface, args->vp_mode);
+        pshader_glsl_input_pack(iface, buffer, This->semantics_in, reg_maps, args->vp_mode);
     }
 
     /* Base Shader Body */
@@ -4107,7 +4144,8 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
     else
         pCaps->VertexShaderVersion = WINED3DVS_VERSION(3,0);
     TRACE_(d3d_caps)("Hardware vertex shader version %d.%d enabled (GLSL)\n", (pCaps->VertexShaderVersion >> 8) & 0xff, pCaps->VertexShaderVersion & 0xff);
-    pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
+    /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
+    pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
 
     /* Older DX9-class videocards (GeforceFX / Radeon >9500/X*00) only support pixel shader 2.0/2.0a/2.0b.
      * In OpenGL the extensions related to GLSL abstract lowlevel GL info away which is needed
@@ -4125,6 +4163,13 @@ static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, const WineD3D_GL_Info *
     else
         pCaps->PixelShaderVersion = WINED3DPS_VERSION(3,0);
 
+    /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
+     * In theory the texbem instruction may need one more shader constant too. But lets assume
+     * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
+     * and lets not take away a uniform needlessly from all other shaders.
+     */
+    pCaps->MaxPixelShaderConst = GL_LIMITS(pshader_constantsF) - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+
     /* FIXME: The following line is card dependent. -8.0 to 8.0 is the
      * Direct3D minimum requirement.
      *
@@ -4255,6 +4300,7 @@ const shader_backend_t glsl_shader_backend = {
     shader_glsl_update_float_vertex_constants,
     shader_glsl_update_float_pixel_constants,
     shader_glsl_load_constants,
+    shader_glsl_load_np2fixup_constants,
     shader_glsl_destroy,
     shader_glsl_alloc,
     shader_glsl_free,
index de609a7..d1701f5 100644 (file)
@@ -460,7 +460,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
 
     memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set */
     args->srgb_correction = stateblock->renderState[WINED3DRS_SRGBWRITEENABLE] ? 1 : 0;
-    args->texrect_fixup = 0;
+    args->np2_fixup = 0;
 
     for(i = 0; i < MAX_FRAGMENT_SAMPLERS; i++) {
         if(shader->baseShader.reg_maps.samplers[i] == 0) continue;
@@ -473,7 +473,7 @@ void find_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWineD3DStateBlockImp
 
         /* Flag samplers that need NP2 texcoord fixup. */
         if(!tex->baseTexture.pow2Matrix_identity) {
-            args->texrect_fixup |= (1 << i);
+            args->np2_fixup |= (1 << i);
         }
     }
     if (shader->baseShader.reg_maps.shader_version >= WINED3DPS_VERSION(3,0))
index 47a94a0..05e52b0 100644 (file)
@@ -3367,11 +3367,10 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
 
         /* Trigger shader constant reloading (for NP2 texcoord fixup)
          * Only do this if pshaders are used (note: fixup is currently only implemented in GLSL). */
-        if (!tex_impl->baseTexture.pow2Matrix_identity && use_ps(stateblock)) {
+        if (!tex_impl->baseTexture.pow2Matrix_identity) {
             IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice;
-            /* FIXME: add something like shader_load_rectfixup_consts to the backend to only reload the
-             * constants that are used for the fixup (and not the other ones too) */
-            d3ddevice->shader_backend->shader_load_constants((IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
+            d3ddevice->shader_backend->shader_load_np2fixup_constants(
+                (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
         }
     } else if(mapped_stage < GL_LIMITS(textures)) {
         if(sampler < stateblock->lowest_disabled_stage) {
@@ -4631,8 +4630,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
     if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
     } else {
-        IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
-        GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
+        struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData;
+        GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
     }
 }
 
index cbf5f97..1c9b5a8 100644 (file)
@@ -195,6 +195,7 @@ void stateblock_copy(
     Dest->vertexShader = This->vertexShader;
     Dest->streamIsUP = This->streamIsUP;
     Dest->pIndexData = This->pIndexData;
+    Dest->IndexFmt = This->IndexFmt;
     Dest->baseVertexIndex = This->baseVertexIndex;
     /* Dest->lights = This->lights; */
     Dest->clip_status = This->clip_status;
@@ -301,7 +302,7 @@ static ULONG  WINAPI IWineD3DStateBlockImpl_Release(IWineD3DStateBlock *iface) {
                 }
             }
         }
-        if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
+        if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
         if(This->vertexShader) IWineD3DVertexShader_Release(This->vertexShader);
         if(This->pixelShader) IWineD3DPixelShader_Release(This->pixelShader);
 
@@ -506,13 +507,15 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         if (This->changed.primitive_type) This->gl_primitive_type = targetStateBlock->gl_primitive_type;
 
         if (This->changed.indices && ((This->pIndexData != targetStateBlock->pIndexData)
-                        || (This->baseVertexIndex != targetStateBlock->baseVertexIndex))) {
+                        || (This->baseVertexIndex != targetStateBlock->baseVertexIndex)
+                        || (This->IndexFmt != targetStateBlock->IndexFmt))) {
             TRACE("Updating pIndexData to %p, baseVertexIndex to %d\n",
                     targetStateBlock->pIndexData, targetStateBlock->baseVertexIndex);
-            if(targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
-            if(This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
+            if(targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
+            if(This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
             This->pIndexData = targetStateBlock->pIndexData;
             This->baseVertexIndex = targetStateBlock->baseVertexIndex;
+            This->IndexFmt = targetStateBlock->IndexFmt;
         }
 
         if(This->changed.vertexDecl && This->vertexDecl != targetStateBlock->vertexDecl){
@@ -655,10 +658,12 @@ static HRESULT  WINAPI IWineD3DStateBlockImpl_Capture(IWineD3DStateBlock *iface)
         memcpy(This->samplerState, targetStateBlock->samplerState, sizeof(This->samplerState));
         This->scissorRect = targetStateBlock->scissorRect;
 
-        if(targetStateBlock->pIndexData != This->pIndexData) {
-            if (targetStateBlock->pIndexData) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
-            if (This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
+        if(targetStateBlock->pIndexData != This->pIndexData ||
+           targetStateBlock->IndexFmt != This->IndexFmt) {
+            if (targetStateBlock->pIndexData) IWineD3DBuffer_AddRef(targetStateBlock->pIndexData);
+            if (This->pIndexData) IWineD3DBuffer_Release(This->pIndexData);
             This->pIndexData = targetStateBlock->pIndexData;
+            This->IndexFmt = targetStateBlock->IndexFmt;
         }
         for(i = 0; i < MAX_STREAMS; i++) {
             if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
@@ -841,7 +846,7 @@ should really perform a delta so that only the changes get updated*/
         }
 
         if (This->changed.indices) {
-            IWineD3DDevice_SetIndices(pDevice, This->pIndexData);
+            IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->IndexFmt);
             IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
         }
 
@@ -1023,7 +1028,7 @@ should really perform a delta so that only the changes get updated*/
             IWineD3DDevice_SetTransform(pDevice, i, &This->transforms[i]);
         }
         This->wineD3DDevice->updateStateBlock->gl_primitive_type = This->gl_primitive_type;
-        IWineD3DDevice_SetIndices(pDevice, This->pIndexData);
+        IWineD3DDevice_SetIndices(pDevice, This->pIndexData, This->IndexFmt);
         IWineD3DDevice_SetBaseVertexIndex(pDevice, This->baseVertexIndex);
         IWineD3DDevice_SetVertexDeclaration(pDevice, This->vertexDecl);
         IWineD3DDevice_SetMaterial(pDevice, &This->material);
index 02f5255..7eb3d59 100644 (file)
@@ -996,8 +996,6 @@ const char* debug_d3dresourcetype(WINED3DRESOURCETYPE res) {
     RES_TO_STR(WINED3DRTYPE_TEXTURE);
     RES_TO_STR(WINED3DRTYPE_VOLUMETEXTURE);
     RES_TO_STR(WINED3DRTYPE_CUBETEXTURE);
-    RES_TO_STR(WINED3DRTYPE_VERTEXBUFFER);
-    RES_TO_STR(WINED3DRTYPE_INDEXBUFFER);
     RES_TO_STR(WINED3DRTYPE_BUFFER);
 #undef  RES_TO_STR
   default:
index 402d5bd..fdd8cd8 100644 (file)
@@ -174,16 +174,15 @@ static void vshader_set_input(
     unsigned int regnum,
     BYTE usage, BYTE usage_idx) {
 
-    /* Fake usage: set reserved bit, usage, usage_idx */
-    DWORD usage_token = (0x1 << 31) |
-        (usage << WINED3DSP_DCL_USAGE_SHIFT) | (usage_idx << WINED3DSP_DCL_USAGEINDEX_SHIFT);
-
-    /* Fake register; set reserved bit, regnum, type: input, wmask: all */
-    DWORD reg_token = (0x1 << 31) |
-        WINED3DSP_WRITEMASK_ALL | (WINED3DSPR_INPUT << WINED3DSP_REGTYPE_SHIFT) | regnum;
-
-    This->semantics_in[regnum].usage = usage_token;
-    This->semantics_in[regnum].reg = reg_token;
+    This->semantics_in[regnum].usage = usage;
+    This->semantics_in[regnum].usage_idx = usage_idx;
+    This->semantics_in[regnum].reg.register_type = WINED3DSPR_INPUT;
+    This->semantics_in[regnum].reg.register_idx = regnum;
+    This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL;
+    This->semantics_in[regnum].reg.modifiers = 0;
+    This->semantics_in[regnum].reg.shift = 0;
+    This->semantics_in[regnum].reg.has_rel_addr = FALSE;
+    This->semantics_in[regnum].reg.addr_token = 0;
 }
 
 static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) {
@@ -204,11 +203,11 @@ BOOL vshader_get_input(
     int i;
 
     for (i = 0; i < MAX_ATTRIBS; i++) {
-        DWORD usage_token = This->semantics_in[i].usage;
-        DWORD usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT;
-        DWORD usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT;
+        if (!This->baseShader.reg_maps.attributes[i]) continue;
 
-        if (usage_token && match_usage(usage, usage_idx, usage_req, usage_idx_req)) {
+        if (match_usage(This->semantics_in[i].usage,
+                This->semantics_in[i].usage_idx, usage_req, usage_idx_req))
+        {
             *regnum = i;
             return TRUE;
         }
index 2b5cbab..cc76035 100644 (file)
@@ -3320,8 +3320,13 @@ typedef enum _GL_Cards {
   CARD_NVIDIA_GEFORCE_8600GT      = 0x0402,
   CARD_NVIDIA_GEFORCE_8600MGT     = 0x0407,
   CARD_NVIDIA_GEFORCE_8800GTS     = 0x0193,
+  CARD_NVIDIA_GEFORCE_9200        = 0x086d,
+  CARD_NVIDIA_GEFORCE_9400GT      = 0x042c,
+  CARD_NVIDIA_GEFORCE_9500GT      = 0x0640,
   CARD_NVIDIA_GEFORCE_9600GT      = 0x0622,
   CARD_NVIDIA_GEFORCE_9800GT      = 0x0614,
+  CARD_NVIDIA_GEFORCE_GTX260      = 0x05e2,
+  CARD_NVIDIA_GEFORCE_GTX275      = 0x05e6,
   CARD_NVIDIA_GEFORCE_GTX280      = 0x05e1,
 
   CARD_INTEL_845G                 = 0x2562,
@@ -3903,6 +3908,7 @@ typedef struct _WineD3D_GL_Info {
   UINT   vidmem;
   DWORD  driver_version;
   DWORD  driver_version_hipart;
+  CHAR   driver_description[255];
   CHAR   gl_renderer[255];
   /**
    * CAPS Constants
index 8f27f2d..566e2a6 100644 (file)
@@ -408,12 +408,6 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_TABLE_SIZE
 };
 
-typedef struct semantic
-{
-    DWORD usage;
-    DWORD reg;
-} semantic;
-
 typedef struct shader_reg_maps
 {
     DWORD shader_version;
@@ -454,8 +448,12 @@ typedef struct SHADER_OPCODE
 
 struct wined3d_shader_dst_param
 {
+    WINED3DSHADER_PARAM_REGISTER_TYPE register_type;
     UINT register_idx;
-    DWORD token;
+    DWORD write_mask;
+    DWORD modifiers;
+    DWORD shift;
+    BOOL has_rel_addr;
     DWORD addr_token;
 };
 
@@ -475,6 +473,13 @@ struct wined3d_shader_instruction
     UINT src_count;
 };
 
+struct wined3d_shader_semantic
+{
+    WINED3DDECLUSAGE usage;
+    UINT usage_idx;
+    struct wined3d_shader_dst_param reg;
+};
+
 typedef void (*SHADER_HANDLER)(const struct wined3d_shader_instruction *);
 
 struct shader_caps {
@@ -483,6 +488,7 @@ struct shader_caps {
 
     DWORD               PixelShaderVersion;
     float               PixelShader1xMaxValue;
+    DWORD               MaxPixelShaderConst;
 
     WINED3DVSHADERCAPS2_0   VS20Caps;
     WINED3DPSHADERCAPS2_0   PS20Caps;
@@ -533,8 +539,8 @@ struct ps_compile_args {
     /* Projected textures(ps 1.0-1.3) */
     /* Texture types(2D, Cube, 3D) in ps 1.x */
     BOOL                        srgb_correction;
-    WORD                        texrect_fixup;
-    /* Bitmap for texture rect coord fixups (16 samplers max currently).
+    WORD                        np2_fixup;
+    /* Bitmap for NP2 texcoord fixups (16 samplers max currently).
        D3D9 has a limit of 16 samplers and the fixup is superfluous
        in D3D10 (unconditional NP2 support mandatory). */
 };
@@ -557,6 +563,7 @@ typedef struct {
     void (*shader_update_float_vertex_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_update_float_pixel_constants)(IWineD3DDevice *iface, UINT start, UINT count);
     void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, char useVS);
+    void (*shader_load_np2fixup_constants)(IWineD3DDevice *iface, char usePS, char useVS);
     void (*shader_destroy)(IWineD3DBaseShader *iface);
     HRESULT (*shader_alloc_private)(IWineD3DDevice *iface);
     void (*shader_free_private)(IWineD3DDevice *iface);
@@ -1212,6 +1219,7 @@ struct IWineD3DDeviceImpl
     const struct blit_shader *blitter;
 
     unsigned int max_ffp_textures, max_ffp_texture_stages;
+    DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
 
     WORD view_ident : 1;                /* true iff view matrix is identity */
     WORD untransformed : 1;
@@ -1403,24 +1411,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
 /* Tests show that the start address of resources is 32 byte aligned */
 #define RESOURCE_ALIGNMENT 32
 
-/*****************************************************************************
- * IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl)
- */
-typedef struct IWineD3DIndexBufferImpl
-{
-    /* IUnknown & WineD3DResource Information     */
-    const IWineD3DIndexBufferVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
-
-    GLuint                    vbo;
-    UINT                      dirtystart, dirtyend;
-    LONG                      lockcount;
-
-    /* WineD3DVertexBuffer specifics */
-} IWineD3DIndexBufferImpl;
-
-extern const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl;
-
 /*****************************************************************************
  * IWineD3DBaseTexture D3D- > openGL state map lookups
  */
@@ -1947,7 +1937,8 @@ struct IWineD3DStateBlockImpl
     UINT                      streamFlags[MAX_STREAMS + 1];     /*0 | WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA  */
 
     /* Indices */
-    IWineD3DIndexBuffer*      pIndexData;
+    IWineD3DBuffer*           pIndexData;
+    WINED3DFORMAT             IndexFmt;
     INT                       baseVertexIndex;
     INT                       loadBaseVertexIndex; /* non-indexed drawing needs 0 here, indexed baseVertexIndex */
 
@@ -2092,6 +2083,7 @@ enum wined3d_buffer_conversion_type
 #define WINED3D_BUFFER_DIRTY        0x02    /* Buffer data has been modified */
 #define WINED3D_BUFFER_HASDESC      0x04    /* A vertex description has been found */
 #define WINED3D_BUFFER_CREATEBO     0x08    /* Attempt to create a buffer object next PreLoad */
+#define WINED3D_BUFFER_DOUBLEBUFFER 0x10    /* Use a vbo and local allocated memory */
 
 struct wined3d_buffer
 {
@@ -2102,6 +2094,7 @@ struct wined3d_buffer
 
     GLuint buffer_object;
     GLenum buffer_object_usage;
+    GLenum buffer_type_hint;
     UINT buffer_object_size;
     LONG bind_count;
     DWORD flags;
@@ -2110,9 +2103,6 @@ struct wined3d_buffer
     UINT dirty_end;
     LONG lock_count;
 
-    /* legacy vertex buffers */
-    DWORD fvf;
-
     /* conversion stuff */
     UINT conversion_count;
     UINT draw_count;
@@ -2125,6 +2115,7 @@ struct wined3d_buffer
 
 extern const IWineD3DBufferVtbl wined3d_buffer_vtbl;
 const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object);
+const BYTE *buffer_get_sysmem(struct wined3d_buffer *This);
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
@@ -2357,7 +2348,8 @@ void shader_buffer_init(struct SHADER_BUFFER *buffer);
 void shader_buffer_free(struct SHADER_BUFFER *buffer);
 void shader_cleanup(IWineD3DBaseShader *iface);
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, struct shader_reg_maps *reg_maps,
-        struct semantic *semantics_in, struct semantic *semantics_out, const DWORD *byte_code);
+        struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out,
+        const DWORD *byte_code);
 void shader_init(struct IWineD3DBaseShaderClass *shader,
         IWineD3DDevice *device, const SHADER_OPCODE *instruction_table);
 void shader_trace_init(const DWORD *byte_code, const SHADER_OPCODE *opcode_table);
@@ -2386,16 +2378,13 @@ static inline BOOL shader_is_comment(DWORD token) {
     return WINED3DSIO_COMMENT == (token & WINED3DSI_OPCODE_MASK);
 }
 
-static inline BOOL shader_is_scalar(DWORD param) {
-    DWORD reg_type = shader_get_regtype(param);
-    DWORD reg_num;
-
-    switch (reg_type) {
+static inline BOOL shader_is_scalar(WINED3DSHADER_PARAM_REGISTER_TYPE register_type, UINT register_idx)
+{
+    switch (register_type)
+    {
         case WINED3DSPR_RASTOUT:
-            if ((param & WINED3DSP_REGNUM_MASK) != 0) {
-                /* oFog & oPts */
-                return TRUE;
-            }
+            /* oFog & oPts */
+            if (register_idx != 0) return TRUE;
             /* oPos */
             return FALSE;
 
@@ -2406,8 +2395,8 @@ static inline BOOL shader_is_scalar(DWORD param) {
             return TRUE;
 
         case WINED3DSPR_MISCTYPE:
-            reg_num = param & WINED3DSP_REGNUM_MASK;
-            switch(reg_num) {
+            switch(register_idx)
+            {
                 case 0: /* vPos */
                     return FALSE;
                 case 1: /* vFace */
@@ -2458,8 +2447,8 @@ typedef struct IWineD3DVertexShaderImpl {
     UINT                        num_gl_shaders, shader_array_size;
 
     /* Vertex shader input and output semantics */
-    semantic semantics_in [MAX_ATTRIBS];
-    semantic semantics_out [MAX_REG_OUTPUT];
+    struct wined3d_shader_semantic semantics_in[MAX_ATTRIBS];
+    struct wined3d_shader_semantic semantics_out[MAX_REG_OUTPUT];
 
     UINT                       min_rel_offset, max_rel_offset;
     UINT                       rel_offset;
@@ -2493,7 +2482,7 @@ typedef struct IWineD3DPixelShaderImpl {
     IUnknown                   *parent;
 
     /* Pixel shader input semantics */
-    semantic semantics_in [MAX_REG_INPUT];
+    struct wined3d_shader_semantic semantics_in[MAX_REG_INPUT];
     DWORD                 input_reg_map[MAX_REG_INPUT];
     BOOL                  input_reg_used[MAX_REG_INPUT];
     int                         declared_in_count;
index 604781b..b8691a7 100644 (file)
@@ -766,12 +766,10 @@ typedef enum _WINED3DRESOURCETYPE
     WINED3DRTYPE_TEXTURE                    = 3,
     WINED3DRTYPE_VOLUMETEXTURE              = 4,
     WINED3DRTYPE_CUBETEXTURE                = 5,
-    WINED3DRTYPE_VERTEXBUFFER               = 6,
-    WINED3DRTYPE_INDEXBUFFER                = 7,
-    WINED3DRTYPE_BUFFER                     = 8,
+    WINED3DRTYPE_BUFFER                     = 6,
     WINED3DRTYPE_FORCE_DWORD                = 0x7fffffff
 } WINED3DRESOURCETYPE;
-const UINT WINED3DRTYPECOUNT                = WINED3DRTYPE_INDEXBUFFER + 1;
+const UINT WINED3DRTYPECOUNT                = WINED3DRTYPE_BUFFER + 1;
 
 typedef enum _WINED3DPOOL
 {
@@ -1864,24 +1862,13 @@ typedef struct WINED3DDEVINFO_VCACHE
                            non user modifiable (only valid if OptMethod==1) */
 } WINED3DDEVINFO_VCACHE;
 
-typedef struct _WINED3DVERTEXBUFFER_DESC
+typedef struct _WINED3DBUFFER_DESC
 {
-    WINED3DFORMAT Format;
-    WINED3DRESOURCETYPE Type;
-    DWORD Usage;
-    WINED3DPOOL Pool;
-    UINT Size;
-    DWORD FVF;
-} WINED3DVERTEXBUFFER_DESC;
-
-typedef struct _WINED3DINDEXBUFFER_DESC
-{
-    WINED3DFORMAT Format;
     WINED3DRESOURCETYPE Type;
     DWORD Usage;
     WINED3DPOOL Pool;
     UINT Size;
-} WINED3DINDEXBUFFER_DESC;
+} WINED3DBUFFER_DESC;
 
 typedef struct glDescriptor
 {
@@ -2350,26 +2337,6 @@ interface IWineD3DRendertargetView : IWineD3DBase
     );
 }
 
-[
-    object,
-    local,
-    uuid(3a02a54e-6f30-11d9-c687-00046142c14f)
-]
-interface IWineD3DIndexBuffer : IWineD3DResource
-{
-    HRESULT Lock(
-        [in] UINT offset,
-        [in] UINT size,
-        [out] BYTE **data,
-        [in] DWORD flags
-    );
-    HRESULT Unlock(
-    );
-    HRESULT GetDesc(
-        [out] WINED3DINDEXBUFFER_DESC *desc
-    );
-}
-
 [
     object,
     local,
@@ -2844,7 +2811,7 @@ interface IWineD3DBuffer : IWineD3DResource
     HRESULT Unmap(
     );
     HRESULT GetDesc(
-        [out] WINED3DVERTEXBUFFER_DESC *desc
+        [out] WINED3DBUFFER_DESC *desc
     );
 }
 
@@ -2925,9 +2892,8 @@ interface IWineD3DDevice : IWineD3DBase
     HRESULT CreateIndexBuffer(
         [in] UINT length,
         [in] DWORD usage,
-        [in] WINED3DFORMAT format,
         [in] WINED3DPOOL pool,
-        [out] IWineD3DIndexBuffer **index_buffer,
+        [out] IWineD3DBuffer **index_buffer,
         [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
@@ -3150,10 +3116,11 @@ interface IWineD3DDevice : IWineD3DBase
         [out] WINED3DGAMMARAMP *ramp
     );
     HRESULT SetIndices(
-        [in] IWineD3DIndexBuffer *index_buffer
+        [in] IWineD3DBuffer *index_buffer,
+        [in] WINED3DFORMAT format
     );
     HRESULT GetIndices(
-        [out] IWineD3DIndexBuffer **index_buffer
+        [out] IWineD3DBuffer **index_buffer
     );
     HRESULT SetBaseVertexIndex(
         [in] INT base_index
@@ -3380,7 +3347,8 @@ interface IWineD3DDevice : IWineD3DBase
         [in] UINT vertex_count,
         [in] IWineD3DBuffer *dest_buffer,
         [in] IWineD3DVertexDeclaration *declaration,
-        [in] DWORD flags
+        [in] DWORD flags,
+        [in] DWORD DestFVF
     );
     HRESULT BeginStateBlock(
     );