/*
 * IWineD3DVertexBuffer Implementation
 *
 * Copyright 2002-2005 Jason Edmeades
 *                     Raphael Junqueira
 * Copyright 2004 Christian Costa
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info

#define VB_MAXDECLCHANGES     100     /* After that number we stop converting */
#define VB_RESETDECLCHANGE    1000    /* Reset the changecount after that number of draws */

/* *******************************************
   IWineD3DVertexBuffer IUnknown parts follow
   ******************************************* */
static HRESULT WINAPI IWineD3DVertexBufferImpl_QueryInterface(IWineD3DVertexBuffer *iface, REFIID riid, LPVOID *ppobj)
{
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IWineD3DBase)
        || IsEqualGUID(riid, &IID_IWineD3DResource)
        || IsEqualGUID(riid, &IID_IWineD3DVertexBuffer)){
        IUnknown_AddRef(iface);
        *ppobj = This;
        return S_OK;
    }
    *ppobj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI IWineD3DVertexBufferImpl_AddRef(IWineD3DVertexBuffer *iface) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
    ULONG ref = InterlockedIncrement(&This->resource.ref);
    TRACE("(%p) : AddRef increasing from %d\n", This, ref - 1);
    return ref;
}

static ULONG WINAPI IWineD3DVertexBufferImpl_Release(IWineD3DVertexBuffer *iface) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
    ULONG ref = InterlockedDecrement(&This->resource.ref);
    TRACE("(%p) : Releasing from %d\n", This, ref + 1);
    if (ref == 0) {

        if(This->vbo) {
            ENTER_GL();
            GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
            checkGLcall("glDeleteBuffersARB");
            LEAVE_GL();
        }

        IWineD3DResourceImpl_CleanUp((IWineD3DResource *)iface);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

/* ****************************************************
   IWineD3DVertexBuffer IWineD3DResource parts follow
   **************************************************** */
static HRESULT WINAPI IWineD3DVertexBufferImpl_GetDevice(IWineD3DVertexBuffer *iface, IWineD3DDevice** ppDevice) {
    return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice);
}

static HRESULT WINAPI IWineD3DVertexBufferImpl_SetPrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
    return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags);
}

static HRESULT WINAPI IWineD3DVertexBufferImpl_GetPrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
    return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData);
}

static HRESULT WINAPI IWineD3DVertexBufferImpl_FreePrivateData(IWineD3DVertexBuffer *iface, REFGUID refguid) {
    return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid);
}

static DWORD    WINAPI IWineD3DVertexBufferImpl_SetPriority(IWineD3DVertexBuffer *iface, DWORD PriorityNew) {
    return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew);
}

static DWORD    WINAPI IWineD3DVertexBufferImpl_GetPriority(IWineD3DVertexBuffer *iface) {
    return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface);
}

static void fixup_vertices(BYTE *src, BYTE *dst, int stride, int num, BYTE *pos, BOOL haspos, BYTE *diffuse, BOOL hasdiffuse, BYTE *specular, BOOL hasspecular) {
    int i;
    float x, y, z, w;

    for(i = num - 1; i >= 0; i--) {
        if(haspos) {
            float *p = (float *) (((int) src + (int) pos) + i * stride);

            /* 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 = (float *) ((int) dst + i * stride + (int) pos);
            p[0] = x;
            p[1] = y;
            p[2] = z;
            p[3] = w;
        }
        if(hasdiffuse) {
            DWORD srcColor, *dstColor = (DWORD *) (dst + i * stride + (int) diffuse);
            srcColor = * (DWORD *) ( ((int) src + (int) diffuse) + i * stride);

            /* 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
            */

            *dstColor = 0;
            *dstColor |= (srcColor & 0xff00ff00)      ;   /* Alpha Green */
            *dstColor |= (srcColor & 0x00ff0000) >> 16;   /* Red */
            *dstColor |= (srcColor & 0x000000ff) << 16;   /* Blue */
        }
        if(hasspecular) {
            DWORD srcColor, *dstColor = (DWORD *) (dst + i * stride + (int) specular);
            srcColor = * (DWORD *) ( ((int) src + (int) specular) + i * stride);

            /* Similar to diffuse
             * TODO: Write the alpha value out for fog coords
             */
            *dstColor = 0;
            *dstColor |= (srcColor & 0xff00ff00)      ;   /* Alpha Green */
            *dstColor |= (srcColor & 0x00ff0000) >> 16;   /* Red */
            *dstColor |= (srcColor & 0x000000ff) << 16;   /* Blue */
        }
    }
}

inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *This)
{
    WineDirect3DVertexStridedData strided;
    IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
    BOOL ret;

    memset(&strided, 0, sizeof(strided));
    /* There are certain vertex data types that need to be fixed up. The Vertex Buffers FVF doesn't
     * help finding them, only the vertex declaration or the device FVF can determine that at drawPrim
     * time. Rules are as follows:
     *
     * -> No modification when Vertex Shaders are used
     * -> Fix up position1 and position 2 if they are XYZRHW
     * -> Fix up diffuse color
     * -> Fix up specular color
     *
     * The Declaration is only known at drawing time, and it can change from draw to draw. If any converted values
     * are changed, the whole buffer has to be reconverted and reloaded. (Converting is SLOW, so if this happens too
     * often PreLoad stops converting entirely and falls back to drawStridedSlow).
     *
     * Reconvert if:
     * -> New semantics that have to be converted appear
     * -> The position of semantics that have to be converted changes
     * -> The stride of the vertex changed AND there is stuff that needs conversion
     * -> (If a vertex buffer is bound and in use assume that nothing that needs conversion is there)
     *
     * Return values:
     *  TRUE: Reload is needed
     *  FALSE: otherwise
     */

    if(device->stateBlock->vertexShader != NULL && wined3d_settings.vs_mode != VS_NONE 
       &&((IWineD3DVertexShaderImpl *)device->stateBlock->vertexShader)->baseShader.function != NULL
       && GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
        /* Case 1: Vertex Shader: No conversion */
        TRACE("Vertex Shader, no conversion needed\n");
    } else if(device->stateBlock->vertexDecl || device->stateBlock->vertexShader) {
        /* Case 2: Vertex Declaration */
        TRACE("Using vertex declaration\n");

        This->Flags |= VBFLAG_LOAD;
        primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
                FALSE,
                &strided,
                0,
                &ret /* buffer contains fixed data, ignored here */);
        This->Flags &= ~VBFLAG_LOAD;

    } else {
        /* Case 3: FVF */
        if(!(This->Flags & VBFLAG_STREAM) ) {
            TRACE("No vertex decl used and buffer is not bound to a stream\n");
            /* No reload needed */
            return FALSE;
        } else {
            This->Flags |= VBFLAG_LOAD;
            primitiveConvertFVFtoOffset(device->stateBlock->fvf,
                                        device->stateBlock->streamStride[This->stream],
                                        NULL,
                                        &strided,
                                        This->vbo);
            This->Flags &= ~VBFLAG_LOAD;
            /* Data can only come from this buffer */
        }
    }

    /* Filter out data that does not come from this VBO */
    if(strided.u.s.position.VBO != This->vbo)    memset(&strided.u.s.position, 0, sizeof(strided.u.s.position));
    if(strided.u.s.diffuse.VBO != This->vbo)     memset(&strided.u.s.diffuse, 0, sizeof(strided.u.s.diffuse));
    if(strided.u.s.specular.VBO != This->vbo)    memset(&strided.u.s.specular, 0, sizeof(strided.u.s.specular));
    if(strided.u.s.position2.VBO != This->vbo)   memset(&strided.u.s.position2, 0, sizeof(strided.u.s.position2));

    /* We have a declaration now in the buffer */
    This->Flags |= VBFLAG_HASDESC;

    /* Find out if reload is needed
     * Position of the semantic in the vertex and the stride must be equal to the stored type. Don't mind if only unconverted stuff changed.
     *
     * If some stuff does not exist in the buffer, then lpData, dwStride and dwType are memsetted to 0. So if the semantic didn't exist before
     * and does not exist now all 3 values will be equal(=0).
     *
     * Checking the lpData field alone is not enough, because data may appear at offset 0 in the buffer. This is the same location as nonexistent
     * data uses, so we have to check the type and stride too. Colors can be at offset 0 too, because it is perfectly fine to render from 2 or more
     * buffers at the same time and get the position from one and the color from the other buffer.
     */
    if( /* Position transformed vs untransformed */
        ((This->strided.u.s.position_transformed || strided.u.s.position_transformed) &&
          This->strided.u.s.position.lpData != strided.u.s.position.lpData) ||
        /* Diffuse position and data type */
        This->strided.u.s.diffuse.lpData != strided.u.s.diffuse.lpData || This->strided.u.s.diffuse.dwStride != strided.u.s.diffuse.dwStride ||
         This->strided.u.s.diffuse.dwType != strided.u.s.diffuse.dwType ||
        /* Specular position and data type */
        This->strided.u.s.specular.lpData != strided.u.s.specular.lpData || This->strided.u.s.specular.dwStride != strided.u.s.specular.dwStride ||
         This->strided.u.s.specular.dwType != strided.u.s.specular.dwType) {

        TRACE("Declaration changed, reloading buffer\n");
        /* Set the new description */
        memcpy(&This->strided, &strided, sizeof(strided));
        return TRUE;
    }

    return FALSE;
}

