wined3d: Do not release the local vertex buffer copy.
This commit is contained in:
parent
40c85a60b7
commit
e6fedfca7a
|
@ -355,25 +355,20 @@ static void CreateVBO(IWineD3DVertexBufferImpl *object) {
|
|||
}
|
||||
|
||||
/* Don't use static, because dx apps tend to update the buffer
|
||||
* quite often even if they specify 0 usage
|
||||
* 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 & (D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC) ) {
|
||||
case D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC:
|
||||
case D3DUSAGE_DYNAMIC:
|
||||
TRACE("Gl usage = GL_STREAM_DRAW\n");
|
||||
glUsage = GL_STREAM_DRAW_ARB;
|
||||
break;
|
||||
case D3DUSAGE_WRITEONLY:
|
||||
default:
|
||||
TRACE("Gl usage = GL_DYNAMIC_DRAW\n");
|
||||
glUsage = GL_DYNAMIC_DRAW_ARB;
|
||||
break;
|
||||
case D3DUSAGE_DYNAMIC:
|
||||
TRACE("Gl usage = GL_STREAM_COPY\n");
|
||||
glUsage = GL_STREAM_COPY_ARB;
|
||||
break;
|
||||
default:
|
||||
TRACE("Gl usage = GL_DYNAMIC_COPY\n");
|
||||
glUsage = GL_DYNAMIC_COPY_ARB;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reserve memory for the buffer. The amount of data won't change
|
||||
|
@ -444,13 +439,6 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexBuffer(IWineD3DDevice *ifac
|
|||
if( GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) && Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) &&
|
||||
(dxVersion > 7 || !conv) ) {
|
||||
CreateVBO(object);
|
||||
|
||||
/* DX7 buffers can be locked directly into the VBO (no conversion, see above */
|
||||
if(dxVersion == 7 && object->vbo) {
|
||||
HeapFree(GetProcessHeap(), 0, object->resource.allocatedMemory);
|
||||
object->resource.allocatedMemory = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
|
|
@ -289,7 +289,6 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
|||
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));
|
||||
|
@ -306,11 +305,6 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
|||
|
||||
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
|
||||
|
@ -339,46 +333,20 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
|||
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
|
||||
/* 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
|
||||
* the stride is 0, for instancing emulation, vertex blending emulation or shader emulation.
|
||||
*/
|
||||
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));
|
||||
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start));
|
||||
checkGLcall("glBufferSubDataARB");
|
||||
LEAVE_GL();
|
||||
return;
|
||||
|
@ -448,31 +416,8 @@ static HRESULT WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface
|
|||
This->dirtyend = 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 & WINED3DLOCK_DISCARD) ) {
|
||||
mode = GL_WRITE_ONLY_ARB;
|
||||
} else if( Flags & (WINED3DLOCK_READONLY | WINED3DLOCK_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);
|
||||
|
@ -491,14 +436,7 @@ HRESULT WINAPI IWineD3DVertexBufferImpl_Unlock(IWineD3DVertexBuffer *iface) {
|
|||
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){
|
||||
if(This->Flags & VBFLAG_HASDESC) {
|
||||
IWineD3DVertexBufferImpl_PreLoad(iface);
|
||||
}
|
||||
return WINED3D_OK;
|
||||
|
|
Loading…
Reference in New Issue