Commit 2a7a2371 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Merge indexbuffer and buffer implementations.

parent 3ed94329
...@@ -54,11 +54,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) ...@@ -54,11 +54,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
while (glGetError() != GL_NO_ERROR); while (glGetError() != GL_NO_ERROR);
/* Basically the FVF parameter passed to CreateVertexBuffer is no good /* Basically the FVF parameter passed to CreateVertexBuffer is no good
* It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with * It is the FVF set with IWineD3DDevice::SetFVF or the Vertex Declaration set with
* IWineD3DDevice::SetVertexDeclaration that decides how the vertices in the buffer * 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 * 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. * to check if the rhw and color values are in the correct format.
*/ */
GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object)); GL_EXTCALL(glGenBuffersARB(1, &This->buffer_object));
error = glGetError(); error = glGetError();
...@@ -68,7 +68,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) ...@@ -68,7 +68,11 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
goto fail; goto fail;
} }
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
error = glGetError(); error = glGetError();
if (error != GL_NO_ERROR) if (error != GL_NO_ERROR)
{ {
...@@ -99,7 +103,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This) ...@@ -99,7 +103,7 @@ static void buffer_create_buffer_object(struct wined3d_buffer *This)
* so we are safe with calling glBufferData once with a NULL ptr and * so we are safe with calling glBufferData once with a NULL ptr and
* calling glBufferSubData on updates * calling glBufferSubData on updates
*/ */
GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, This->resource.size, NULL, gl_usage)); GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, This->resource.size, NULL, gl_usage));
error = glGetError(); error = glGetError();
if (error != GL_NO_ERROR) if (error != GL_NO_ERROR)
{ {
...@@ -298,9 +302,14 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) ...@@ -298,9 +302,14 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
unsigned int i; unsigned int i;
/* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer. /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
* Once we have our declaration there is no need to look it up again. * Once we have our declaration there is no need to look it up again. Index buffers also never need
* conversion, so once the (empty) conversion structure is created don't bother checking again
*/ */
if (((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 && This->flags & WINED3D_BUFFER_HASDESC) return FALSE; if (This->flags & WINED3D_BUFFER_HASDESC)
{
if(((IWineD3DImpl *)device->wineD3D)->dxVersion == 7 ||
This->resource.format_desc->format != WINED3DFMT_VERTEXDATA) return FALSE;
}
TRACE("Finding vertex buffer conversion information\n"); TRACE("Finding vertex buffer conversion information\n");
/* Certain declaration types need some fixups before we can pass them to /* Certain declaration types need some fixups before we can pass them to
...@@ -439,10 +448,15 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This) ...@@ -439,10 +448,15 @@ static void buffer_check_buffer_object_size(struct wined3d_buffer *This)
if (This->buffer_object_size != size) if (This->buffer_object_size != size)
{ {
TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size); TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size);
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB"); checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, This->buffer_object_usage)); GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, size, NULL, This->buffer_object_usage));
This->buffer_object_size = size; This->buffer_object_size = size;
checkGLcall("glBufferDataARB"); checkGLcall("glBufferDataARB");
LEAVE_GL(); LEAVE_GL();
...@@ -734,6 +748,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) ...@@ -734,6 +748,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
This->dirty_start = 0; This->dirty_start = 0;
This->dirty_end = 0; This->dirty_end = 0;
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
if (!This->conversion_map) if (!This->conversion_map)
{ {
/* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory /* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory
...@@ -747,9 +766,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) ...@@ -747,9 +766,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
} }
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB"); checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start)); GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end-start, This->resource.allocatedMemory + start));
checkGLcall("glBufferSubDataARB"); checkGLcall("glBufferSubDataARB");
LEAVE_GL(); LEAVE_GL();
return; return;
...@@ -793,9 +812,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) ...@@ -793,9 +812,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
} }
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB"); checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, vertices * This->conversion_stride, data)); GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, 0, vertices * This->conversion_stride, data));
checkGLcall("glBufferSubDataARB"); checkGLcall("glBufferSubDataARB");
LEAVE_GL(); LEAVE_GL();
} }
...@@ -832,9 +851,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface) ...@@ -832,9 +851,9 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
} }
ENTER_GL(); ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->buffer_object)); GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB"); checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data + start)); GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end - start, data + start));
checkGLcall("glBufferSubDataARB"); checkGLcall("glBufferSubDataARB");
LEAVE_GL(); LEAVE_GL();
} }
...@@ -947,253 +966,3 @@ const struct IWineD3DBufferVtbl wined3d_buffer_vtbl = ...@@ -947,253 +966,3 @@ const struct IWineD3DBufferVtbl wined3d_buffer_vtbl =
buffer_Unmap, buffer_Unmap,
buffer_GetDesc, buffer_GetDesc,
}; };
/* IUnknown methods */
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_QueryInterface(IWineD3DIndexBuffer *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_IWineD3DIndexBuffer)
|| IsEqualGUID(riid, &IID_IWineD3DResource)
|| IsEqualGUID(riid, &IID_IWineD3DBase)
|| IsEqualGUID(riid, &IID_IUnknown))
{
IUnknown_AddRef(iface);
*object = iface;
return S_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
*object = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_AddRef(IWineD3DIndexBuffer *iface)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
ULONG refcount = InterlockedIncrement(&This->resource.ref);
TRACE("%p increasing refcount to %u\n", This, refcount);
return refcount;
}
static ULONG STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
ULONG refcount = InterlockedDecrement(&This->resource.ref);
TRACE("%p decreasing refcount to %u\n", This, refcount);
if (!refcount)
{
if (This->vbo)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
/* No need to manually unset the buffer. glDeleteBuffers unsets it for the current context,
* but not for other contexts. However, because the d3d buffer is destroyed the app has to
* unset it before doing the next draw, thus dirtifying the index buffer state and forcing
* binding a new buffer
*/
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
checkGLcall("glDeleteBuffersARB");
LEAVE_GL();
}
resource_cleanup((IWineD3DResource *)iface);
HeapFree(GetProcessHeap(), 0, This);
}
return refcount;
}
/* IWineD3DBase methods */
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetParent(IWineD3DIndexBuffer *iface, IUnknown **parent)
{
return resource_get_parent((IWineD3DResource *)iface, parent);
}
/* IWineD3DResource methods */
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDevice(IWineD3DIndexBuffer *iface, IWineD3DDevice **device)
{
return resource_get_device((IWineD3DResource *)iface, device);
}
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPrivateData(IWineD3DIndexBuffer *iface,
REFGUID guid, const void *data, DWORD data_size, DWORD flags)
{
return resource_set_private_data((IWineD3DResource *)iface, guid, data, data_size, flags);
}
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPrivateData(IWineD3DIndexBuffer *iface,
REFGUID guid, void *data, DWORD *data_size)
{
return resource_get_private_data((IWineD3DResource *)iface, guid, data, data_size);
}
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_FreePrivateData(IWineD3DIndexBuffer *iface, REFGUID guid)
{
return resource_free_private_data((IWineD3DResource *)iface, guid);
}
static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_SetPriority(IWineD3DIndexBuffer *iface, DWORD priority)
{
return resource_set_priority((IWineD3DResource *)iface, priority);
}
static DWORD STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetPriority(IWineD3DIndexBuffer *iface)
{
return resource_get_priority((IWineD3DResource *)iface);
}
static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_PreLoad(IWineD3DIndexBuffer *iface)
{
TRACE("iface %p\n", iface);
}
static void STDMETHODCALLTYPE IWineD3DIndexBufferImpl_UnLoad(IWineD3DIndexBuffer *iface)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *) iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p)\n", This);
/* This is easy: The whole content is shadowed in This->resource.allocatedMemory,
* so we only have to destroy the vbo. Only do it if we have a vbo, which implies
* that vbos are supported.
* (TODO: Make a IWineD3DBuffer base class for index and vertex buffers and share
* this code. Also needed for D3D10)
*/
if (This->vbo)
{
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
checkGLcall("glDeleteBuffersARB");
LEAVE_GL();
This->vbo = 0;
}
}
static WINED3DRESOURCETYPE STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetType(IWineD3DIndexBuffer *iface)
{
return resource_get_type((IWineD3DResource *)iface);
}
/* IWineD3DIndexBuffer methods */
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Map(IWineD3DIndexBuffer *iface,
UINT OffsetToLock, UINT SizeToLock, BYTE **ppbData, DWORD Flags)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
TRACE("(%p) : offset %d, size %d, Flags=%x\n", This, OffsetToLock, SizeToLock, Flags);
InterlockedIncrement(&This->lockcount);
*ppbData = This->resource.allocatedMemory + OffsetToLock;
if (Flags & (WINED3DLOCK_READONLY | WINED3DLOCK_NO_DIRTY_UPDATE) || !This->vbo)
{
return WINED3D_OK;
}
if (This->dirtystart != This->dirtyend)
{
if (This->dirtystart > OffsetToLock) This->dirtystart = OffsetToLock;
if (SizeToLock)
{
if (This->dirtyend < OffsetToLock + SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
}
else
{
This->dirtyend = This->resource.size;
}
}
else
{
This->dirtystart = OffsetToLock;
if (SizeToLock) This->dirtyend = OffsetToLock + SizeToLock;
else This->dirtyend = This->resource.size;
}
return WINED3D_OK;
}
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_Unmap(IWineD3DIndexBuffer *iface)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
ULONG locks = InterlockedDecrement(&This->lockcount);
TRACE("(%p)\n", This);
/* For now load in unlock */
if (!locks && This->vbo && (This->dirtyend - This->dirtystart) > 0)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->vbo));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->dirtystart,
This->dirtyend - This->dirtystart, This->resource.allocatedMemory + This->dirtystart));
checkGLcall("glBufferSubDataARB");
LEAVE_GL();
This->dirtystart = 0;
This->dirtyend = 0;
/* TODO: Move loading into preload when the buffer is used, that avoids dirtifying the state */
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_INDEXBUFFER);
}
return WINED3D_OK;
}
static HRESULT STDMETHODCALLTYPE IWineD3DIndexBufferImpl_GetDesc(IWineD3DIndexBuffer *iface,
WINED3DBUFFER_DESC *pDesc)
{
IWineD3DIndexBufferImpl *This = (IWineD3DIndexBufferImpl *)iface;
TRACE("(%p)\n", This);
pDesc->Format = This->resource.format_desc->format;
pDesc->Type = This->resource.resourceType;
pDesc->Usage = This->resource.usage;
pDesc->Pool = This->resource.pool;
pDesc->Size = This->resource.size;
return WINED3D_OK;
}
const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl =
{
/* IUnknown methods */
IWineD3DIndexBufferImpl_QueryInterface,
IWineD3DIndexBufferImpl_AddRef,
IWineD3DIndexBufferImpl_Release,
/* IWineD3DBase methods */
IWineD3DIndexBufferImpl_GetParent,
/* IWineD3DResource methods */
IWineD3DIndexBufferImpl_GetDevice,
IWineD3DIndexBufferImpl_SetPrivateData,
IWineD3DIndexBufferImpl_GetPrivateData,
IWineD3DIndexBufferImpl_FreePrivateData,
IWineD3DIndexBufferImpl_SetPriority,
IWineD3DIndexBufferImpl_GetPriority,
IWineD3DIndexBufferImpl_PreLoad,
IWineD3DIndexBufferImpl_UnLoad,
IWineD3DIndexBufferImpl_GetType,
/* IWineD3DIndexBuffer methods */
IWineD3DIndexBufferImpl_Map,
IWineD3DIndexBufferImpl_Unmap,
IWineD3DIndexBufferImpl_GetDesc,
};
...@@ -463,6 +463,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface, ...@@ -463,6 +463,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateBuffer(IWineD3DDevice *iface,
HeapFree(GetProcessHeap(), 0, object); HeapFree(GetProcessHeap(), 0, object);
return hr; return hr;
} }
object->buffer_type_hint = GL_ARRAY_BUFFER_ARB;
TRACE("Created resource %p\n", object); TRACE("Created resource %p\n", object);
...@@ -540,6 +541,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac ...@@ -540,6 +541,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
*ppVertexBuffer = NULL; *ppVertexBuffer = NULL;
return hr; return hr;
} }
object->buffer_type_hint = GL_ARRAY_BUFFER_ARB;
TRACE("(%p) : Created resource %p\n", This, object); TRACE("(%p) : Created resource %p\n", This, object);
...@@ -580,62 +582,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac ...@@ -580,62 +582,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
return WINED3D_OK; return WINED3D_OK;
} }
static void CreateIndexBufferVBO(IWineD3DDeviceImpl *This, IWineD3DIndexBufferImpl *object) { static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage,
GLenum error, glUsage;
TRACE("Creating VBO for Index Buffer %p\n", object);
/* The following code will modify the ELEMENT_ARRAY_BUFFER binding, make sure it is
* restored on the next draw
*/
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
/* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
while(glGetError());
GL_EXTCALL(glGenBuffersARB(1, &object->vbo));
error = glGetError();
if(error != GL_NO_ERROR || object->vbo == 0) {
ERR("Creating a vbo failed with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error);
goto out;
}
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->vbo));
error = glGetError();
if(error != GL_NO_ERROR) {
ERR("Failed to bind index buffer with error %s (%#x), continuing without vbo for this buffer\n", debug_glerror(error), error);
goto out;
}
/* Use static write only usage for now. Dynamic index buffers stay in sysmem, and due to the sysmem
* copy no readback will be needed
*/
glUsage = GL_STATIC_DRAW_ARB;
GL_EXTCALL(glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, object->resource.size, NULL, glUsage));
error = glGetError();
if(error != GL_NO_ERROR) {
ERR("Failed to initialize the index buffer with error %s (%#x)\n", debug_glerror(error), error);
goto out;
}
LEAVE_GL();
TRACE("Successfully created vbo %d for index buffer %p\n", object->vbo, object);
return;
out:
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
GL_EXTCALL(glDeleteBuffersARB(1, &object->vbo));
LEAVE_GL();
object->vbo = 0;
}
static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface, UINT Length, DWORD Usage,
WINED3DFORMAT Format, WINED3DPOOL Pool, IWineD3DIndexBuffer** ppIndexBuffer, WINED3DFORMAT Format, WINED3DPOOL Pool, IWineD3DIndexBuffer** ppIndexBuffer,
HANDLE *sharedHandle, IUnknown *parent) { HANDLE *sharedHandle, IUnknown *parent) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info); const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(Format, &This->adapter->gl_info);
IWineD3DIndexBufferImpl *object; struct wined3d_buffer *object;
HRESULT hr; HRESULT hr;
TRACE("(%p) Creating index buffer\n", This); TRACE("(%p) Creating index buffer\n", This);
...@@ -649,7 +601,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface ...@@ -649,7 +601,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
return WINED3DERR_OUTOFVIDEOMEMORY; return WINED3DERR_OUTOFVIDEOMEMORY;
} }
object->lpVtbl = &IWineD3DIndexBuffer_Vtbl; object->vtbl = &wined3d_buffer_vtbl;
hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent); hr = resource_init(&object->resource, WINED3DRTYPE_BUFFER, This, Length, Usage, format_desc, Pool, parent);
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -658,13 +610,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface ...@@ -658,13 +610,14 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateIndexBuffer(IWineD3DDevice *iface
*ppIndexBuffer = NULL; *ppIndexBuffer = NULL;
return hr; return hr;
} }
object->buffer_type_hint = GL_ELEMENT_ARRAY_BUFFER_ARB;
TRACE("(%p) : Created resource %p\n", This, object); TRACE("(%p) : Created resource %p\n", This, object);
IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object); IWineD3DDeviceImpl_AddResource(iface, (IWineD3DResource *)object);
if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) { if(Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) && GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
CreateIndexBufferVBO(This, object); object->flags |= WINED3D_BUFFER_CREATEBO;
} }
TRACE("(%p) : Len=%d, Use=%x, Format=(%u,%s), Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage, Format, TRACE("(%p) : Len=%d, Use=%x, Format=(%u,%s), Pool=%d - Memory@%p, Iface@%p\n", This, Length, Usage, Format,
...@@ -3704,9 +3657,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWine ...@@ -3704,9 +3657,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetIndices(IWineD3DDevice *iface, IWine
if(oldIdxs != pIndexData) { if(oldIdxs != pIndexData) {
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
if(pIndexData) IWineD3DIndexBuffer_AddRef(pIndexData); if(pIndexData) {
if(oldIdxs) IWineD3DIndexBuffer_Release(oldIdxs); InterlockedIncrement(&((struct wined3d_buffer *)pIndexData)->bind_count);
IWineD3DIndexBuffer_AddRef(pIndexData);
}
if(oldIdxs) {
InterlockedDecrement(&((struct wined3d_buffer *)oldIdxs)->bind_count);
IWineD3DIndexBuffer_Release(oldIdxs);
}
} }
return WINED3D_OK; return WINED3D_OK;
} }
...@@ -5700,7 +5660,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if ...@@ -5700,7 +5660,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
This->stateBlock->streamIsUP = FALSE; This->stateBlock->streamIsUP = FALSE;
} }
vbo = ((IWineD3DIndexBufferImpl *) pIB)->vbo; vbo = ((struct wined3d_buffer *) pIB)->buffer_object;
TRACE("(%p) : min %u, vertex count %u, startIdx %u, index count %u\n", TRACE("(%p) : min %u, vertex count %u, startIdx %u, index count %u\n",
This, minIndex, NumVertices, startIndex, index_count); This, minIndex, NumVertices, startIndex, index_count);
...@@ -5718,7 +5678,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if ...@@ -5718,7 +5678,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitive(IWineD3DDevice *if
} }
drawPrimitive(iface, index_count, NumVertices, startIndex, idxStride, drawPrimitive(iface, index_count, NumVertices, startIndex, idxStride,
vbo ? NULL : ((IWineD3DIndexBufferImpl *) pIB)->resource.allocatedMemory, minIndex); vbo ? NULL : ((struct wined3d_buffer *) pIB)->resource.allocatedMemory, minIndex);
return WINED3D_OK; return WINED3D_OK;
} }
......
...@@ -95,7 +95,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i ...@@ -95,7 +95,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_i
* idxData will be != NULL * idxData will be != NULL
*/ */
if(idxData == NULL) { if(idxData == NULL) {
idxData = ((IWineD3DIndexBufferImpl *) This->stateBlock->pIndexData)->resource.allocatedMemory; idxData = ((struct wined3d_buffer *) This->stateBlock->pIndexData)->resource.allocatedMemory;
} }
if (idxSize == 2) pIdxBufS = idxData; if (idxSize == 2) pIdxBufS = idxData;
...@@ -413,7 +413,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream ...@@ -413,7 +413,7 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream
* idxData will be != NULL * idxData will be != NULL
*/ */
if(idxData == NULL) { if(idxData == NULL) {
idxData = ((IWineD3DIndexBufferImpl *) stateblock->pIndexData)->resource.allocatedMemory; idxData = ((struct wined3d_buffer *) stateblock->pIndexData)->resource.allocatedMemory;
} }
if (idxSize == 2) pIdxBufS = idxData; if (idxSize == 2) pIdxBufS = idxData;
......
...@@ -4631,8 +4631,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D ...@@ -4631,8 +4631,8 @@ static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) { if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
} else { } else {
IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData; struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData;
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo)); GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
} }
} }
......
...@@ -1405,24 +1405,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid, ...@@ -1405,24 +1405,6 @@ HRESULT resource_set_private_data(IWineD3DResource *iface, REFGUID guid,
#define RESOURCE_ALIGNMENT 32 #define RESOURCE_ALIGNMENT 32
/***************************************************************************** /*****************************************************************************
* IWineD3DIndexBuffer implementation structure (extends IWineD3DResourceImpl)
*/
typedef struct IWineD3DIndexBufferImpl
{
/* IUnknown & WineD3DResource Information */
const IWineD3DIndexBufferVtbl *lpVtbl;
IWineD3DResourceClass resource;
GLuint vbo;
UINT dirtystart, dirtyend;
LONG lockcount;
/* WineD3DVertexBuffer specifics */
} IWineD3DIndexBufferImpl;
extern const IWineD3DIndexBufferVtbl IWineD3DIndexBuffer_Vtbl;
/*****************************************************************************
* IWineD3DBaseTexture D3D- > openGL state map lookups * IWineD3DBaseTexture D3D- > openGL state map lookups
*/ */
#define WINED3DFUNC_NOTSUPPORTED -2 #define WINED3DFUNC_NOTSUPPORTED -2
...@@ -2103,6 +2085,7 @@ struct wined3d_buffer ...@@ -2103,6 +2085,7 @@ struct wined3d_buffer
GLuint buffer_object; GLuint buffer_object;
GLenum buffer_object_usage; GLenum buffer_object_usage;
GLenum buffer_type_hint;
UINT buffer_object_size; UINT buffer_object_size;
LONG bind_count; LONG bind_count;
DWORD flags; DWORD flags;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment