wined3d: Merge IWineD3DVertexBuffer with IWineD3DBuffer.

That still leaves IWineD3DIndexBuffer, but that code is also mostly similar,
except for the conversion code (which will be unused there).
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 7092690..9878a1f 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -320,7 +320,7 @@
     LONG                              ref;
 
     /* IDirect3DResource8 fields */
-    IWineD3DVertexBuffer             *wineD3DVertexBuffer;
+    IWineD3DBuffer *wineD3DVertexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE8                 parentDevice;
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index cad9fef..33edbe8 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -2262,7 +2262,7 @@
 
 static HRESULT WINAPI IDirect3DDevice8Impl_GetStreamSource(LPDIRECT3DDEVICE8 iface, UINT StreamNumber,IDirect3DVertexBuffer8** pStream,UINT* pStride) {
     IDirect3DDevice8Impl *This = (IDirect3DDevice8Impl *)iface;
-    IWineD3DVertexBuffer *retStream = NULL;
+    IWineD3DBuffer *retStream = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n" , This);
@@ -2274,8 +2274,8 @@
     EnterCriticalSection(&d3d8_cs);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, 0 /* Offset in bytes */, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
-        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
-        IWineD3DVertexBuffer_Release(retStream);
+        IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
+        IWineD3DBuffer_Release(retStream);
     }else{
         if (rc != D3D_OK){
             FIXME("Call to GetStreamSource failed %p\n",  pStride);
diff --git a/dlls/d3d8/vertexbuffer.c b/dlls/d3d8/vertexbuffer.c
index 1132181..c26f00d 100644
--- a/dlls/d3d8/vertexbuffer.c
+++ b/dlls/d3d8/vertexbuffer.c
@@ -58,7 +58,7 @@
 
     if (ref == 0) {
         EnterCriticalSection(&d3d8_cs);
-        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         LeaveCriticalSection(&d3d8_cs);
         IUnknown_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -85,7 +85,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
+    hr = IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -96,7 +96,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -107,7 +107,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -118,7 +118,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
+    ret = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -129,7 +129,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    ret = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer);
+    ret = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return ret;
 }
@@ -139,7 +139,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
 }
 
@@ -149,7 +149,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    type = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer);
+    type = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return type;
 }
@@ -161,7 +161,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, ppbData, Flags);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -172,7 +172,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d8_cs);
     return hr;
 }
@@ -183,7 +183,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d8_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
     LeaveCriticalSection(&d3d8_cs);
 
     if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index c1ea36b..2a4b10d 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -345,7 +345,7 @@
     LONG                    ref;
 
     /* IDirect3DResource9 fields */
-    IWineD3DVertexBuffer   *wineD3DVertexBuffer;
+    IWineD3DBuffer *wineD3DVertexBuffer;
 
     /* Parent reference */
     LPDIRECT3DDEVICE9EX       parentDevice;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index bb5303e..57d3e15 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -470,7 +470,7 @@
             break;
 
         case WINED3DRTYPE_VERTEXBUFFER:
-            IWineD3DVertexBuffer_GetDesc((IWineD3DVertexBuffer *) resource, &vertex_desc);
+            IWineD3DBuffer_GetDesc((IWineD3DBuffer *)resource, &vertex_desc);
             pool = vertex_desc.Pool;
             break;
 
@@ -1576,7 +1576,7 @@
 
 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
-    IWineD3DVertexBuffer *retStream = NULL;
+    IWineD3DBuffer *retStream = NULL;
     HRESULT rc = D3D_OK;
 
     TRACE("(%p) Relay\n" , This);
@@ -1588,8 +1588,8 @@
     EnterCriticalSection(&d3d9_cs);
     rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
     if (rc == D3D_OK  && NULL != retStream) {
-        IWineD3DVertexBuffer_GetParent(retStream, (IUnknown **)pStream);
-        IWineD3DVertexBuffer_Release(retStream);
+        IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
+        IWineD3DBuffer_Release(retStream);
     }else{
         if (rc != D3D_OK){
             FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
diff --git a/dlls/d3d9/vertexbuffer.c b/dlls/d3d9/vertexbuffer.c
index b58001b..a831336 100644
--- a/dlls/d3d9/vertexbuffer.c
+++ b/dlls/d3d9/vertexbuffer.c
@@ -59,7 +59,7 @@
 
     if (ref == 0) {
         EnterCriticalSection(&d3d9_cs);
-        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         LeaveCriticalSection(&d3d9_cs);
         IDirect3DDevice9Ex_Release(This->parentDevice);
         HeapFree(GetProcessHeap(), 0, This);
@@ -82,7 +82,7 @@
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_SetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
     IDirect3DVertexBuffer9Impl *This = (IDirect3DVertexBuffer9Impl *)iface;
     TRACE("(%p) Relay\n", This);
-    return IWineD3DVertexBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
+    return IWineD3DBuffer_SetPrivateData(This->wineD3DVertexBuffer, refguid, pData, SizeOfData, Flags);
 }
 
 static HRESULT WINAPI IDirect3DVertexBuffer9Impl_GetPrivateData(LPDIRECT3DVERTEXBUFFER9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
@@ -91,7 +91,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
+    hr = IWineD3DBuffer_GetPrivateData(This->wineD3DVertexBuffer, refguid, pData, pSizeOfData);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -102,7 +102,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
+    hr = IWineD3DBuffer_FreePrivateData(This->wineD3DVertexBuffer, refguid);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -113,7 +113,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
+    hr = IWineD3DBuffer_SetPriority(This->wineD3DVertexBuffer, PriorityNew);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -124,7 +124,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetPriority(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_GetPriority(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -134,7 +134,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    IWineD3DVertexBuffer_PreLoad(This->wineD3DVertexBuffer);
+    IWineD3DBuffer_PreLoad(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return ;
 }
@@ -145,7 +145,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    ret = IWineD3DVertexBuffer_GetType(This->wineD3DVertexBuffer);
+    ret = IWineD3DBuffer_GetType(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return ret;
 }
@@ -157,7 +157,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, OffsetToLock, SizeToLock, (BYTE **)ppbData, Flags);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -168,7 +168,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&d3d9_cs);
     return hr;
 }
@@ -179,7 +179,7 @@
     TRACE("(%p) Relay\n", This);
 
     EnterCriticalSection(&d3d9_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *) pDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, (WINED3DVERTEXBUFFER_DESC *)pDesc);
     LeaveCriticalSection(&d3d9_cs);
 
     if (SUCCEEDED(hr)) pDesc->Format = d3dformat_from_wined3dformat(pDesc->Format);
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 27261a1..f5dc251 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -681,7 +681,7 @@
     LONG                 ref;
 
     /*** WineD3D and ddraw links ***/
-    IWineD3DVertexBuffer *wineD3DVertexBuffer;
+    IWineD3DBuffer *wineD3DVertexBuffer;
     IWineD3DVertexDeclaration *wineD3DVertexDeclaration;
     IDirectDrawImpl *ddraw;
 
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index e17cf03..4d642e5 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -4117,8 +4117,7 @@
 
     /* Get the FVF of the vertex buffer, and its stride */
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
-                                      &Desc);
+    hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc);
     if(hr != D3D_OK)
     {
         ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
@@ -4247,8 +4246,7 @@
 
     EnterCriticalSection(&ddraw_cs);
     /* Get the FVF of the vertex buffer, and its stride */
-    hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
-                                      &Desc);
+    hr = IWineD3DBuffer_GetDesc(vb->wineD3DVertexBuffer, &Desc);
     if(hr != D3D_OK)
     {
         ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c
index f9e06f7..2a051d0 100644
--- a/dlls/ddraw/direct3d.c
+++ b/dlls/ddraw/direct3d.c
@@ -1043,7 +1043,7 @@
     if(!object->wineD3DVertexDeclaration)
     {
         ERR("Cannot find the vertex declaration for fvf %08x\n", Desc->dwFVF);
-        IWineD3DVertexBuffer_Release(object->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(object->wineD3DVertexBuffer);
         HeapFree(GetProcessHeap(), 0, object);
         LeaveCriticalSection(&ddraw_cs);
         return DDERR_INVALIDPARAMS;
diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c
index 18fe93e..277591c 100644
--- a/dlls/ddraw/vertexbuffer.c
+++ b/dlls/ddraw/vertexbuffer.c
@@ -159,7 +159,7 @@
 
     if (ref == 0)
     {
-        IWineD3DVertexBuffer *curVB = NULL;
+        IWineD3DBuffer *curVB = NULL;
         UINT offset, stride;
 
         EnterCriticalSection(&ddraw_cs);
@@ -182,11 +182,11 @@
         }
         if(curVB)
         {
-            IWineD3DVertexBuffer_Release(curVB); /* For the GetStreamSource */
+            IWineD3DBuffer_Release(curVB); /* For the GetStreamSource */
         }
 
         IWineD3DVertexDeclaration_Release(This->wineD3DVertexDeclaration);
-        IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer);
+        IWineD3DBuffer_Release(This->wineD3DVertexBuffer);
         LeaveCriticalSection(&ddraw_cs);
         HeapFree(GetProcessHeap(), 0, This);
 
@@ -242,8 +242,7 @@
     if(Size)
     {
         /* Get the size, for returning it, and for locking */
-        hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
-                                          &Desc);
+        hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &Desc);
         if(hr != D3D_OK)
         {
             ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr);
@@ -253,11 +252,8 @@
         *Size = Desc.Size;
     }
 
-    hr = IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer,
-                                   0 /* OffsetToLock */,
-                                   0 /* SizeToLock, 0 == Full lock */,
-                                   (BYTE **) Data,
-                                   Flags);
+    hr = IWineD3DBuffer_Map(This->wineD3DVertexBuffer, 0 /* OffsetToLock */,
+            0 /* SizeToLock, 0 == Full lock */, (BYTE **)Data, Flags);
     LeaveCriticalSection(&ddraw_cs);
     return hr;
 }
@@ -291,7 +287,7 @@
     TRACE("(%p)->()\n", This);
 
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer);
+    hr = IWineD3DBuffer_Unmap(This->wineD3DVertexBuffer);
     LeaveCriticalSection(&ddraw_cs);
 
     return hr;
@@ -376,8 +372,7 @@
                                       doClip);
     }
 
-    IWineD3DVertexBuffer_GetDesc(Src->wineD3DVertexBuffer,
-                                 &Desc);
+    IWineD3DBuffer_GetDesc(Src->wineD3DVertexBuffer, &Desc);
     IWineD3DDevice_SetStreamSource(D3D->wineD3DDevice,
                                    0, /* Stream No */
                                    Src->wineD3DVertexBuffer,
@@ -447,8 +442,7 @@
     if(!Desc) return DDERR_INVALIDPARAMS;
 
     EnterCriticalSection(&ddraw_cs);
-    hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer,
-                                      &WDesc);
+    hr = IWineD3DBuffer_GetDesc(This->wineD3DVertexBuffer, &WDesc);
     if(hr != D3D_OK)
     {
         ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08x\n", This, hr);
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 16c9a5d..cd4952d 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -34,348 +34,106 @@
 #define VB_MAXDECLCHANGES     100     /* After that number we stop converting */
 #define VB_RESETDECLCHANGE    1000    /* Reset the changecount after that number of draws */
 
-/* IUnknown methods */
-
-static HRESULT STDMETHODCALLTYPE buffer_QueryInterface(IWineD3DBuffer *iface,
-        REFIID riid, void **object)
+static void buffer_create_buffer_object(struct wined3d_buffer *This)
 {
-    TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
+    GLenum error, gl_usage;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
 
-    if (IsEqualGUID(riid, &IID_IWineD3DBuffer)
-            || IsEqualGUID(riid, &IID_IWineD3DResource)
-            || IsEqualGUID(riid, &IID_IWineD3DBase)
-            || IsEqualGUID(riid, &IID_IUnknown))
+    TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n",
+            This, debug_d3dusage(This->resource.usage));
+
+    /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
+    ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
+    ENTER_GL();
+
+    /* Make sure that the gl error is cleared. Do not use checkGLcall
+    * here because checkGLcall just prints a fixme and continues. However,
+    * if an error during VBO creation occurs we can fall back to non-vbo operation
+    * with full functionality(but performance loss)
+    */
+    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.
+    */
+
+    GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
+    error = glGetError();
+    if (!This->buffer_object || error != GL_NO_ERROR)
     {
-        IUnknown_AddRef(iface);
-        *object = iface;
-        return S_OK;
+        ERR("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error);
+        goto fail;
     }
 
-    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
-
-    *object = NULL;
-
-    return E_NOINTERFACE;
-}
-
-static ULONG STDMETHODCALLTYPE buffer_AddRef(IWineD3DBuffer *iface)
-{
-    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
-    ULONG refcount = InterlockedIncrement(&This->resource.ref);
-
-    TRACE("%p increasing refcount to %u\n", This, refcount);
-
-    return refcount;
-}
-
-static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
-{
-    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
-    ULONG refcount = InterlockedDecrement(&This->resource.ref);
-
-    TRACE("%p decreasing refcount to %u\n", This, refcount);
-
-    if (!refcount)
+    GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
+    error = glGetError();
+    if (error != GL_NO_ERROR)
     {
-        resource_cleanup((IWineD3DResource *)iface);
-        HeapFree(GetProcessHeap(), 0, This);
+        ERR("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error);
+        goto fail;
     }
 
-    return refcount;
-}
-
-/* IWineD3DBase methods */
-
-static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknown **parent)
-{
-    return resource_get_parent((IWineD3DResource *)iface, parent);
-}
-
-/* IWineD3DResource methods */
-
-static HRESULT STDMETHODCALLTYPE buffer_GetDevice(IWineD3DBuffer *iface, IWineD3DDevice **device)
-{
-    return resource_get_device((IWineD3DResource *)iface, device);
-}
-
-static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *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 buffer_GetPrivateData(IWineD3DBuffer *iface,
-        REFGUID guid, void *data, DWORD *data_size)
-{
-    return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size);
-}
-
-static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid)
-{
-    return resource_free_private_data((IWineD3DResource *)iface, guid);
-}
-
-static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority)
-{
-    return resource_set_priority((IWineD3DResource *)iface, priority);
-}
-
-static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface)
-{
-    return resource_get_priority((IWineD3DResource *)iface);
-}
-
-static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
-{
-    TRACE("iface %p\n", iface);
-}
-
-static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
-{
-    TRACE("iface %p\n", iface);
-}
-
-static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface)
-{
-    return resource_get_type((IWineD3DResource *)iface);
-}
-
-const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
-{
-    /* IUnknown methods */
-    buffer_QueryInterface,
-    buffer_AddRef,
-    buffer_Release,
-    /* IWineD3DBase methods */
-    buffer_GetParent,
-    /* IWineD3DResource methods */
-    buffer_GetDevice,
-    buffer_SetPrivateData,
-    buffer_GetPrivateData,
-    buffer_FreePrivateData,
-    buffer_SetPriority,
-    buffer_GetPriority,
-    buffer_PreLoad,
-    buffer_UnLoad,
-    buffer_GetType,
-};
-
-/* IUnknown methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_QueryInterface(IWineD3DVertexBuffer *iface,
-        REFIID riid, void **object)
-{
-    TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
-
-    if (IsEqualGUID(riid, &IID_IWineD3DVertexBuffer)
-            || IsEqualGUID(riid, &IID_IWineD3DResource)
-            || IsEqualGUID(riid, &IID_IWineD3DBase)
-            || IsEqualGUID(riid, &IID_IUnknown))
+    /* Don't use static, because dx apps tend to update the buffer
+    * quite often even if they specify 0 usage. Because we always keep the local copy
+    * we never read from the vbo and can create a write only opengl buffer.
+    */
+    switch(This->resource.usage & (WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC))
     {
-        IUnknown_AddRef(iface);
-        *object = iface;
-        return S_OK;
+        case WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC:
+        case WINED3DUSAGE_DYNAMIC:
+            TRACE("Gl usage = GL_STREAM_DRAW\n");
+            gl_usage = GL_STREAM_DRAW_ARB;
+            break;
+
+        case WINED3DUSAGE_WRITEONLY:
+        default:
+            TRACE("Gl usage = GL_DYNAMIC_DRAW\n");
+            gl_usage = GL_DYNAMIC_DRAW_ARB;
+            break;
     }
 
-    WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
-
-    *object = NULL;
-
-    return E_NOINTERFACE;
-}
-
-static ULONG STDMETHODCALLTYPE IWineD3DVertexBufferImpl_AddRef(IWineD3DVertexBuffer *iface)
-{
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
-    ULONG refcount = InterlockedIncrement(&This->resource.ref);
-
-    TRACE("%p increasing refcount to %u\n", This, refcount);
-
-    return refcount;
-}
-
-static ULONG STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Release(IWineD3DVertexBuffer *iface)
-{
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
-    ULONG refcount = InterlockedDecrement(&This->resource.ref);
-
-    TRACE("%p decreasing refcount to %u\n", This, refcount);
-
-    if (!refcount)
+    /* 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));
+    error = glGetError();
+    if (error != GL_NO_ERROR)
     {
-        if (This->vbo)
-        {
-            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-
-            ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-            ENTER_GL();
-            GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
-            checkGLcall("glDeleteBuffersARB");
-            LEAVE_GL();
-        }
-
-        resource_cleanup((IWineD3DResource *)iface);
-        HeapFree(GetProcessHeap(), 0, This);
+        ERR("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error);
+        goto fail;
     }
 
-    return refcount;
+    LEAVE_GL();
+
+    This->buffer_object_size = This->resource.size;
+    This->buffer_object_usage = gl_usage;
+    This->dirty_start = 0;
+    This->dirty_end = This->resource.size;
+    This->flags |= WINED3D_BUFFER_DIRTY;
+
+    return;
+
+fail:
+    /* Clean up all vbo init, but continue because we can work without a vbo :-) */
+    ERR("Failed to create a vertex buffer object. Continuing, but performance issues may occur\n");
+    if (This->buffer_object) GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
+    This->buffer_object = 0;
+    LEAVE_GL();
+
+    return;
 }
 
-/* IWineD3DBase methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetParent(IWineD3DVertexBuffer *iface, IUnknown **parent)
-{
-    return resource_get_parent((IWineD3DResource *)iface, parent);
-}
-
-/* IWineD3DResource methods */
-
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetDevice(IWineD3DVertexBuffer *iface,
-        IWineD3DDevice **device)
-{
-    return resource_get_device((IWineD3DResource *)iface, device);
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_SetPrivateData(IWineD3DVertexBuffer *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 IWineD3DVertexBufferImpl_GetPrivateData(IWineD3DVertexBuffer *iface,
-        REFGUID guid, void *data, DWORD *data_size)
-{
-    return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size);
-}
-
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_FreePrivateData(IWineD3DVertexBuffer *iface, REFGUID guid)
-{
-    return resource_free_private_data((IWineD3DResource *)iface, guid);
-}
-
-static DWORD STDMETHODCALLTYPE IWineD3DVertexBufferImpl_SetPriority(IWineD3DVertexBuffer *iface, DWORD priority)
-{
-    return resource_set_priority((IWineD3DResource *)iface, priority);
-}
-
-static DWORD STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetPriority(IWineD3DVertexBuffer *iface)
-{
-    return resource_get_priority((IWineD3DResource *)iface);
-}
-
-static inline void fixup_d3dcolor(DWORD *pos)
-{
-    DWORD srcColor = *pos;
-
-    /* Color conversion like in drawStridedSlow. watch out for little endianity
-     * If we want that stuff to work on big endian machines too we have to consider more things
-     *
-     * 0xff000000: Alpha mask
-     * 0x00ff0000: Blue mask
-     * 0x0000ff00: Green mask
-     * 0x000000ff: Red mask
-     */
-    *pos = 0;
-    *pos |= (srcColor & 0xff00ff00)      ;   /* Alpha Green */
-    *pos |= (srcColor & 0x00ff0000) >> 16;   /* Red */
-    *pos |= (srcColor & 0x000000ff) << 16;   /* Blue */
-}
-
-static inline void fixup_transformed_pos(float *p)
-{
-    float x, y, z, w;
-
-    /* rhw conversion like in drawStridedSlow */
-    if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps)))
-    {
-        x = p[0];
-        y = p[1];
-        z = p[2];
-        w = 1.0;
-    }
-    else
-    {
-        w = 1.0 / p[3];
-        x = p[0] * w;
-        y = p[1] * w;
-        z = p[2] * w;
-    }
-    p[0] = x;
-    p[1] = y;
-    p[2] = z;
-    p[3] = w;
-}
-
-static DWORD *find_conversion_shift(IWineD3DVertexBufferImpl *This,
-        const WineDirect3DVertexStridedData *strided, DWORD stride)
-{
-    DWORD *ret, i, shift, j, type;
-    DWORD orig_type_size;
-
-    if (!stride)
-    {
-        TRACE("No shift\n");
-        return NULL;
-    }
-
-    This->conv_stride = stride;
-    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride);
-    for (i = 0; i < MAX_ATTRIBS; ++i)
-    {
-        if (strided->u.input[i].VBO != This->vbo) continue;
-
-        type = strided->u.input[i].dwType;
-        if (type == WINED3DDECLTYPE_FLOAT16_2)
-        {
-            shift = 4;
-        }
-        else if (type == WINED3DDECLTYPE_FLOAT16_4)
-        {
-            shift = 8;
-            /* Pre-shift the last 4 bytes in the FLOAT16_4 by 4 bytes - this makes FLOAT16_2 and FLOAT16_4 conversions
-             * compatible
-             */
-            for (j = 4; j < 8; ++j)
-            {
-                ret[(DWORD_PTR)strided->u.input[i].lpData + j] += 4;
-            }
-        }
-        else
-        {
-            shift = 0;
-        }
-        This->conv_stride += shift;
-
-        if (shift)
-        {
-            orig_type_size = WINED3D_ATR_TYPESIZE(type) * WINED3D_ATR_SIZE(type);
-            for (j = (DWORD_PTR)strided->u.input[i].lpData + orig_type_size; j < stride; ++j)
-            {
-                ret[j] += shift;
-            }
-        }
-    }
-
-    if (TRACE_ON(d3d))
-    {
-        TRACE("Dumping conversion shift:\n");
-        for (i = 0; i < stride; ++i)
-        {
-            TRACE("[%d]", ret[i]);
-        }
-        TRACE("\n");
-    }
-
-    return ret;
-}
-
-static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This,
-        const enum vbo_conversion_type conv_type, const WineDirect3DStridedData *attrib,
-        DWORD *stride_this_run, const DWORD type)
+static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
+        const enum wined3d_buffer_conversion_type conversion_type,
+        const WineDirect3DStridedData *attrib, DWORD *stride_this_run, const DWORD type)
 {
     DWORD attrib_size;
     BOOL ret = FALSE;
-    int i;
+    unsigned int i;
     DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->streamNo];
     DWORD_PTR data;
 