static void     WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
    BYTE *data;
    UINT start = 0, end = 0, stride = 0;
    BOOL declChanged = FALSE;
    TRACE("(%p)->()\n", This);

    if(This->Flags & VBFLAG_LOAD) {
        return; /* Already doing that stuff */
    }

    if(!This->vbo) {
        /* TODO: Make converting independent from VBOs */
        return; /* Not doing any conversion */
    }

    declChanged = IWineD3DVertexBufferImpl_FindDecl(This);

    /* 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 much
     * of them(and thus stop converting)
     */
    if(declChanged) {
        This->declChanges++;
        This->draws = 0;

        if(This->declChanges > VB_MAXDECLCHANGES) {
            if(This->resource.allocatedMemory) {
                FIXME("Too much declaration changes, stopping converting\n");
                ENTER_GL();
                GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
                checkGLcall("glDeleteBuffersARB");
                LEAVE_GL();
                This->vbo = 0;
                return;
            }
            /* Otherwise do not bother to release the VBO. If we're doing direct locking now,
             * and the declarations changed the code below will fetch the VBO's contents, convert
             * and on the next decl change the data will be in sysmem too and we can just release the VBO
             */
        }
    } else {
        /* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
         * 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;
    }

    if(declChanged) {
        /* The declaration changed, reload the whole buffer */
        WARN("Reloading buffer because of decl change\n");
        start = 0;
        end = This->resource.size;
    } else if(This->Flags & VBFLAG_DIRTY) {
        /* No decl change, but dirty data, reload the changed stuff */
        start = This->dirtystart;
        end = This->dirtyend;
    } else {
        /* Desc not changed, buffer not dirty, nothing to do :-) */
        return;
    }

    /* Mark the buffer clean */
    This->Flags &= ~VBFLAG_DIRTY;
    This->dirtystart = 0;
    This->dirtyend = 0;

    /* If there was no conversion done before, then resource.allocatedMemory does not exist
     * because locking was done directly into the VBO. In this case get the data out
     */
    if(declChanged && !This->resource.allocatedMemory) {

        This->resource.allocatedMemory = HeapAlloc(GetProcessHeap(), 0, This->resource.size);
        if(!This->resource.allocatedMemory) {
            ERR("Out of memory when allocating memory for a vertex buffer\n");
            return;
        }
        ERR("Was locking directly into the VBO, reading data back because conv is needed\n");

        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
        checkGLcall("glBindBufferARB");
        data = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB));
        if(!data) {
            ERR("glMapBuffer failed!\n");
            LEAVE_GL();
            return;
        }
        memcpy(This->resource.allocatedMemory, data, This->resource.size);
        GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB));
        checkGLcall("glUnmapBufferARB");
        LEAVE_GL();
    }

    if     (This->strided.u.s.position.dwStride) stride = This->strided.u.s.position.dwStride;
    else if(This->strided.u.s.specular.dwStride) stride = This->strided.u.s.specular.dwStride;
    else if(This->strided.u.s.diffuse.dwStride)  stride = This->strided.u.s.diffuse.dwStride;
    else {
        /* That means that there is nothing to fixup. Upload everything into the VBO and
         * free This->resource.allocatedMemory
         */
        TRACE("No conversion needed, locking directly into the VBO in future\n");

        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
        checkGLcall("glBindBufferARB");
        GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, This->resource.size, This->resource.allocatedMemory));
        checkGLcall("glBufferSubDataARB");
        LEAVE_GL();
        return;
    }

    /* OK, we have the original data from the app, the description of the buffer and the dirty area.
     * so convert the stuff
     */
    data = HeapAlloc(GetProcessHeap(), 0, end-start);
    if(!data) {
        ERR("Out of memory\n");
        return;
    }
    memcpy(data, This->resource.allocatedMemory + start, end - start);

    fixup_vertices(data, data, stride, ( end - start) / stride,
                   /* Position */
                   This->strided.u.s.position.lpData, /* Data location */
                   This->strided.u.s.position_transformed, /* Do convert? */
                   /* Diffuse color */
                   This->strided.u.s.diffuse.lpData, /* Location */
                   This->strided.u.s.diffuse.dwType == WINED3DDECLTYPE_SHORT4 || This->strided.u.s.diffuse.dwType == WINED3DDECLTYPE_D3DCOLOR, /* Convert? */
                   /* specular color */
                   This->strided.u.s.specular.lpData, /* location */
                   This->strided.u.s.specular.dwType == WINED3DDECLTYPE_SHORT4 || This->strided.u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR);

    ENTER_GL();
    GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
    checkGLcall("glBindBufferARB");
    GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data));
    checkGLcall("glBufferSubDataARB");
    LEAVE_GL();

    HeapFree(GetProcessHeap(), 0, data);
}

