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