@@ -403,8 +161,9 @@
              */
             TRACE("Reconverting because converted attributes occur, and the stride changed\n");
             This->stride = *stride_this_run;
-            HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conv_map);
-            This->conv_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->conv_map) * This->stride);
+            HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This->conversion_map);
+            This->conversion_map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                    sizeof(*This->conversion_map) * This->stride);
             ret = TRUE;
         }
     }
@@ -413,19 +172,19 @@
     attrib_size = WINED3D_ATR_SIZE(type) * WINED3D_ATR_TYPESIZE(type);
     for (i = 0; i < attrib_size; ++i)
     {
-        if (This->conv_map[data + i] != conv_type)
+        if (This->conversion_map[data + i] != conversion_type)
         {
             TRACE("Byte %ld in vertex changed\n", i + data);
-            TRACE("It was type %d, is %d now\n", This->conv_map[data + i], conv_type);
+            TRACE("It was type %d, is %d now\n", This->conversion_map[data + i], conversion_type);
             ret = TRUE;
-            This->conv_map[data + i] = conv_type;
+            This->conversion_map[data + i] = conversion_type;
         }
     }
 
     return ret;
 }
 
-static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This,
+static BOOL buffer_check_attribute(struct wined3d_buffer *This,
         const WineDirect3DStridedData *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position,
         const BOOL is_ffp_color, DWORD *stride_this_run, BOOL *float16_used)
 {
@@ -435,13 +194,13 @@
     /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
      * there, on nonexistent attribs the vbo is 0.
      */
-    if (attrib->VBO != This->vbo) return FALSE;
+    if (attrib->VBO != This->buffer_object) return FALSE;
 
     type = attrib->dwType;
     /* Look for newly appeared conversion */
     if (!GL_SUPPORT(NV_HALF_FLOAT) && (type == WINED3DDECLTYPE_FLOAT16_2 || type == WINED3DDECLTYPE_FLOAT16_4))
     {
-        ret = process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run, type);
+        ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run, type);
 
         if (is_ffp_position) FIXME("Test FLOAT16 fixed function processing positions\n");
         else if (is_ffp_color) FIXME("test FLOAT16 fixed function processing colors\n");
@@ -449,34 +208,100 @@
     }
     else if (check_d3dcolor && type == WINED3DDECLTYPE_D3DCOLOR)
     {
-        ret = process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run, WINED3DDECLTYPE_D3DCOLOR);
+        ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR,
+                attrib, stride_this_run, WINED3DDECLTYPE_D3DCOLOR);
 
         if (!is_ffp_color) FIXME("Test for non-color fixed function D3DCOLOR type\n");
     }
     else if (is_ffp_position && type == WINED3DDECLTYPE_FLOAT4)
     {
-        ret = process_converted_attribute(This, CONV_POSITIONT, attrib, stride_this_run, WINED3DDECLTYPE_FLOAT4);
+        ret = buffer_process_converted_attribute(This, CONV_POSITIONT,
+                attrib, stride_this_run, WINED3DDECLTYPE_FLOAT4);
     }
-    else if (This->conv_map)
+    else if (This->conversion_map)
     {
-        ret = process_converted_attribute(This, CONV_NONE, attrib, stride_this_run, type);
+        ret = buffer_process_converted_attribute(This, CONV_NONE,
+                attrib, stride_this_run, type);
     }
 
     return ret;
 }
 
-static inline BOOL IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *This)
+static UINT *find_conversion_shift(struct wined3d_buffer *This,
+        const WineDirect3DVertexStridedData *strided, UINT stride)
+{
+    UINT *ret, i, j, shift, orig_type_size;
+    DWORD type;
+
+    if (!stride)
+    {
+        TRACE("No shift\n");
+        return NULL;
+    }
+
+    This->conversion_stride = stride;
+    ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride);
+    for (i = 0; i < MAX_ATTRIBS; ++i)
+    {
+        if (strided->u.input[i].VBO != This->buffer_object) continue;
+
+        type = strided->u.input[i].dwType;
+        if (type == WINED3DDECLTYPE_FLOAT16_2)
+        {
+            shift = 4;
+        }
+        else if (type == WINED3DDECLTYPE_FLOAT16_4)
+        {
+            shift = 8;
+            /* Pre-shift the last 4 bytes in the FLOAT16_4 by 4 bytes - this makes FLOAT16_2 and FLOAT16_4 conversions
+             * compatible
+             */
+            for (j = 4; j < 8; ++j)
+            {
+                ret[(DWORD_PTR)strided->u.input[i].lpData + j] += 4;
+            }
+        }
+        else
+        {
+            shift = 0;
+        }
+        This->conversion_stride += shift;
+
+        if (shift)
+        {
+            orig_type_size = WINED3D_ATR_TYPESIZE(type) * WINED3D_ATR_SIZE(type);
+            for (j = (DWORD_PTR)strided->u.input[i].lpData + orig_type_size; j < stride; ++j)
+            {
+                ret[j] += shift;
+            }
+        }
+    }
+
+    if (TRACE_ON(d3d))
+    {
+        TRACE("Dumping conversion shift:\n");
+        for (i = 0; i < stride; ++i)
+        {
+            TRACE("[%d]", ret[i]);
+        }
+        TRACE("\n");
+    }
+
+    return ret;
+}
+
+static BOOL buffer_find_decl(struct wined3d_buffer *This)
 {
     IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BOOL ret = FALSE;
-    int i;
-    DWORD stride_this_run = 0;
+    UINT stride_this_run = 0;
     BOOL float16_used = FALSE;
+    BOOL ret = FALSE;
+    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.
      */
-    if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->Flags & VBFLAG_HASDESC) return FALSE;
+    if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->flags & WINED3D_BUFFER_HASDESC) return FALSE;
 
     TRACE("Finding vertex buffer conversion information\n");
     /* Certain declaration types need some fixups before we can pass them to
@@ -528,15 +353,15 @@
          */
         if (!((IWineD3DVertexDeclarationImpl *) device->stateBlock->vertexDecl)->half_float_conv_needed)
         {
-            if (This->conv_map)
+            if (This->conversion_map)
             {
                 TRACE("Now using shaders without conversion, but conversion used before\n");
-                HeapFree(GetProcessHeap(), 0, This->conv_map);
-                HeapFree(GetProcessHeap(), 0, This->conv_shift);
-                This->conv_map = NULL;
+                HeapFree(GetProcessHeap(), 0, This->conversion_map);
+                HeapFree(GetProcessHeap(), 0, This->conversion_shift);
+                This->conversion_map = NULL;
                 This->stride = 0;
-                This->conv_shift = NULL;
-                This->conv_stride = 0;
+                This->conversion_shift = NULL;
+                This->conversion_stride = 0;
                 return TRUE;
             }
             else
@@ -546,17 +371,17 @@
         }
         for (i = 0; i < MAX_ATTRIBS; ++i)
         {
-            ret = check_attribute(This, &device->strided_streams.u.input[i],
+            ret = buffer_check_attribute(This, &device->strided_streams.u.input[i],
                     FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
         }
 
         /* Recalculate the conversion shift map if the declaration has changed,
          * and we're using float16 conversion or used it on the last run
          */
-        if (ret && (float16_used || This->conv_map))
+        if (ret && (float16_used || This->conversion_map))
         {
-            HeapFree(GetProcessHeap(), 0, This->conv_shift);
-            This->conv_shift = find_conversion_shift(This, &device->strided_streams, This->stride);
+            HeapFree(GetProcessHeap(), 0, This->conversion_shift);
+            This->conversion_shift = find_conversion_shift(This, &device->strided_streams, This->stride);
         }
     }
     else
@@ -566,40 +391,40 @@
          * the attributes that our current fixed function pipeline implementation cares for.
          */
         BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA);
-        ret = check_attribute(This, &device->strided_streams.u.s.position,
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.position,
                 TRUE, TRUE,  FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.normal,
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.normal,
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.diffuse,
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.diffuse,
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.specular,
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.specular,
                 !support_d3dcolor, FALSE, TRUE,  &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[0],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[0],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[1],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[1],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[2],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[2],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[3],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[3],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[4],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[4],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[5],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[5],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[6],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[6],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
-        ret = check_attribute(This, &device->strided_streams.u.s.texCoords[7],
+        ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[7],
                 TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
 
         if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n");
     }
 
-    if (stride_this_run == 0 && This->conv_map)
+    if (stride_this_run == 0 && This->conversion_map)
     {
         /* Sanity test */
         if (!ret) ERR("no converted attributes found, old conversion map exists, and no declaration change?\n");
-        HeapFree(GetProcessHeap(), 0, This->conv_map);
-        This->conv_map = NULL;
+        HeapFree(GetProcessHeap(), 0, This->conversion_map);
+        This->conversion_map = NULL;
         This->stride = 0;
     }
 
@@ -608,132 +433,225 @@
     return ret;
 }
 
