wined3d: Activate a context before doing opengl calls.

This commit is contained in:
Stefan Dösinger 2007-03-17 23:00:39 +01:00 committed by Alexandre Julliard
parent 9789f993ce
commit fcb83e7111
11 changed files with 131 additions and 38 deletions

View File

@ -96,9 +96,12 @@ ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) {
/* class static */
void IWineD3DBaseTextureImpl_CleanUp(IWineD3DBaseTexture *iface) {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p) : textureName(%d)\n", This, This->baseTexture.textureName);
if (This->baseTexture.textureName != 0) {
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
glDeleteTextures(1, &This->baseTexture.textureName);
LEAVE_GL();
@ -236,7 +239,6 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) {
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
ENTER_GL();
/* Generate a texture name if we don't already have one */
if (This->baseTexture.textureName == 0) {
glGenTextures(1, &This->baseTexture.textureName);

View File

@ -706,6 +706,14 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
}
}
if (readTexture) {
BOOL oldInDraw = This->isInDraw;
/* PreLoad requires a context to load the texture, thus it will call ActivateContext.
* Set the isInDraw to true to signal PreLoad that it has a context. Will be tricky
* when using offscreen rendering with multithreading
*/
This->isInDraw = TRUE;
/* Do that before switching the context:
* Read the back buffer of the old drawable into the destination texture
*/
@ -713,6 +721,8 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
/* Assume that the drawable will be modified by some other things now */
((IWineD3DSurfaceImpl *) This->lastActiveRenderTarget)->Flags &= ~SFLAG_INDRAWABLE;
This->isInDraw = oldInDraw;
}
This->lastActiveRenderTarget = target;
if(oldRenderOffscreen != This->render_offscreen && This->depth_copy_state != WINED3D_DCS_NO_COPY) {

View File

@ -104,11 +104,23 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
unsigned int i,j;
BOOL setGlTextureDesc = FALSE;
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty);
if (This->baseTexture.textureName == 0) setGlTextureDesc = TRUE;
/* We only have to activate a context for gl when we're not drawing. In most cases PreLoad will be called during draw
* and a context was activated at the beginning of drawPrimitive
*/
if(!device->isInDraw) {
/* No danger of recursive calls, ActivateContext sets isInDraw to true when loading
* offscreen render targets into their texture
*/
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
}
IWineD3DCubeTexture_BindTexture(iface);
ENTER_GL();

View File

@ -250,6 +250,9 @@ static void CreateVBO(IWineD3DVertexBufferImpl *object) {
TRACE("Creating an OpenGL vertex buffer object for IWineD3DVertexBuffer %p Usage(%s)\n", object, debug_d3dusage(vboUsage));
ENTER_GL();
/* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
/* Make sure that the gl error is cleared. Do not use checkGLcall
* here because checkGLcall just prints a fixme and continues. However,
* if an error during VBO creation occurs we can fall back to non-vbo operation
@ -377,6 +380,9 @@ static void CreateIndexBufferVBO(IWineD3DDeviceImpl *This, IWineD3DIndexBufferIm
IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER);
ENTER_GL();
/* Make sure that a context is there. Needed in a multithreaded environment. Otherwise this call is a nop */
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
while(glGetError());
GL_EXTCALL(glGenBuffersARB(1, &object->vbo));
@ -1756,6 +1762,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Uninit3D(IWineD3DDevice *iface, D3DCB_D
if(!This->d3d_initialized) return WINED3DERR_INVALIDCALL;
ENTER_GL();
/* I don't think that the interface guarants that the device is destroyed from the same thread
* it was created. Thus make sure a context is active for the glDelete* calls
*/
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
/* Delete the pbuffer context if there is any */
if(This->pbufferContext) DestroyContext(This, This->pbufferContext);
@ -3674,6 +3687,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface,
WARN("NULL source vertex buffer\n");
return WINED3DERR_INVALIDCALL;
}
/* Need any context to write to the vbo. In a non-multithreaded environment a context is there anyway,
* and this call is quite performance critical, so don't call needlessly
*/
if(This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED) {
ENTER_GL();
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
}
/* We don't need the source vbo because this buffer is only used as
* a source for ProcessVertices. Avoid wasting resources by converting the
* buffer and loading the VBO
@ -4103,6 +4126,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) {
}
ENTER_GL();
if(This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED) {
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
/* We only have to do this if we need to read the, swapbuffers performs a flush for us */
glFlush();
checkGLcall("glFlush");
@ -4152,6 +4178,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Coun
}
ENTER_GL();
/* This is for offscreen rendering as well as for multithreading, thus activate the set render target
* and not the last active one.
*/
ActivateContext(This, This->render_targets[0], CTXUSAGE_RESOURCELOAD);
glEnable(GL_SCISSOR_TEST);
checkGLcall("glEnable GL_SCISSOR_TEST");
@ -4755,6 +4785,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
}
ENTER_GL();
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
checkGLcall("glActiveTextureARB");
@ -4995,6 +5028,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
if(Swapchain->backBuffer[0] != Back) {
TRACE("Changing the back buffer from %p to %p\n", Swapchain->backBuffer, Back);
/* What to do about the context here in the case of multithreading? Not sure.
* This function is called by IDirect3D7::CreateDevice so in theory its initialization code
*/
ENTER_GL();
if(!Swapchain->backBuffer[0]) {
/* GL was told to draw to the front buffer at creation,
@ -5248,6 +5285,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetCursorProperties(IWineD3DDevice* i
/* some basic validation checks */
if(This->cursorTexture) {
ENTER_GL();
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
glDeleteTextures(1, &This->cursorTexture);
LEAVE_GL();
This->cursorTexture = 0;
@ -5419,6 +5457,7 @@ static void updateSurfaceDesc(IWineD3DSurfaceImpl *surface, WINED3DPRESENT_PARAM
}
if(surface->glDescription.textureName) {
ENTER_GL();
ActivateContext(This, This->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
glDeleteTextures(1, &surface->glDescription.textureName);
LEAVE_GL();
surface->glDescription.textureName = 0;

View File

@ -59,7 +59,10 @@ static ULONG WINAPI IWineD3DIndexBufferImpl_Release(IWineD3DIndexBuffer *iface)
TRACE("(%p) : Releasing from %d\n", This, ref + 1);
if (ref == 0) {
if(This->vbo) {
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
/* 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
@ -153,7 +156,13 @@ static HRESULT WINAPI IWineD3DIndexBufferImpl_Unlock(IWineD3DIndexBuffer *iface)
/* For now load in unlock */
if(locks == 0 && This->vbo) {
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
ENTER_GL();
if(device->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, This->vbo));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
@ -163,7 +172,7 @@ static HRESULT WINAPI IWineD3DIndexBufferImpl_Unlock(IWineD3DIndexBuffer *iface)
This->dirtystart = 0;
This->dirtyend = 0;
/* TODO: Move loading into preload when the buffer is used, that avoids dirtifying the state */
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_INDEXBUFFER);
}
return WINED3D_OK;
}

View File

@ -60,12 +60,8 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
TRACE("(%p) : Calling glGetCompressedTexImageARB level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level,
This->glDescription.glFormat, This->glDescription.glType, This->resource.allocatedMemory);
ENTER_GL();
GL_EXTCALL(glGetCompressedTexImageARB(This->glDescription.target, This->glDescription.level, This->resource.allocatedMemory));
checkGLcall("glGetCompressedTexImageARB()");
LEAVE_GL();
}
} else {
void *mem;
@ -89,14 +85,10 @@ static void surface_download_data(IWineD3DSurfaceImpl *This) {
TRACE("(%p) : Calling glGetTexImage level %d, format %#x, type %#x, data %p\n", This, This->glDescription.level,
This->glDescription.glFormat, This->glDescription.glType, mem);
ENTER_GL();
glGetTexImage(This->glDescription.target, This->glDescription.level, This->glDescription.glFormat,
This->glDescription.glType, mem);
checkGLcall("glGetTexImage()");
LEAVE_GL();
if (This->Flags & SFLAG_NONPOW2) {
LPBYTE src_data, dst_data;
int y;
@ -258,6 +250,7 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
* and the lastActiveRenderTarget member shouldn't matter
*/
if(swapchain) {
ENTER_GL(); /* For ActivateContext */
if(swapchain->backBuffer && swapchain->backBuffer[0] != iface) {
TRACE("Activating primary back buffer\n");
ActivateContext(device, swapchain->backBuffer[0], CTXUSAGE_RESOURCELOAD);
@ -272,6 +265,7 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
*/
device->lastActiveRenderTarget = (IWineD3DSurface *) 0xdeadbabe;
}
LEAVE_GL();
} else {
/* May happen during ddraw uninitialization */
TRACE("Render target set, but swapchain does not exist!\n");
@ -281,6 +275,15 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) {
if (This->glDescription.textureName != 0) { /* release the openGL texture.. */
ENTER_GL();
/* Need a context to destroy the texture. Use the currently active render target, but only if
* the primary render target exists. Otherwise lastActiveRenderTarget is garbage, see above.
* When destroying the primary rt, Uninit3D will activate a context before doing anything
*/
if(device->render_targets[0]) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
TRACE("Deleting texture %d\n", This->glDescription.textureName);
glDeleteTextures(1, &This->glDescription.textureName);
LEAVE_GL();
@ -338,13 +341,11 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPriority(IWineD3DSurface *iface) {
}
void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
/* TODO: re-write the way textures and managed,
* use a 'opengl context manager' to manage RenderTarget surfaces
** *********************************************************/
/* TODO: check for locks */
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DBaseTexture *baseTexture = NULL;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p)Checking to see if the container is a base texture\n", This);
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
TRACE("Passing to conatiner\n");
@ -352,10 +353,12 @@ void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
IWineD3DBaseTexture_Release(baseTexture);
} else {
TRACE("(%p) : About to load surface\n", This);
ENTER_GL();
#if 0 /* TODO: context manager support */
IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_2D, ENABLED, NOW /* make sure the state is applied now */);
#endif
if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
glEnable(This->glDescription.target);/* make sure texture support is enabled in this context */
if (!This->glDescription.level) {
if (!This->glDescription.textureName) {
@ -377,11 +380,6 @@ void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
tmp = 0.9f;
glPrioritizeTextures(1, &This->glDescription.textureName, &tmp);
}
/* TODO: disable texture support, if it wastn't enabled when we entered. */
#if 0 /* TODO: context manager support */
IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_2D, DISABLED,DELAYED
/* we don't care when the state is disabled(if atall) */);
#endif
LEAVE_GL();
}
return;
@ -768,24 +766,25 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED
/* This path is for normal surfaces, offscreen render targets and everything else that is in a gl texture */
TRACE("locking an ordinarary surface\n");
/* TODO: Make sure that *any* context is active for this thread. It is not important which context that is,
* nor that is has any special setup(CTXUSAGE_LOADRESOURCE is fine), but the code below needs a context.
* A context is guaranteed to be there in a single threaded environment, but not with multithreading
*/
if (0 != This->glDescription.textureName) {
/* Now I have to copy thing bits back */
ENTER_GL();
if(myDevice->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED) {
ActivateContext(myDevice, myDevice->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
/* Make sure that a proper texture unit is selected, bind the texture and dirtify the sampler to restore the texture on the next draw */
if (GL_SUPPORT(ARB_MULTITEXTURE)) {
ENTER_GL();
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB));
checkGLcall("glActiveTextureARB");
LEAVE_GL();
}
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(0));
IWineD3DSurface_PreLoad(iface);
surface_download_data(This);
LEAVE_GL();
}
/* The local copy is now up to date to the opengl one because a full download was done */

View File

@ -146,6 +146,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
ENTER_GL();
/* Does glXSwapBuffers need a glx context? I don't think so. Blt will activate its own context if needed */
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) {
IWineD3DSurfaceImpl cursor;

View File

@ -97,11 +97,21 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
unsigned int i;
BOOL setGlTextureDesc = FALSE;
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p) : About to load texture\n", This);
if (This->baseTexture.textureName == 0) setGlTextureDesc = TRUE;
if(!device->isInDraw) {
/* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture, thus no danger of
* recursive calls
*/
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL();
}
IWineD3DTexture_BindTexture(iface);
ENTER_GL();
/* If were dirty then reload the surfaces */

View File

@ -810,7 +810,8 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2],
&tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx);
ENTER_GL();
/* This is called by a state handler which has the gl lock held and a context for the thread */
switch(op)
{
@ -1082,7 +1083,6 @@ void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEX
checkGLcall("set_tex_op_nvrc()\n");
LEAVE_GL();
}
static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
@ -1160,7 +1160,7 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
ENTER_GL();
/* This is called by a state handler which has the gl lock held and a context for the thread */
/* Note: Operations usually involve two ars, src0 and src1 and are operations of
the form (a1 <operation> a2). However, some of the more complex operations
@ -1681,7 +1681,6 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
LEAVE_GL();
return;
}
} /* GL_NV_texture_env_combine4 */
@ -2148,7 +2147,6 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
break;
default:
FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
LEAVE_GL();
return;
}
}
@ -2158,13 +2156,10 @@ void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
LEAVE_GL();
return;
}
}
LEAVE_GL();
/* After all the extensions, if still unhandled, report fixme */
FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
#undef GLINFO_LOCATION