static WINED3DRESOURCETYPE WINAPI IWineD3DVertexBufferImpl_GetType(IWineD3DVertexBuffer *iface) {
    return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface);
}

static HRESULT WINAPI IWineD3DVertexBufferImpl_GetParent(IWineD3DVertexBuffer *iface, IUnknown **pParent) {
    return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent);
}

/* ******************************************************
   IWineD3DVertexBuffer IWineD3DVertexBuffer parts follow
   ****************************************************** */
static HRESULT  WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface, UINT OffsetToLock, UINT SizeToLock, BYTE** ppbData, DWORD Flags) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;
    BYTE *data;
    TRACE("(%p)->%d, %d, %p, %08x\n", This, OffsetToLock, SizeToLock, ppbData, Flags);

    InterlockedIncrement(&This->lockcount);

    if(This->Flags & VBFLAG_DIRTY) {
        if(This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
        if(SizeToLock) {
            if(This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
        } else {
            This->dirtyend = This->resource.size;
        }
    } else {
        This->dirtystart = OffsetToLock;
        if(SizeToLock)
            This->dirtyend = OffsetToLock + SizeToLock;
        else
            This->dirtyend = OffsetToLock + This->resource.size;
    }

    if(This->resource.allocatedMemory) {
          data = This->resource.allocatedMemory;
          This->Flags |= VBFLAG_DIRTY;
    } else {
        GLenum mode = GL_READ_WRITE_ARB;
        /* Return data to the VBO */

        TRACE("Locking directly into the buffer\n");

        if((This->resource.usage & WINED3DUSAGE_WRITEONLY) || ( Flags & D3DLOCK_DISCARD) ) {
            mode = GL_WRITE_ONLY_ARB;
        } else if( Flags & (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE) ) {
            mode = GL_READ_ONLY_ARB;
        }

        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
        checkGLcall("glBindBufferARB");
        data = GL_EXTCALL(glMapBufferARB(GL_ARRAY_BUFFER_ARB, mode));
        LEAVE_GL();
        if(!data) {
            ERR("glMapBuffer failed\n");
            return WINED3DERR_INVALIDCALL;
        }
    }
    *ppbData = data + OffsetToLock;

    TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, data + OffsetToLock, data, OffsetToLock);
    /* TODO: check Flags compatibility with This->currentDesc.Usage (see MSDN) */
    return WINED3D_OK;
}
HRESULT  WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
    LONG lockcount;
    TRACE("(%p)\n", This);

    lockcount = InterlockedDecrement(&This->lockcount);
    if(lockcount > 0) {
        /* Delay loading the buffer until everything is unlocked */
        TRACE("Ignoring the unlock\n");
        return D3D_OK;
    }

    if(!This->resource.allocatedMemory) {
        ENTER_GL();
        GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
        checkGLcall("glBindBufferARB");
        GL_EXTCALL(glUnmapBufferARB(GL_ARRAY_BUFFER_ARB));
        checkGLcall("glUnmapBufferARB");
        LEAVE_GL();
    } else if(This->Flags & VBFLAG_HASDESC){
        IWineD3DVertexBufferImpl_PreLoad(iface);
    }
    return WINED3D_OK;
}
static HRESULT  WINAPI IWineD3DVertexBufferImpl_GetDesc(IWineD3DVertexBuffer *iface, WINED3DVERTEXBUFFER_DESC *pDesc) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)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;
    return WINED3D_OK;
}