-static void check_vbo_size(IWineD3DVertexBufferImpl *This)
+static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
 {
-    DWORD size = This->conv_stride ? This->conv_stride * (This->resource.size / This->stride) : This->resource.size;
-    if (This->vbo_size != size)
+    UINT size = This->conversion_stride ?
+            This->conversion_stride * (This->resource.size / This->stride) : This->resource.size;
+    if (This->buffer_object_size != size)
     {
-        TRACE("Old size %d, creating new size %d\n", This->vbo_size, size);
+        TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size);
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
+        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->vbo_usage));
-        This->vbo_size = size;
+        GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->buffer_object_usage));
+        This->buffer_object_size = size;
         checkGLcall("glBufferDataARB");
         LEAVE_GL();
     }
 }
 
-static void CreateVBO(IWineD3DVertexBufferImpl *This)
+static inline void fixup_d3dcolor(DWORD *dst_color)
 {
-    GLenum error, glUsage;
-    DWORD vboUsage = This->resource.usage;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    DWORD src_color = *dst_color;
 
-    TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p  Usage(%s)\n",
-            This, debug_d3dusage(vboUsage));
-
-    /* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
-    ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-    ENTER_GL();
-
-    /* Make sure that the gl error is cleared. Do not use checkGLcall
-    * here because checkGLcall just prints a fixme and continues. However,
-    * if an error during VBO creation occurs we can fall back to non-vbo operation
-    * with full functionality(but performance loss)
-    */
-    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.
-    */
-
-    GL_EXTCALL(glGenBuffersARB(1, &This->vbo));
-    error = glGetError();
-    if (This->vbo == 0 || error != GL_NO_ERROR)
-    {
-        WARN("Failed to create a VBO with error %s (%#x)\n", debug_glerror(error), error);
-        goto error;
-    }
-
-    GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
-    error = glGetError();
-    if (error != GL_NO_ERROR)
-    {
-        WARN("Failed to bind the VBO with error %s (%#x)\n", debug_glerror(error), error);
-        goto error;
-    }
-
-    /* Don't use static, because dx apps tend to update the buffer
-    * quite often even if they specify 0 usage. Because we always keep the local copy
-    * we never read from the vbo and can create a write only opengl buffer.
-    */
-    switch(vboUsage & (WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC))
-    {
-        case WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC:
-        case WINED3DUSAGE_DYNAMIC:
-            TRACE("Gl usage = GL_STREAM_DRAW\n");
-            glUsage = GL_STREAM_DRAW_ARB;
-            break;
-
-        case WINED3DUSAGE_WRITEONLY:
-        default:
-            TRACE("Gl usage = GL_DYNAMIC_DRAW\n");
-            glUsage = GL_DYNAMIC_DRAW_ARB;
-            break;
-    }
-
-    /* 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, glUsage));
-    error = glGetError();
-    if (error != GL_NO_ERROR)
-    {
-        WARN("glBufferDataARB failed with error %s (%#x)\n", debug_glerror(error), error);
-        goto error;
-    }
-    This->vbo_size = This->resource.size;
-    This->vbo_usage = glUsage;
-    This->dirtystart = 0;
-    This->dirtyend = This->resource.size;
-    This->Flags |= VBFLAG_DIRTY;
-
-    LEAVE_GL();
-
-    return;
-
-error:
-    /* Clean up all vbo init, but continue because we can work without a vbo :-) */
-    FIXME("Failed to create a vertex buffer object. Continuing, but performance issues can occur\n");
-    if (This->vbo) GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
-    This->vbo = 0;
-    LEAVE_GL();
-
-    return;
+    /* Color conversion like in drawStridedSlow. watch out for little endianity
+     * If we want that stuff to work on big endian machines too we have to consider more things
+     *
+     * 0xff000000: Alpha mask
+     * 0x00ff0000: Blue mask
+     * 0x0000ff00: Green mask
+     * 0x000000ff: Red mask
+     */
+    *dst_color = 0;
+    *dst_color |= (src_color & 0xff00ff00);         /* Alpha Green */
+    *dst_color |= (src_color & 0x00ff0000) >> 16;   /* Red */
+    *dst_color |= (src_color & 0x000000ff) << 16;   /* Blue */
 }
 
-static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface)
+static inline void fixup_transformed_pos(float *p)
 {
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
-    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
-    BYTE *data;
-    UINT start = 0, end = 0, vertices;
-    BOOL declChanged = FALSE;
-    int i, j;
-    TRACE("(%p)->()\n", This);
+    float x, y, z, w;
 
-    if (!This->vbo)
+    /* rhw conversion like in drawStridedSlow */
+    if (p[3] == 1.0 || ((p[3] < eps) && (p[3] > -eps)))
+    {
+        x = p[0];
+        y = p[1];
+        z = p[2];
+        w = 1.0;
+    }
+    else
+    {
+        w = 1.0 / p[3];
+        x = p[0] * w;
+        y = p[1] * w;
+        z = p[2] * w;
+    }
+    p[0] = x;
+    p[1] = y;
+    p[2] = z;
+    p[3] = w;
+}
+
+const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object)
+{
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+
+    *buffer_object = This->buffer_object;
+    if (!This->buffer_object)
+    {
+        if (This->flags & WINED3D_BUFFER_CREATEBO)
+        {
+            buffer_create_buffer_object(This);
+            This->flags &= ~WINED3D_BUFFER_CREATEBO;
+            if (This->buffer_object)
+            {
+                *buffer_object = This->buffer_object;
+                return (const BYTE *)offset;
+            }
+        }
+        return This->resource.allocatedMemory + offset;
+    }
+    else
+    {
+        return (const BYTE *)offset;
+    }
+}
+
+/* IUnknown methods */
+
+static HRESULT STDMETHODCALLTYPE buffer_QueryInterface(IWineD3DBuffer *iface,
+        REFIID riid, void **object)
+{
+    TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
+
+    if (IsEqualGUID(riid, &IID_IWineD3DBuffer)
+            || 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 buffer_AddRef(IWineD3DBuffer *iface)
+{
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+    ULONG refcount = InterlockedIncrement(&This->resource.ref);
+
+    TRACE("%p increasing refcount to %u\n", This, refcount);
+
+    return refcount;
+}
+
+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);
+        ENTER_GL();
+        GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
+        checkGLcall("glDeleteBuffersARB");
+        LEAVE_GL();
+        This->buffer_object = 0;
+        This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
+    }
+}
+
+static ULONG STDMETHODCALLTYPE buffer_Release(IWineD3DBuffer *iface)
+{
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+    ULONG refcount = InterlockedDecrement(&This->resource.ref);
+
+    TRACE("%p decreasing refcount to %u\n", This, refcount);
+
+    if (!refcount)
+    {
+        buffer_UnLoad(iface);
+        resource_cleanup((IWineD3DResource *)iface);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return refcount;
+}
+
+/* IWineD3DBase methods */
+
+static HRESULT STDMETHODCALLTYPE buffer_GetParent(IWineD3DBuffer *iface, IUnknown **parent)
+{
+    return resource_get_parent((IWineD3DResource *)iface, parent);
+}
+
+/* IWineD3DResource methods */
+
+static HRESULT STDMETHODCALLTYPE buffer_GetDevice(IWineD3DBuffer *iface, IWineD3DDevice **device)
+{
+    return resource_get_device((IWineD3DResource *)iface, device);
+}
+
+static HRESULT STDMETHODCALLTYPE buffer_SetPrivateData(IWineD3DBuffer *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 buffer_GetPrivateData(IWineD3DBuffer *iface,
+        REFGUID guid, void *data, DWORD *data_size)
+{
+    return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size);
+}
+
+static HRESULT STDMETHODCALLTYPE buffer_FreePrivateData(IWineD3DBuffer *iface, REFGUID guid)
+{
+    return resource_free_private_data((IWineD3DResource *)iface, guid);
+}
+
+static DWORD STDMETHODCALLTYPE buffer_SetPriority(IWineD3DBuffer *iface, DWORD priority)
+{
+    return resource_set_priority((IWineD3DResource *)iface, priority);
+}
+
+static DWORD STDMETHODCALLTYPE buffer_GetPriority(IWineD3DBuffer *iface)
+{
+    return resource_get_priority((IWineD3DResource *)iface);
+}
+
+static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
+{
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
+    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
+    UINT start = 0, end = 0, vertices;
+    BOOL decl_changed = FALSE;
+    unsigned int i, j;
+    BYTE *data;
+
+    TRACE("iface %p\n", iface);
+
+    if (!This->buffer_object)
     {
         /* TODO: Make converting independent from VBOs */
-        if (This->Flags & VBFLAG_CREATEVBO)
+        if (This->flags & WINED3D_BUFFER_CREATEBO)
         {
-            CreateVBO(This);
-            This->Flags &= ~VBFLAG_CREATEVBO;
+            buffer_create_buffer_object(This);
+            This->flags &= ~WINED3D_BUFFER_CREATEBO;
         }
         else
         {
@@ -742,33 +660,33 @@
     }
 
     /* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */
-    if (device->isInDraw && This->bindCount > 0)
+    if (device->isInDraw && This->bind_count > 0)
     {
-        declChanged = IWineD3DVertexBufferImpl_FindDecl(This);
-        This->Flags |= VBFLAG_HASDESC;
+        decl_changed = buffer_find_decl(This);
+        This->flags |= WINED3D_BUFFER_HASDESC;
     }
 
-    if (!declChanged && !(This->Flags & VBFLAG_HASDESC && This->Flags & VBFLAG_DIRTY)) return;
+    if (!decl_changed && !(This->flags & WINED3D_BUFFER_HASDESC && This->flags & WINED3D_BUFFER_DIRTY)) return;
 
     /* If applications change the declaration over and over, reconverting all the time is a huge
      * performance hit. So count the declaration changes and release the VBO if there are too many
      * of them (and thus stop converting)
      */
-    if (declChanged)
+    if (decl_changed)
     {
-        ++This->declChanges;
-        This->draws = 0;
+        ++This->conversion_count;
+        This->draw_count = 0;
 
-        if (This->declChanges > VB_MAXDECLCHANGES)
+        if (This->conversion_count > VB_MAXDECLCHANGES)
         {
             FIXME("Too many declaration changes, stopping converting\n");
             ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
             ENTER_GL();
-            GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
+            GL_EXTCALL(glDeleteBuffersARB(1, &This->buffer_object));
             checkGLcall("glDeleteBuffersARB");
             LEAVE_GL();
-            This->vbo = 0;
-            HeapFree(GetProcessHeap(), 0, This->conv_shift);
+            This->buffer_object = 0;
+            HeapFree(GetProcessHeap(), 0, This->conversion_shift);
 
             /* The stream source state handler might have read the memory of the vertex buffer already
              * and got the memory in the vbo which is not valid any longer. Dirtify the stream source
@@ -779,7 +697,7 @@
 
             return;
         }
-        check_vbo_size(This);
+        buffer_check_buffer_object_size(This);
     }
     else
     {
@@ -787,11 +705,11 @@
          * changes it every minute drop the VBO after VB_MAX_DECL_CHANGES minutes. So count draws without
          * decl changes and reset the decl change count after a specific number of them
          */
-        ++This->draws;
-        if (This->draws > VB_RESETDECLCHANGE) This->declChanges = 0;
+        ++This->draw_count;
+        if (This->draw_count > VB_RESETDECLCHANGE) This->conversion_count = 0;
     }
 
-    if (declChanged)
+    if (decl_changed)
     {
         /* The declaration changed, reload the whole buffer */
         WARN("Reloading buffer because of decl change\n");
@@ -801,23 +719,23 @@
     else
     {
         /* No decl change, but dirty data, reload the changed stuff */
-        if (This->conv_shift)
+        if (This->conversion_shift)
         {
-            if (This->dirtystart != 0 || This->dirtyend != 0)
+            if (This->dirty_start != 0 || This->dirty_end != 0)
             {
                 FIXME("Implement partial buffer loading with shifted conversion\n");
             }
         }
-        start = This->dirtystart;
-        end = This->dirtyend;
+        start = This->dirty_start;
+        end = This->dirty_end;
     }
 
     /* Mark the buffer clean */
-    This->Flags &= ~VBFLAG_DIRTY;
-    This->dirtystart = 0;
-    This->dirtyend = 0;
+    This->flags &= ~WINED3D_BUFFER_DIRTY;
+    This->dirty_start = 0;
+    This->dirty_end = 0;
 
-    if (!This->conv_map)
+    if (!This->conversion_map)
     {
         /* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory
          * directly into the vbo. Do not free the system memory copy because drawPrimitive may need it if
@@ -830,7 +748,7 @@
             ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
         }
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
+        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
         checkGLcall("glBindBufferARB");
         GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start));
         checkGLcall("glBufferSubDataARB");
@@ -841,24 +759,25 @@
     /* Now for each vertex in the buffer that needs conversion */
     vertices = This->resource.size / This->stride;
 
-    if (This->conv_shift)
+    if (This->conversion_shift)
     {
         TRACE("Shifted conversion\n");
-        data = HeapAlloc(GetProcessHeap(), 0, vertices * This->conv_stride);
+        data = HeapAlloc(GetProcessHeap(), 0, vertices * This->conversion_stride);
 
         for (i = start / This->stride; i < min((end / This->stride) + 1, vertices); ++i)
         {
             for (j = 0; j < This->stride; ++j)
             {
-                switch(This->conv_map[j])
+                switch(This->conversion_map[j])
                 {
                     case CONV_NONE:
-                        data[This->conv_stride * i + j + This->conv_shift[j]] = This->resource.allocatedMemory[This->stride * i + j];
+                        data[This->conversion_stride * i + j + This->conversion_shift[j]]
+                                = This->resource.allocatedMemory[This->stride * i + j];
                         break;
 
                     case CONV_FLOAT16_2:
                     {
-                        float *out = (float *)(&data[This->conv_stride * i + j + This->conv_shift[j]]);
+                        float *out = (float *)(&data[This->conversion_stride * i + j + This->conversion_shift[j]]);
                         const WORD *in = (WORD *)(&This->resource.allocatedMemory[i * This->stride + j]);
 
                         out[1] = float_16_to_32(in + 1);
@@ -868,15 +787,16 @@
                     }
 
                     default:
-                        FIXME("Unimplemented conversion %d in shifted conversion\n", This->conv_map[j]);
+                        FIXME("Unimplemented conversion %d in shifted conversion\n", This->conversion_map[j]);
+                        break;
                 }
             }
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
+        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
         checkGLcall("glBindBufferARB");
-        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conv_stride, data));
+        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conversion_stride, data));
         checkGLcall("glBufferSubDataARB");
         LEAVE_GL();
     }
@@ -888,7 +808,7 @@
         {
             for (j = 0; j < This->stride; ++j)
             {
-                switch(This->conv_map[j])
+                switch(This->conversion_map[j])
                 {
                     case CONV_NONE:
                         /* Done already */
@@ -907,13 +827,13 @@
                     case CONV_FLOAT16_2:
                         ERR("Did not expect FLOAT16 conversion in unshifted conversion\n");
                     default:
-                        FIXME("Unimplemented conversion %d in shifted conversion\n", This->conv_map[j]);
+                        FIXME("Unimplemented conversion %d in shifted conversion\n", This->conversion_map[j]);
                 }
             }
         }
 
         ENTER_GL();
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
+        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object));
         checkGLcall("glBindBufferARB");
         GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data + start));
         checkGLcall("glBufferSubDataARB");
@@ -923,164 +843,112 @@
     HeapFree(GetProcessHeap(), 0, data);
 }
 
-static void STDMETHODCALLTYPE IWineD3DVertexBufferImpl_UnLoad(IWineD3DVertexBuffer *iface)
-{
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)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
-     */
-    if (This->vbo)
-    {
-        ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
-        ENTER_GL();
-        GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
-        checkGLcall("glDeleteBuffersARB");
-        LEAVE_GL();
-        This->vbo = 0;
-        This->Flags |= VBFLAG_CREATEVBO; /* Recreate the VBO next load */
-    }
-}
-
-static WINED3DRESOURCETYPE STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetType(IWineD3DVertexBuffer *iface)
+static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface)
 {
     return resource_get_type((IWineD3DResource *)iface);
 }
 
-/* IWineD3DVertexBuffer methods */
+/* IWineD3DBuffer methods */
 
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface,
-        UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags)
+static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset, UINT size, BYTE **data, DWORD flags)
 {
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
-    BYTE *data;
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 
-    TRACE("(%p)->%d, %d, %p, %08x\n", This, OffsetToLock, SizeToLock, ppbData, Flags);
+    TRACE("iface %p, offset %u, size %u, data %p, flags %#x\n", iface, offset, size, data, flags);
 
-    InterlockedIncrement(&This->lockcount);
+    InterlockedIncrement(&This->lock_count);
 
-    if (This->Flags & VBFLAG_DIRTY)
+    if (This->flags & WINED3D_BUFFER_DIRTY)
     {
-        if (This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
-        if (SizeToLock)
+        if (This->dirty_start > offset) This->dirty_start = offset;
+
+        if (size)
         {
-            if (This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
+            if (This->dirty_end < offset + size) This->dirty_end = offset + size;
         }
         else
         {
-            This->dirtyend = This->resource.size;
+            This->dirty_end = This->resource.size;
         }
     }
     else
     {
-        This->dirtystart = OffsetToLock;
-        if (SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
-        else This->dirtyend = This->resource.size;
+        This->dirty_start = offset;
+        if (size) This->dirty_end = offset + size;
+        else This->dirty_end = This->resource.size;
     }
 
-    data = This->resource.allocatedMemory;
-    This->Flags |= VBFLAG_DIRTY;
-    *ppbData = data + OffsetToLock;
+    This->flags |= WINED3D_BUFFER_DIRTY;
 
-    TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, data + OffsetToLock, data, OffsetToLock);
+    *data = This->resource.allocatedMemory + offset;
+
+    TRACE("Returning memory at %p (base %p, offset %u)\n", *data, This->resource.allocatedMemory, offset);
     /* TODO: check Flags compatibility with This->currentDesc.Usage (see MSDN) */
 
     return WINED3D_OK;
 }
 
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface)
+static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
 {
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
-    LONG lockcount;
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 
     TRACE("(%p)\n", This);
 
-    lockcount = InterlockedDecrement(&This->lockcount);
-    if (lockcount > 0)
+    if (InterlockedDecrement(&This->lock_count))
     {
         /* Delay loading the buffer until everything is unlocked */
-        TRACE("Ignoring the unlock\n");
+        TRACE("Ignoring unlock\n");
         return WINED3D_OK;
     }
 
-    if (This->Flags & VBFLAG_HASDESC)
+    if (This->flags & WINED3D_BUFFER_HASDESC)
     {
-        IWineD3DVertexBufferImpl_PreLoad(iface);
+        buffer_PreLoad(iface);
     }
 
     return WINED3D_OK;
 }
 
-static HRESULT STDMETHODCALLTYPE IWineD3DVertexBufferImpl_GetDesc(IWineD3DVertexBuffer *iface,
-        WINED3DVERTEXBUFFER_DESC *pDesc)
+static HRESULT STDMETHODCALLTYPE buffer_GetDesc(IWineD3DBuffer *iface, WINED3DVERTEXBUFFER_DESC *desc)
 {
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
+    struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
 
     TRACE("(%p)\n", This);
 
-    pDesc->Format = This->resource.format;
-    pDesc->Type = This->resource.resourceType;
-    pDesc->Usage = This->resource.usage;
-    pDesc->Pool = This->resource.pool;
-    pDesc->Size = This->resource.size;
-    pDesc->FVF = This->fvf;
+    desc->Format = This->resource.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;
 }
 
-const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl =
+const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
 {
     /* IUnknown methods */
-    IWineD3DVertexBufferImpl_QueryInterface,
-    IWineD3DVertexBufferImpl_AddRef,
-    IWineD3DVertexBufferImpl_Release,
+    buffer_QueryInterface,
+    buffer_AddRef,
+    buffer_Release,
     /* IWineD3DBase methods */
-    IWineD3DVertexBufferImpl_GetParent,
+    buffer_GetParent,
     /* IWineD3DResource methods */
-    IWineD3DVertexBufferImpl_GetDevice,
-    IWineD3DVertexBufferImpl_SetPrivateData,
-    IWineD3DVertexBufferImpl_GetPrivateData,
-    IWineD3DVertexBufferImpl_FreePrivateData,
-    IWineD3DVertexBufferImpl_SetPriority,
-    IWineD3DVertexBufferImpl_GetPriority,
-    IWineD3DVertexBufferImpl_PreLoad,
-    IWineD3DVertexBufferImpl_UnLoad,
-    IWineD3DVertexBufferImpl_GetType,
-    /* IWineD3DVertexBuffer methods */
-    IWineD3DVertexBufferImpl_Lock,
-    IWineD3DVertexBufferImpl_Unlock,
-    IWineD3DVertexBufferImpl_GetDesc,
+    buffer_GetDevice,
+    buffer_SetPrivateData,
+    buffer_GetPrivateData,
+    buffer_FreePrivateData,
+    buffer_SetPriority,
+    buffer_GetPriority,
+    buffer_PreLoad,
+    buffer_UnLoad,
+    buffer_GetType,
+    /* IWineD3DBuffer methods */
+    buffer_Map,
+    buffer_Unmap,
+    buffer_GetDesc,
 };
 
-const BYTE *IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer *iface, DWORD iOffset, GLint *vbo)
-{
-    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
-
-    *vbo = This->vbo;
-    if (!This->vbo)
-    {
-        if (This->Flags & VBFLAG_CREATEVBO)
-        {
-            CreateVBO(This);
-            This->Flags &= ~VBFLAG_CREATEVBO;
-            if (This->vbo)
-            {
-                *vbo = This->vbo;
-                return (const BYTE *)iOffset;
-            }
-        }
-        return This->resource.allocatedMemory + iOffset;
-    }
-    else
-    {
-        return (const BYTE *)iOffset;
-    }
-}
-
 /* IUnknown methods */
 
 static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index ce8a8d0..d21b132 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -258,11 +258,11 @@
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage, 
-                             DWORD FVF, WINED3DPOOL Pool, IWineD3DVertexBuffer** ppVertexBuffer, HANDLE *sharedHandle,
-                             IUnknown *parent) {
+static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *iface, UINT Size, DWORD Usage,
+        DWORD FVF, WINED3DPOOL Pool, IWineD3DBuffer **ppVertexBuffer, HANDLE *sharedHandle, IUnknown *parent)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexBufferImpl *object;
+    struct wined3d_buffer *object;
     WINED3DFORMAT Format = WINED3DFMT_VERTEXDATA; /* Dummy format for now */
     int dxVersion = ( (IWineD3DImpl *) This->wineD3D)->dxVersion;
     HRESULT hr;