View File

@ -62,7 +62,10 @@ static ULONG WINAPI IWineD3DVertexBufferImpl_Release(IWineD3DVertexBuffer *iface
if (ref == 0) {
if(This->vbo) {
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
checkGLcall("glDeleteBuffersARB");
LEAVE_GL();
@ -244,6 +247,7 @@ inline BOOL WINAPI IWineD3DVertexBufferImpl_FindDecl(IWineD3DVertexBufferImpl *T
static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *iface) {
IWineD3DVertexBufferImpl *This = (IWineD3DVertexBufferImpl *) iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BYTE *data;
UINT start = 0, end = 0, stride = 0;
BOOL declChanged = FALSE;
@ -259,7 +263,7 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
}
/* Reading the declaration makes only sense if the stateblock is finalized and the buffer bound to a stream */
if(This->resource.wineD3DDevice->isInDraw && This->bindCount > 0) {
if(device->isInDraw && This->bindCount > 0) {
declChanged = IWineD3DVertexBufferImpl_FindDecl(This);
} else if(This->Flags & VBFLAG_HASDESC) {
/* Reuse the declaration stored in the buffer. It will most likely not change, and if it does
@ -284,6 +288,7 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
if(This->declChanges > VB_MAXDECLCHANGES) {
FIXME("Too much declaration changes, stopping converting\n");
ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
GL_EXTCALL(glDeleteBuffersARB(1, &This->vbo));
checkGLcall("glDeleteBuffersARB");
LEAVE_GL();
@ -294,7 +299,7 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
* to force a reload. This happens only once per changed vertexbuffer and should occur rather
* rarely
*/
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_STREAMSRC);
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
return;
}
@ -337,6 +342,9 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
TRACE("No conversion needed, locking directly into the VBO in future\n");
ENTER_GL();
if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end-start, This->resource.allocatedMemory + start));
@ -367,6 +375,9 @@ static void WINAPI IWineD3DVertexBufferImpl_PreLoad(IWineD3DVertexBuffer *if
This->strided.u.s.specular.dwType == WINED3DDECLTYPE_SHORT4 || This->strided.u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR);
ENTER_GL();
if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, This->vbo));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, start, end - start, data));

View File

@ -94,12 +94,16 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
/* Overrider the IWineD3DResource Preload method */
UINT i;
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
TRACE("(%p) : About to load texture\n", This);
IWineD3DVolumeTexture_BindTexture(iface);
ENTER_GL();
if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
}
/* If were dirty then reload the volumes */
if(This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) {