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
|
/* 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) ) {
|
switch(vboUsage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC) ) {
|
||||||
case D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC:
|
case D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC:
|
||||||
|
case D3DUSAGE_DYNAMIC:
|
||||||
TRACE("Gl usage = GL_STREAM_DRAW\n");
|
TRACE("Gl usage = GL_STREAM_DRAW\n");
|
||||||
glUsage = GL_STREAM_DRAW_ARB;
|
glUsage = GL_STREAM_DRAW_ARB;
|
||||||
break;
|
break;
|
||||||
case D3DUSAGE_WRITEONLY:
|
case D3DUSAGE_WRITEONLY:
|
||||||
|
default:
|
||||||
TRACE("Gl usage = GL_DYNAMIC_DRAW\n");
|
TRACE("Gl usage = GL_DYNAMIC_DRAW\n");
|
||||||
glUsage = GL_DYNAMIC_DRAW_ARB;
|
glUsage = GL_DYNAMIC_DRAW_ARB;
|
||||||
break;
|
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
|
/* 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) &&
|
if( GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) && Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) &&
|
||||||
(dxVersion > 7 || !conv) ) {
|
(dxVersion > 7 || !conv) ) {
|
||||||
CreateVBO(object);
|
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;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,6 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
||||||
This->draws = 0;
|
This->draws = 0;
|
||||||
|
|
||||||
if(This->declChanges > VB_MAXDECLCHANGES) {
|
if(This->declChanges > VB_MAXDECLCHANGES) {
|
||||||
if(This->resource.allocatedMemory) {
|
|
||||||
FIXME("Too much declaration changes, stopping converting\n");
|
FIXME("Too much declaration changes, stopping converting\n");
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
|
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
|
||||||
|
@ -306,11 +305,6 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
|
||||||
|
|
||||||
return;
|
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 {
|
} else {
|
||||||
/* However, it is perfectly fine to change the declaration every now and then. We don't want a game that
|
/* 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
|
* 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->dirtystart = 0;
|
||||||
This->dirtyend = 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;
|
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.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 if(This->strided.u.s.diffuse.dwStride) stride = This->strided.u.s.diffuse.dwStride;
|
||||||
else {
|
else {
|
||||||
/* That means that there is nothing to fixup. Upload everything into the VBO and
|
/* That means that there is nothing to fixup. Just upload from This->resource.allocatedMemory
|
||||||
* free 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");
|
TRACE("No conversion needed, locking directly into the VBO in future\n");
|
||||||
|
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
|
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
|
||||||
checkGLcall("glBindBufferARB");
|
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");
|
checkGLcall("glBufferSubDataARB");
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
return;
|
return;
|
||||||
|
@ -448,31 +416,8 @@ static HRESULT WINAPI IWineD3DVertexBufferImpl_Lock(IWineD3DVertexBuffer *iface
|
||||||
This->dirtyend = This->resource.size;
|
This->dirtyend = This->resource.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(This->resource.allocatedMemory) {
|
|
||||||
data = This->resource.allocatedMemory;
|
data = This->resource.allocatedMemory;
|
||||||
This->Flags |= VBFLAG_DIRTY;
|
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;
|
*ppbData = data + OffsetToLock;
|
||||||
|
|
||||||
TRACE("(%p) : returning memory of %p (base:%p,offset:%u)\n", This, data + OffsetToLock, 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;
|
return D3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!This->resource.allocatedMemory) {
|
if(This->Flags & VBFLAG_HASDESC) {
|
||||||
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);
|
IWineD3DVertexBufferImpl_PreLoad(iface);
|
||||||
}
|
}
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
|
|
Loading…
Reference in New Issue