@@ -289,7 +289,7 @@
         return WINED3DERR_OUTOFVIDEOMEMORY;
     }
 
-    object->lpVtbl = &IWineD3DVertexBuffer_Vtbl;
+    object->vtbl = &wined3d_buffer_vtbl;
     hr = resource_init(&object->resource, WINED3DRTYPE_VERTEXBUFFER, This, Size, Usage, Format, Pool, parent);
     if (FAILED(hr))
     {
@@ -304,7 +304,7 @@
     IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
 
     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 = (IWineD3DVertexBuffer *)object;
+    *ppVertexBuffer = (IWineD3DBuffer *)object;
 
     object->fvf = FVF;
 
@@ -333,7 +333,7 @@
     } else if(dxVersion <= 7 && conv) {
         TRACE("Not creating a vbo because dxVersion is 7 and the fvf needs conversion\n");
     } else {
-        object->Flags |= VBFLAG_CREATEVBO;
+        object->flags |= WINED3D_BUFFER_CREATEBO;
     }
     return WINED3D_OK;
 }
@@ -552,7 +552,7 @@
 
         for(i = 0; i < MAX_STREAMS; i++) {
             if(object->streamSource[i]) {
-                IWineD3DVertexBuffer_AddRef(object->streamSource[i]);
+                IWineD3DBuffer_AddRef(object->streamSource[i]);
             }
         }
         if(object->pIndexData) {
@@ -685,7 +685,7 @@
 
         for(i = 0; i < MAX_STREAMS; i++) {
             if(object->streamSource[i]) {
-                IWineD3DVertexBuffer_AddRef(object->streamSource[i]);
+                IWineD3DBuffer_AddRef(object->streamSource[i]);
             }
         }
         if(object->vertexShader) {
@@ -2824,9 +2824,11 @@
 /*****
  * Get / Set Stream Source
  *****/
-static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, UINT StreamNumber,IWineD3DVertexBuffer* pStreamData, UINT OffsetInBytes, UINT Stride) {
-        IWineD3DDeviceImpl       *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexBuffer     *oldSrc;
+static HRESULT WINAPI IWineD3DDeviceImpl_SetStreamSource(IWineD3DDevice *iface, UINT StreamNumber,
+        IWineD3DBuffer *pStreamData, UINT OffsetInBytes, UINT Stride)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
+    IWineD3DBuffer *oldSrc;
 
     if (StreamNumber >= MAX_STREAMS) {
         WARN("Stream out of range %d\n", StreamNumber);
@@ -2857,19 +2859,18 @@
     /* Handle recording of state blocks */
     if (This->isRecordingState) {
         TRACE("Recording... not performing anything\n");
-        if(pStreamData) IWineD3DVertexBuffer_AddRef(pStreamData);
-        if(oldSrc) IWineD3DVertexBuffer_Release(oldSrc);
+        if (pStreamData) IWineD3DBuffer_AddRef(pStreamData);
+        if (oldSrc) IWineD3DBuffer_Release(oldSrc);
         return WINED3D_OK;
     }
 
     if (pStreamData != NULL) {
-        IWineD3DVertexBufferImpl *vbImpl = (IWineD3DVertexBufferImpl *) pStreamData;
-        InterlockedIncrement(&vbImpl->bindCount);
-        IWineD3DVertexBuffer_AddRef(pStreamData);
+        InterlockedIncrement(&((struct wined3d_buffer *)pStreamData)->bind_count);
+        IWineD3DBuffer_AddRef(pStreamData);
     }
     if (oldSrc != NULL) {
-        InterlockedDecrement(&((IWineD3DVertexBufferImpl *) oldSrc)->bindCount);
-        IWineD3DVertexBuffer_Release(oldSrc);
+        InterlockedDecrement(&((struct wined3d_buffer *)oldSrc)->bind_count);
+        IWineD3DBuffer_Release(oldSrc);
     }
 
     IWineD3DDeviceImpl_MarkStateDirty(This, STATE_STREAMSRC);
@@ -2877,7 +2878,9 @@
     return WINED3D_OK;
 }
 
-static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice *iface, UINT StreamNumber,IWineD3DVertexBuffer** pStream, UINT *pOffset, UINT* pStride) {
+static HRESULT WINAPI IWineD3DDeviceImpl_GetStreamSource(IWineD3DDevice *iface,
+        UINT StreamNumber, IWineD3DBuffer **pStream, UINT *pOffset, UINT *pStride)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
 
     TRACE("(%p) : StreamNo: %u, Stream (%p), Offset %u, Stride %u\n", This, StreamNumber,
@@ -2896,7 +2899,7 @@
     }
 
     if (*pStream != NULL) {
-        IWineD3DVertexBuffer_AddRef(*pStream); /* We have created a new reference to the VB */
+        IWineD3DBuffer_AddRef(*pStream); /* We have created a new reference to the VB */
     }
     return WINED3D_OK;
 }
@@ -4296,7 +4299,7 @@
 
 #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 WineDirect3DVertexStridedData *lpStrideData, IWineD3DVertexBufferImpl *dest, DWORD dwFlags)
+        const WineDirect3DVertexStridedData *lpStrideData, struct wined3d_buffer *dest, DWORD dwFlags)
 {
     char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL;
     unsigned int i;
@@ -4328,9 +4331,10 @@
             ERR("Out of memory\n");
             return E_OUTOFMEMORY;
         }
-        if(dest->vbo) {
+        if (dest->buffer_object)
+        {
             const void *src;
-            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->vbo));
+            GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object));
             checkGLcall("glBindBufferARB");
             src = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB));
             if(src) {
@@ -4344,12 +4348,14 @@
     /* Get a pointer into the destination vbo(create one if none exists) and
      * write correct opengl data into it. It's cheap and allows us to run drawStridedFast
      */
-    if(!dest->vbo && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
-        dest->Flags |= VBFLAG_CREATEVBO;
-        IWineD3DVertexBuffer_PreLoad((IWineD3DVertexBuffer *) dest);
+    if (!dest->buffer_object && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT))
+    {
+        dest->flags |= WINED3D_BUFFER_CREATEBO;
+        IWineD3DBuffer_PreLoad((IWineD3DBuffer *)dest);
     }
 
-    if(dest->vbo) {
+    if (dest->buffer_object)
+    {
         unsigned char extrabytes = 0;
         /* If the destination vertex buffer has D3DFVF_XYZ position(non-rhw), native d3d writes RHW position, where the RHW
          * gets written into the 4 bytes after the Z position. In the case of a dest buffer that only has D3DFVF_XYZ data,
@@ -4636,7 +4642,7 @@
     }
 
     if(dest_conv) {
-        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->vbo));
+        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, dest->buffer_object));
         checkGLcall("glBindBufferARB(GL_ARRAY_BUFFER_ARB)");
         GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, dwDestIndex * get_flexible_vertex_size(DestFVF),
                                       dwCount * get_flexible_vertex_size(DestFVF),
@@ -4651,7 +4657,9 @@
 }
 #undef copy_and_next
 
-static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IWineD3DVertexBuffer* pDestBuffer, IWineD3DVertexDeclaration* pVertexDecl, DWORD Flags) {
+static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT SrcStartIndex, UINT DestIndex,
+        UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags)
+{
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
     WineDirect3DVertexStridedData strided;
     BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP;
@@ -4681,12 +4689,12 @@
          */
 #define FIXSRC(type) \
         if(strided.u.s.type.VBO) { \
-            IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[strided.u.s.type.streamNo]; \
+            struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.s.type.streamNo]; \
             strided.u.s.type.VBO = 0; \
             strided.u.s.type.lpData = (BYTE *) ((unsigned long) strided.u.s.type.lpData + (unsigned long) vb->resource.allocatedMemory); \
             ENTER_GL(); \
-            GL_EXTCALL(glDeleteBuffersARB(1, &vb->vbo)); \
-            vb->vbo = 0; \
+            GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); \
+            vb->buffer_object = 0; \
             LEAVE_GL(); \
         } \
         if(strided.u.s.type.lpData) { \
@@ -4713,7 +4721,8 @@
 #undef FIXSRC
     }
 
-    return process_vertices_strided(This, DestIndex, VertexCount, &strided, (IWineD3DVertexBufferImpl *) pDestBuffer, Flags);
+    return process_vertices_strided(This, DestIndex, VertexCount, &strided,
+            (struct wined3d_buffer *)pDestBuffer, Flags);
 }
 
 /*****
@@ -5490,7 +5499,7 @@
         const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
 {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexBuffer *vb;
+    IWineD3DBuffer *vb;
 
     TRACE("(%p) : vertex count %u, pVtxData %p, stride %u\n",
             This, vertex_count, pVertexStreamZeroData, VertexStreamZeroStride);
@@ -5502,8 +5511,8 @@
 
     /* Note in the following, it's not this type, but that's the purpose of streamIsUP */
     vb = This->stateBlock->streamSource[0];