const IWineD3DVertexBufferVtbl IWineD3DVertexBuffer_Vtbl =
{
    /* IUnknown */
    IWineD3DVertexBufferImpl_QueryInterface,
    IWineD3DVertexBufferImpl_AddRef,
    IWineD3DVertexBufferImpl_Release,
    /* IWineD3DResource */
    IWineD3DVertexBufferImpl_GetParent,
    IWineD3DVertexBufferImpl_GetDevice,
    IWineD3DVertexBufferImpl_SetPrivateData,
    IWineD3DVertexBufferImpl_GetPrivateData,
    IWineD3DVertexBufferImpl_FreePrivateData,
    IWineD3DVertexBufferImpl_SetPriority,
    IWineD3DVertexBufferImpl_GetPriority,
    IWineD3DVertexBufferImpl_PreLoad,
    IWineD3DVertexBufferImpl_GetType,
    /* IWineD3DVertexBuffer */
    IWineD3DVertexBufferImpl_Lock,
    IWineD3DVertexBufferImpl_Unlock,
    IWineD3DVertexBufferImpl_GetDesc
};

BYTE* WINAPI IWineD3DVertexBufferImpl_GetMemory(IWineD3DVertexBuffer* iface, DWORD iOffset, GLint *vbo) {
    IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *)iface;

    *vbo = This->vbo;
    if(This->vbo == 0) {
        return This->resource.allocatedMemory + iOffset;
    } else {
        return (BYTE *) iOffset;
    }
}

HRESULT WINAPI IWineD3DVertexBufferImpl_ReleaseMemory(IWineD3DVertexBuffer* iface) {
  return WINED3D_OK;
}