-    This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData;
-    if(vb) IWineD3DVertexBuffer_Release(vb);
+    This->stateBlock->streamSource[0] = (IWineD3DBuffer *)pVertexStreamZeroData;
+    if (vb) IWineD3DBuffer_Release(vb);
     This->stateBlock->streamOffset[0] = 0;
     This->stateBlock->streamStride[0] = VertexStreamZeroStride;
     This->stateBlock->streamIsUP = TRUE;
@@ -5531,7 +5540,7 @@
 {
     int                 idxStride;
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-    IWineD3DVertexBuffer *vb;
+    IWineD3DBuffer *vb;
     IWineD3DIndexBuffer *ib;
 
     TRACE("(%p) : MinVtxIdx %u, NumVIdx %u, index count %u, pidxdata %p, IdxFmt %u, pVtxdata %p, stride=%u\n",
@@ -5551,8 +5560,8 @@
 
     /* Note in the following, it's not this type, but that's the purpose of streamIsUP */
     vb = This->stateBlock->streamSource[0];
-    This->stateBlock->streamSource[0] = (IWineD3DVertexBuffer *)pVertexStreamZeroData;
-    if(vb) IWineD3DVertexBuffer_Release(vb);
+    This->stateBlock->streamSource[0] = (IWineD3DBuffer *)pVertexStreamZeroData;
+    if (vb) IWineD3DBuffer_Release(vb);
     This->stateBlock->streamIsUP = TRUE;
     This->stateBlock->streamOffset[0] = 0;
     This->stateBlock->streamStride[0] = VertexStreamZeroStride;
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index dd0bd3a..804e65b 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -108,7 +108,7 @@
     /* Translate the declaration into strided data */
     strided->swizzle_map = 0;
     for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) {
-        GLint streamVBO = 0;
+        GLuint streamVBO = 0;
         BOOL stride_used;
         unsigned int idx;
 
@@ -126,7 +126,7 @@
             data    = (BYTE *)This->stateBlock->streamSource[element->Stream];
         } else {
             TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
-            data    = IWineD3DVertexBufferImpl_GetMemory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
+            data = buffer_get_memory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO);
 
             /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets
              * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory
@@ -137,7 +137,7 @@
             if(This->stateBlock->loadBaseVertexIndex < 0) {
                 WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
                 streamVBO = 0;
-                data = ((IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory;
+                data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory;
                 if((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) {
                     FIXME("System memory vertex data load offset is negative!\n");
                 }
@@ -200,9 +200,9 @@
      * once in there.
      */
     for(i=0; i < numPreloadStreams; i++) {
-        IWineD3DVertexBuffer *vb = This->stateBlock->streamSource[streams[i]];
+        IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]];
         if(vb) {
-            IWineD3DVertexBuffer_PreLoad(vb);
+            IWineD3DBuffer_PreLoad(vb);
         }
     }
 }
@@ -675,7 +675,7 @@
                         sd->u.input[instancedData[j]].dwStride * i +
                         stateblock->streamOffset[sd->u.input[instancedData[j]].streamNo];
             if(sd->u.input[instancedData[j]].VBO) {
-                IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[sd->u.input[instancedData[j]].streamNo];
+                struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[sd->u.input[instancedData[j]].streamNo];
                 ptr += (long) vb->resource.allocatedMemory;
             }
 
@@ -690,87 +690,87 @@
 
 static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) {
     unsigned char i;
-    IWineD3DVertexBufferImpl *vb;
+    struct wined3d_buffer *vb;
 
     if(s->u.s.position.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.position.streamNo];
         s->u.s.position.VBO = 0;
         s->u.s.position.lpData = (BYTE *) ((unsigned long) s->u.s.position.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.blendWeights.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendWeights.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.blendWeights.streamNo];
         s->u.s.blendWeights.VBO = 0;
         s->u.s.blendWeights.lpData = (BYTE *) ((unsigned long) s->u.s.blendWeights.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.blendMatrixIndices.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.blendMatrixIndices.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.blendMatrixIndices.streamNo];
         s->u.s.blendMatrixIndices.VBO = 0;
         s->u.s.blendMatrixIndices.lpData = (BYTE *) ((unsigned long) s->u.s.blendMatrixIndices.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.normal.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.normal.streamNo];
         s->u.s.normal.VBO = 0;
         s->u.s.normal.lpData = (BYTE *) ((unsigned long) s->u.s.normal.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.pSize.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.pSize.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.pSize.streamNo];
         s->u.s.pSize.VBO = 0;
         s->u.s.pSize.lpData = (BYTE *) ((unsigned long) s->u.s.pSize.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.diffuse.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.diffuse.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.diffuse.streamNo];
         s->u.s.diffuse.VBO = 0;
         s->u.s.diffuse.lpData = (BYTE *) ((unsigned long) s->u.s.diffuse.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.specular.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.specular.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.specular.streamNo];
         s->u.s.specular.VBO = 0;
         s->u.s.specular.lpData = (BYTE *) ((unsigned long) s->u.s.specular.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     for(i = 0; i < WINED3DDP_MAXTEXCOORD; i++) {
         if(s->u.s.texCoords[i].VBO) {
-            vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.texCoords[i].streamNo];
+            vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.texCoords[i].streamNo];
             s->u.s.texCoords[i].VBO = 0;
             s->u.s.texCoords[i].lpData = (BYTE *) ((unsigned long) s->u.s.texCoords[i].lpData + (unsigned long) vb->resource.allocatedMemory);
         }
     }
     if(s->u.s.position2.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.position2.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.position2.streamNo];
         s->u.s.position2.VBO = 0;
         s->u.s.position2.lpData = (BYTE *) ((unsigned long) s->u.s.position2.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.normal2.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.normal2.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.normal2.streamNo];
         s->u.s.normal2.VBO = 0;
         s->u.s.normal2.lpData = (BYTE *) ((unsigned long) s->u.s.normal2.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.tangent.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tangent.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.tangent.streamNo];
         s->u.s.tangent.VBO = 0;
         s->u.s.tangent.lpData = (BYTE *) ((unsigned long) s->u.s.tangent.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.binormal.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.binormal.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.binormal.streamNo];
         s->u.s.binormal.VBO = 0;
         s->u.s.binormal.lpData = (BYTE *) ((unsigned long) s->u.s.binormal.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.tessFactor.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.tessFactor.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.tessFactor.streamNo];
         s->u.s.tessFactor.VBO = 0;
         s->u.s.tessFactor.lpData = (BYTE *) ((unsigned long) s->u.s.tessFactor.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.fog.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.fog.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.fog.streamNo];
         s->u.s.fog.VBO = 0;
         s->u.s.fog.lpData = (BYTE *) ((unsigned long) s->u.s.fog.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.depth.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.depth.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.depth.streamNo];
         s->u.s.depth.VBO = 0;
         s->u.s.depth.lpData = (BYTE *) ((unsigned long) s->u.s.depth.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
     if(s->u.s.sample.VBO) {
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[s->u.s.sample.streamNo];
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.s.sample.streamNo];
         s->u.s.sample.VBO = 0;
         s->u.s.sample.lpData = (BYTE *) ((unsigned long) s->u.s.sample.lpData + (unsigned long) vb->resource.allocatedMemory);
     }
@@ -975,8 +975,8 @@
     memset(&strided, 0, sizeof(strided));
     primitiveDeclarationConvertToStridedData((IWineD3DDevice *) This, FALSE, &strided, NULL);
     if(strided.u.s.position.VBO) {
-        IWineD3DVertexBufferImpl *vb;
-        vb = (IWineD3DVertexBufferImpl *) This->stateBlock->streamSource[strided.u.s.position.streamNo];
+        struct wined3d_buffer *vb;
+        vb = (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.s.position.streamNo];
         strided.u.s.position.lpData = (BYTE *) ((unsigned long) strided.u.s.position.lpData +
                                                 (unsigned long) vb->resource.allocatedMemory);
     }
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 6b36a3d..c791081 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -3842,7 +3842,7 @@
     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
     int i;
     const UINT *offset = stateblock->streamOffset;
-    IWineD3DVertexBufferImpl *vb;
+    struct wined3d_buffer *vb;
     DWORD_PTR shift_index;
 
     /* Default to no instancing */
@@ -3870,27 +3870,28 @@
                 checkGLcall("glBindBufferARB");
                 curVBO = strided->u.input[i].VBO;
             }
-            vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
+            vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo];
             /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a
              * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no
              * vbo we won't be load converted attributes anyway
              */
-            if(curVBO && vb->conv_shift) {
+            if (curVBO && vb->conversion_shift)
+            {
                 TRACE("Loading attribute from shifted buffer\n");
-                TRACE("Attrib %d has original stride %d, new stride %d\n", i, strided->u.input[i].dwStride, vb->conv_stride);
-                TRACE("Original offset %p, additional offset 0x%08x\n",strided->u.input[i].lpData, vb->conv_shift[(DWORD_PTR) strided->u.input[i].lpData]);
+                TRACE("Attrib %d has original stride %d, new stride %d\n",
+                        i, strided->u.input[i].dwStride, vb->conversion_stride);
+                TRACE("Original offset %p, additional offset 0x%08x\n",
+                        strided->u.input[i].lpData, vb->conversion_shift[(DWORD_PTR) strided->u.input[i].lpData]);
                 TRACE("Opengl type %x\n", WINED3D_ATR_GLTYPE(strided->u.input[i].dwType));
                 shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]);
                 shift_index = shift_index % strided->u.input[i].dwStride;
-                GL_EXTCALL(glVertexAttribPointerARB(i,
-                                WINED3D_ATR_FORMAT(strided->u.input[i].dwType),
-                                WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
-                                WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
-                                vb->conv_stride,
-
-                                strided->u.input[i].lpData + vb->conv_shift[shift_index] +
-                                stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
-                                offset[strided->u.input[i].streamNo]));
+                GL_EXTCALL(glVertexAttribPointerARB(i, WINED3D_ATR_FORMAT(strided->u.input[i].dwType),
+                        WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
+                        WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
+                        vb->conversion_stride,
+                        strided->u.input[i].lpData + vb->conversion_shift[shift_index]
+                        + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride
+                        + offset[strided->u.input[i].streamNo]));
 
             } else {
                 GL_EXTCALL(glVertexAttribPointerARB(i,
@@ -3915,7 +3916,7 @@
              */
             const BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
             if(strided->u.input[i].VBO) {
-                vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
+                vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo];
                 ptr += (long) vb->resource.allocatedMemory;
             }
 
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 8ac6471..cbf5f97 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -230,7 +230,7 @@
     
     memcpy(Dest->streamStride, This->streamStride, sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamOffset, This->streamOffset, sizeof(UINT) * MAX_STREAMS);
-    memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DVertexBuffer*) * MAX_STREAMS);
+    memcpy(Dest->streamSource, This->streamSource, sizeof(IWineD3DBuffer *) * MAX_STREAMS);
     memcpy(Dest->streamFreq,   This->streamFreq,   sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->streamFlags,  This->streamFlags,  sizeof(UINT) * MAX_STREAMS);
     memcpy(Dest->transforms,   This->transforms,   sizeof(WINED3DMATRIX) * (HIGHEST_TRANSFORMSTATE + 1));
@@ -295,7 +295,8 @@
 
         for (counter = 0; counter < MAX_STREAMS; counter++) {
             if(This->streamSource[counter]) {
-                if(0 != IWineD3DVertexBuffer_Release(This->streamSource[counter])) {
+                if (IWineD3DBuffer_Release(This->streamSource[counter]))
+                {
                     TRACE("Vertex buffer still referenced by stateblock, applications has leaked Stream %u, buffer %p\n", counter, This->streamSource[counter]);
                 }
             }
@@ -553,8 +554,8 @@
                 TRACE("Updating stream source %u to %p, stride to %u\n",
                         i, targetStateBlock->streamSource[i], targetStateBlock->streamStride[i]);
                 This->streamStride[i] = targetStateBlock->streamStride[i];
-                if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
-                if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
+                if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
+                if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                 This->streamSource[i] = targetStateBlock->streamSource[i];
             }
         }
@@ -655,14 +656,14 @@
         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) IWineD3DIndexBuffer_AddRef(targetStateBlock->pIndexData);
+            if (This->pIndexData) IWineD3DIndexBuffer_Release(This->pIndexData);
             This->pIndexData = targetStateBlock->pIndexData;
         }
         for(i = 0; i < MAX_STREAMS; i++) {
             if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
-                if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
-                if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
+                if(targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
+                if(This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                 This->streamSource[i] = targetStateBlock->streamSource[i];
             }
         }
@@ -696,8 +697,8 @@
         }
         for(i = 0; i < MAX_STREAMS; i++) {
             if(targetStateBlock->streamSource[i] != This->streamSource[i]) {
-                if(targetStateBlock->streamSource[i]) IWineD3DVertexBuffer_AddRef(targetStateBlock->streamSource[i]);
-                if(This->streamSource[i]) IWineD3DVertexBuffer_Release(This->streamSource[i]);
+                if (targetStateBlock->streamSource[i]) IWineD3DBuffer_AddRef(targetStateBlock->streamSource[i]);
+                if (This->streamSource[i]) IWineD3DBuffer_Release(This->streamSource[i]);
                 This->streamSource[i] = targetStateBlock->streamSource[i];
             }
         }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 40ae4b6..7aa4eb4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1260,56 +1260,6 @@
 #define RESOURCE_ALIGNMENT 32
 
 /*****************************************************************************
- * IWineD3DVertexBuffer implementation structure (extends IWineD3DResourceImpl)
- */
-enum vbo_conversion_type {
-    CONV_NONE               = 0,
-    CONV_D3DCOLOR           = 1,
-    CONV_POSITIONT          = 2,
-    CONV_FLOAT16_2          = 3 /* Also handles FLOAT16_4 */
-
-    /* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
-     * fixed function semantics as D3DCOLOR or FLOAT16
-     */
-};
-
-typedef struct IWineD3DVertexBufferImpl
-{
-    /* IUnknown & WineD3DResource Information     */
-    const IWineD3DVertexBufferVtbl *lpVtbl;
-    IWineD3DResourceClass     resource;
-
-    /* WineD3DVertexBuffer specifics */
-    DWORD                     fvf;
-
-    /* Vertex buffer object support */
-    GLuint                    vbo;
-    BYTE                      Flags;
-    LONG                      bindCount;
-    LONG                      vbo_size;
-    GLenum                    vbo_usage;
-
-    UINT                      dirtystart, dirtyend;
-    LONG                      lockcount;
-
-    LONG                      declChanges, draws;
-    /* Last description of the buffer */
-    DWORD                     stride;       /* 0 if no conversion               */
-    enum vbo_conversion_type  *conv_map;    /* NULL if no conversion            */
-
-    /* Extra load offsets, for FLOAT16 conversion */
-    DWORD                     *conv_shift;  /* NULL if no shifted conversion    */
-    DWORD                     conv_stride;  /* 0 if no shifted conversion       */
-} IWineD3DVertexBufferImpl;
-
-extern const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl;
-
-#define VBFLAG_OPTIMIZED      0x01    /* Optimize has been called for the VB */
-#define VBFLAG_DIRTY          0x02    /* Buffer data has been modified */
-#define VBFLAG_HASDESC        0x04    /* A vertex description has been found */
-#define VBFLAG_CREATEVBO      0x08    /* Attempt to create a VBO next PreLoad */
-
-/*****************************************************************************
  * IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl)
  */
 typedef struct IWineD3DIndexBufferImpl
@@ -1843,7 +1793,7 @@
     BOOL                      streamIsUP;
     UINT                      streamStride[MAX_STREAMS];
     UINT                      streamOffset[MAX_STREAMS + 1 /* tesselated pseudo-stream */ ];
-    IWineD3DVertexBuffer     *streamSource[MAX_STREAMS];
+    IWineD3DBuffer           *streamSource[MAX_STREAMS];
     UINT                      streamFreq[MAX_STREAMS + 1];
     UINT                      streamFlags[MAX_STREAMS + 1];     /*0 | WINED3DSTREAMSOURCE_INSTANCEDATA | WINED3DSTREAMSOURCE_INDEXEDDATA  */
 
@@ -1978,15 +1928,54 @@
 } WineQueryEventData;
 
 /* IWineD3DBuffer */
+
+/* TODO: Add tests and support for FLOAT16_4 POSITIONT, D3DCOLOR position, other
+ * fixed function semantics as D3DCOLOR or FLOAT16 */
+enum wined3d_buffer_conversion_type
+{
+    CONV_NONE,
+    CONV_D3DCOLOR,
+    CONV_POSITIONT,
+    CONV_FLOAT16_2, /* Also handles FLOAT16_4 */
+};
+
+#define WINED3D_BUFFER_OPTIMIZED    0x01    /* Optimize has been called for the buffer */
+#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 */
+
 struct wined3d_buffer
 {
     const struct IWineD3DBufferVtbl *vtbl;
     IWineD3DResourceClass resource;
 
     struct wined3d_buffer_desc desc;
+
+    GLuint buffer_object;
+    GLenum buffer_object_usage;
+    UINT buffer_object_size;
+    LONG bind_count;
+    DWORD flags;
+
+    UINT dirty_start;
+    UINT dirty_end;
+    LONG lock_count;
+
+    /* legacy vertex buffers */
+    DWORD fvf;
+
+    /* conversion stuff */
+    UINT conversion_count;
+    UINT draw_count;
+    UINT stride;                                            /* 0 if no conversion */
+    UINT conversion_stride;                                 /* 0 if no shifted conversion */
+    enum wined3d_buffer_conversion_type *conversion_map;    /* NULL if no conversion */
+    /* Extra load offsets, for FLOAT16 conversion */
+    UINT *conversion_shift;                                 /* NULL if no shifted conversion */
 };
 
 extern const IWineD3DBufferVtbl wined3d_buffer_vtbl;
+const BYTE *buffer_get_memory(IWineD3DBuffer *iface, UINT offset, GLuint *buffer_object);
 
 /* IWineD3DRendertargetView */
 struct wined3d_rendertarget_view
@@ -2109,15 +2098,6 @@
 unsigned int count_bits(unsigned int mask);
 UINT wined3d_log2i(UINT32 x);
 
-/*****************************************************************************
- * To enable calling of inherited functions, requires prototypes 
- *
- * Note: Only require classes which are subclassed, ie resource, basetexture, 
- */
-
-    /* IWineD3DVertexBuffer */
-    extern const BYTE *IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer* iface, DWORD iOffset, GLint *vbo);
-
 /* TODO: Make this dynamic, based on shader limits ? */
 #define MAX_REG_ADDR 1
 #define MAX_REG_TEMP 32
diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl
index e0b1d6b..e2aab21 100644
--- a/include/wine/wined3d.idl
+++ b/include/wine/wined3d.idl
@@ -2413,26 +2413,6 @@
 [
     object,
     local,
-    uuid(217f671e-6f30-11d9-c687-00046142c14f)
-]
-interface IWineD3DVertexBuffer : IWineD3DResource
-{
-    HRESULT Lock(
-        [in] UINT offset,
-        [in] UINT size,
-        [out] BYTE **data,
-        [in] DWORD flags
-    );
-    HRESULT Unlock(
-    );
-    HRESULT GetDesc(
-        [out] WINED3DVERTEXBUFFER_DESC *desc
-    );
-}
-
-[
-    object,
-    local,
     uuid(3a02a54e-6f30-11d9-c687-00046142c14f)
 ]
 interface IWineD3DIndexBuffer : IWineD3DResource
@@ -2923,6 +2903,17 @@
 ]
 interface IWineD3DBuffer : IWineD3DResource
 {
+    HRESULT Map(
+        [in] UINT offset,
+        [in] UINT size,
+        [out] BYTE **data,
+        [in] DWORD flags
+    );
+    HRESULT Unmap(
+    );
+    HRESULT GetDesc(
+        [out] WINED3DVERTEXBUFFER_DESC *desc
+    );
 }
 
 [
@@ -2994,7 +2985,7 @@
         [in] DWORD usage,
         [in] DWORD fvf,
         [in] WINED3DPOOL pool,
-        [out] IWineD3DVertexBuffer **vertex_buffer,
+        [out] IWineD3DBuffer **vertex_buffer,
         [in] HANDLE *shared_handle,
         [in] IUnknown *parent
     );
@@ -3351,13 +3342,13 @@
     );
     HRESULT SetStreamSource(
         [in] UINT stream_idx,
-        [in] IWineD3DVertexBuffer *vertex_buffer,
+        [in] IWineD3DBuffer *buffer,
         [in] UINT offset,
         [in] UINT stride
     );
     HRESULT GetStreamSource(
         [in] UINT stream_idx,
-        [out] IWineD3DVertexBuffer **vertex_buffer,
+        [out] IWineD3DBuffer **buffer,
         [out] UINT *offset,
         [out] UINT *stride
     );
@@ -3454,7 +3445,7 @@
         [in] UINT src_start_idx,
         [in] UINT dst_idx,
         [in] UINT vertex_count,
-        [in] IWineD3DVertexBuffer *dest_buffer,
+        [in] IWineD3DBuffer *dest_buffer,
         [in] IWineD3DVertexDeclaration *declaration,
         [in] DWORD flags
     );