Commit eeb54b99 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Keep better track of where we're using wined3d contexts.

The idea here is that we can restore the thread's current GL context on context_release() if it doesn't correspond to the current wined3d context on context_acquire().
parent 401173ff
......@@ -4427,15 +4427,22 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
ENTER_GL();
if(shader_data->num_gl_shaders) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
if (shader_data->num_gl_shaders)
{
struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
}
LEAVE_GL();
for(i = 0; i < shader_data->num_gl_shaders; i++) {
GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
context_release(context);
}
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
This->baseShader.backend_data = NULL;
......@@ -4445,15 +4452,22 @@ static void shader_arb_destroy(IWineD3DBaseShader *iface) {
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
ENTER_GL();
if(shader_data->num_gl_shaders) ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
if (shader_data->num_gl_shaders)
{
struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
for (i = 0; i < shader_data->num_gl_shaders; ++i)
{
GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
}
LEAVE_GL();
for(i = 0; i < shader_data->num_gl_shaders; i++) {
GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId));
checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader_data->gl_shaders[i].prgId))");
context_release(context);
}
LEAVE_GL();
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
This->baseShader.backend_data = NULL;
......
......@@ -83,10 +83,11 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
{
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context = NULL;
if(This->baseTexture.texture_rgb.name ||
This->baseTexture.texture_srgb.name) {
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
if (This->baseTexture.texture_rgb.name || This->baseTexture.texture_srgb.name)
{
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
}
if(This->baseTexture.texture_rgb.name) {
......@@ -95,6 +96,9 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
if(This->baseTexture.texture_srgb.name) {
gltexture_delete(&This->baseTexture.texture_srgb);
}
if (context) context_release(context);
This->baseTexture.texture_rgb.dirty = TRUE;
This->baseTexture.texture_srgb.dirty = TRUE;
}
......@@ -161,7 +165,8 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT
* Or should we delay the applying until the texture is used for drawing? For now, apply
* immediately.
*/
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
struct wined3d_context *context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
glBindTexture(textureDimensions, This->baseTexture.texture_rgb.name);
checkGLcall("glBindTexture");
......@@ -183,6 +188,8 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST)");
}
LEAVE_GL();
context_release(context);
}
This->baseTexture.filterType = FilterType;
TRACE("(%p) :\n", This);
......
......@@ -605,8 +605,9 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
if (This->buffer_object)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context;
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
/* Download the buffer, but don't permanently enable double buffering */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
......@@ -621,6 +622,8 @@ static void STDMETHODCALLTYPE buffer_UnLoad(IWineD3DBuffer *iface)
LEAVE_GL();
This->buffer_object = 0;
This->flags |= WINED3D_BUFFER_CREATEBO; /* Recreate the buffer object next load */
context_release(context);
}
}
......@@ -688,13 +691,14 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
struct wined3d_buffer *This = (struct wined3d_buffer *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
UINT start = 0, end = 0, vertices;
struct wined3d_context *context;
BOOL decl_changed = FALSE;
unsigned int i, j;
BYTE *data;
TRACE("iface %p\n", iface);
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
if (!This->buffer_object)
{
......@@ -706,6 +710,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
}
else
{
context_release(context);
return; /* Not doing any conversion */
}
}
......@@ -717,7 +722,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
This->flags |= WINED3D_BUFFER_HASDESC;
}
if (!decl_changed && !(This->flags & WINED3D_BUFFER_HASDESC && This->flags & WINED3D_BUFFER_DIRTY)) return;
if (!decl_changed && !(This->flags & WINED3D_BUFFER_HASDESC && This->flags & WINED3D_BUFFER_DIRTY))
{
context_release(context);
return;
}
/* If applications change the declaration over and over, reconverting all the time is a huge
* performance hit. So count the declaration changes and release the VBO if there are too many
......@@ -745,7 +754,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
* rarely
*/
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
context_release(context);
return;
}
buffer_check_buffer_object_size(This);
......@@ -800,7 +809,11 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
TRACE("No conversion needed\n");
/* Nothing to do because we locked directly into the vbo */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER)) return;
if (!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
context_release(context);
return;
}
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
......@@ -808,6 +821,8 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
GL_EXTCALL(glBufferSubDataARB(This->buffer_type_hint, start, end-start, This->resource.allocatedMemory + start));
checkGLcall("glBufferSubDataARB");
LEAVE_GL();
context_release(context);
return;
}
......@@ -901,6 +916,7 @@ static void STDMETHODCALLTYPE buffer_PreLoad(IWineD3DBuffer *iface)
}
HeapFree(GetProcessHeap(), 0, data);
context_release(context);
}
static WINED3DRESOURCETYPE STDMETHODCALLTYPE buffer_GetType(IWineD3DBuffer *iface)
......@@ -944,17 +960,19 @@ static HRESULT STDMETHODCALLTYPE buffer_Map(IWineD3DBuffer *iface, UINT offset,
if(count == 1)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context;
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
This->resource.allocatedMemory = GL_EXTCALL(glMapBufferARB(This->buffer_type_hint, GL_READ_WRITE_ARB));
LEAVE_GL();
context_release(context);
}
}
else
......@@ -996,17 +1014,19 @@ static HRESULT STDMETHODCALLTYPE buffer_Unmap(IWineD3DBuffer *iface)
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER) && This->buffer_object)
{
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context;
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_INDEXBUFFER);
}
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
GL_EXTCALL(glUnmapBufferARB(This->buffer_type_hint));
LEAVE_GL();
context_release(context);
This->resource.allocatedMemory = NULL;
}
......
......@@ -831,6 +831,21 @@ BOOL context_set_current(struct wined3d_context *ctx)
return TlsSetValue(wined3d_context_tls_idx, ctx);
}
void context_release(struct wined3d_context *context)
{
TRACE("Releasing context %p, level %u.\n", context, context->level);
if (WARN_ON(d3d))
{
if (!context->level)
WARN("Context %p is not active.\n", context);
else if (context != context_get_current())
WARN("Context %p is not the current context.\n", context);
}
--context->level;
}
/*****************************************************************************
* Context_MarkStateDirty
*
......@@ -1954,14 +1969,14 @@ retry:
BOOL oldInDraw = This->isInDraw;
/* surface_internal_preload() requires a context to load the
* texture, so it will call ActivateContext. Set isInDraw to true
* texture, so it will call context_acquire(). Set isInDraw to true
* to signal surface_internal_preload() that it has a context. */
/* FIXME: This is just broken. There's no guarantee whatsoever
* that the currently active context, if any, is appropriate for
* reading back the render target. We should probably call
* context_set_current(context) here and then rely on
* ActivateContext() doing the right thing. */
* context_acquire() doing the right thing. */
This->isInDraw = TRUE;
/* Read the back buffer of the old drawable into the destination texture. */
......@@ -2035,7 +2050,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
}
/*****************************************************************************
* ActivateContext
* context_acquire
*
* Finds a rendering context and drawable matching the device and render
* target for the current thread, activates them and puts them into the
......@@ -2047,7 +2062,7 @@ static void context_apply_draw_buffer(struct wined3d_context *context, BOOL blit
* usage: Prepares the context for blitting, drawing or other actions
*
*****************************************************************************/
struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This, IWineD3DSurface *target, enum ContextUsage usage)
{
struct wined3d_context *current_context = context_get_current();
DWORD tid = GetCurrentThreadId();
......@@ -2060,6 +2075,9 @@ struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurfac
TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
context = FindContext(This, target, tid);
++context->level;
TRACE("Found context %p, level %u.\n", context, context->level);
if (!context->valid) return context;
gl_info = context->gl_info;
......
......@@ -34,6 +34,7 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3
/* Override the IWineD3DResource Preload method. */
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context = NULL;
unsigned int i, j;
BOOL srgb_mode;
BOOL *dirty;
......@@ -65,9 +66,9 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3
* activated at the beginning of drawPrimitive. */
if (!device->isInDraw)
{
/* No danger of recursive calls, ActivateContext sets isInDraw to true
/* No danger of recursive calls, context_acquire() sets isInDraw to true
* when loading offscreen render targets into their texture. */
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
}
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
......@@ -109,6 +110,8 @@ static void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3
/* No longer dirty. */
*dirty = FALSE;
if (context) context_release(context);
}
static void cubetexture_cleanup(IWineD3DCubeTextureImpl *This)
......
......@@ -596,10 +596,10 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
/* Signals other modules that a drawing is in progress and the stateblock finalized */
This->isInDraw = TRUE;
context = ActivateContext(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
context = context_acquire(This, This->render_targets[0], CTXUSAGE_DRAWPRIM);
if (This->stencilBufferTarget) {
/* Note that this depends on the ActivateContext call above to set
/* Note that this depends on the context_acquire() call above to set
* This->render_offscreen properly. We don't currently take the
* Z-compare function into account, but we could skip loading the
* depthstencil for D3DCMP_NEVER and D3DCMP_ALWAYS as well. Also note
......@@ -683,6 +683,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
/* Finished updating the screen, restore lock */
LEAVE_GL();
context_release(context);
TRACE("Done all gl drawing\n");
/* Diagnostics */
......@@ -766,7 +768,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
float max_x = 0.0f, max_y = 0.0f, max_z = 0.0f, neg_z = 0.0f;
struct wined3d_stream_info stream_info;
struct wined3d_stream_info_element *e;
const struct wined3d_context *context;
struct wined3d_context *context;
const BYTE *data;
const WINED3DRECTPATCH_INFO *info = &patch->RectPatchInfo;
DWORD vtxStride;
......@@ -776,7 +778,7 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
/* Simply activate the context for blitting. This disables all the things we don't want and
* takes care of dirtifying. Dirtifying is preferred over pushing / popping, since drawing the
* patch (as opposed to normal draws) will most likely need different changes anyway. */
context = ActivateContext(This, NULL, CTXUSAGE_BLIT);
context = context_acquire(This, NULL, CTXUSAGE_BLIT);
/* First, locate the position data. This is provided in a vertex buffer in the stateblock.
* Beware of vbos
......@@ -959,11 +961,13 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
LEAVE_GL();
ERR("Feedback failed. Expected %d elements back\n", buffer_size);
HeapFree(GetProcessHeap(), 0, feedbuffer);
context_release(context);
return WINED3DERR_DRIVERINTERNALERROR;
} else if(i != buffer_size) {
LEAVE_GL();
ERR("Unexpected amount of elements returned. Expected %d, got %d\n", buffer_size, i);
HeapFree(GetProcessHeap(), 0, feedbuffer);
context_release(context);
return WINED3DERR_DRIVERINTERNALERROR;
} else {
TRACE("Got %d elements as expected\n", i);
......@@ -1078,6 +1082,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This,
checkGLcall("glDisable vertex attrib generation");
LEAVE_GL();
context_release(context);
HeapFree(GetProcessHeap(), 0, feedbuffer);
vtxStride = 3 * sizeof(float);
......
......@@ -4374,10 +4374,10 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) iface;
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)This->baseShader.device;
struct shader_glsl_priv *priv = device->shader_priv;
const struct wined3d_context *context;
const struct wined3d_gl_info *gl_info;
IWineD3DPixelShaderImpl *ps = NULL;
IWineD3DVertexShaderImpl *vs = NULL;
struct wined3d_context *context;
/* Note: Do not use QueryInterface here to find out which shader type this is because this code
* can be called from IWineD3DBaseShader::Release
......@@ -4395,7 +4395,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
return;
}
context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
gl_info = context->gl_info;
if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->pshader == iface)
......@@ -4415,7 +4415,7 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
return;
}
context = ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
gl_info = context->gl_info;
if (priv->glsl_program && (IWineD3DBaseShader *)priv->glsl_program->vshader == iface)
......@@ -4474,6 +4474,8 @@ static void shader_glsl_destroy(IWineD3DBaseShader *iface) {
HeapFree(GetProcessHeap(), 0, shader_data);
vs->baseShader.backend_data = NULL;
}
context_release(context);
}
static int glsl_program_key_compare(const void *key, const struct wine_rb_entry *entry)
......
......@@ -3,6 +3,7 @@
*
* Copyright 2005 Oliver Stieber
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009 Henri Verbeet for CodeWeavers.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -271,6 +272,7 @@ static HRESULT WINAPI IWineD3DQueryImpl_GetData(IWineD3DQuery* iface, void* pDa
static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
struct wined3d_occlusion_query *query = This->extendedData;
struct wined3d_context *context;
DWORD* data = pData;
GLuint available;
GLuint samples;
......@@ -309,7 +311,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
return S_OK;
}
ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
......@@ -335,13 +337,16 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_GetData(IWineD3DQuery* iface,
LEAVE_GL();
context_release(context);
return res;
}
static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void* pData, DWORD dwSize, DWORD dwGetDataFlags) {
IWineD3DQueryImpl *This = (IWineD3DQueryImpl *) iface;
struct wined3d_event_query *query = This->extendedData;
BOOL* data = pData;
struct wined3d_context *context;
BOOL *data = pData;
TRACE("(%p) : type D3DQUERY_EVENT, pData %p, dwSize %#x, dwGetDataFlags %#x\n", This, pData, dwSize, dwGetDataFlags);
......@@ -364,7 +369,7 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
return S_OK;
}
ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
......@@ -386,6 +391,8 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_GetData(IWineD3DQuery* iface, void
LEAVE_GL();
context_release(context);
return S_OK;
}
......@@ -472,17 +479,17 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
if (query->context->tid != GetCurrentThreadId())
{
context_free_event_query(query);
context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
else
{
ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
}
}
else
{
context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_event_query(context, query);
}
......@@ -500,6 +507,8 @@ static HRESULT WINAPI IWineD3DEventQueryImpl_Issue(IWineD3DQuery* iface, DWORD
}
LEAVE_GL();
context_release(context);
}
else if(dwIssueFlags & WINED3DISSUE_BEGIN)
{
......@@ -534,12 +543,12 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
FIXME("Wrong thread, can't restart query.\n");
context_free_occlusion_query(query);
context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_occlusion_query(context, query);
}
else
{
ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
......@@ -550,7 +559,7 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
else
{
if (query->context) context_free_occlusion_query(query);
context = ActivateContext(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, NULL, CTXUSAGE_RESOURCELOAD);
context_alloc_occlusion_query(context, query);
}
......@@ -558,6 +567,8 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
GL_EXTCALL(glBeginQueryARB(GL_SAMPLES_PASSED_ARB, query->id));
checkGLcall("glBeginQuery()");
LEAVE_GL();
context_release(context);
}
if (dwIssueFlags & WINED3DISSUE_END) {
/* Msdn says _END on a non-building occlusion query returns an error, but
......@@ -572,12 +583,14 @@ static HRESULT WINAPI IWineD3DOcclusionQueryImpl_Issue(IWineD3DQuery* iface, D
}
else
{
ActivateContext(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, query->context->current_rt, CTXUSAGE_RESOURCELOAD);
ENTER_GL();
GL_EXTCALL(glEndQueryARB(GL_SAMPLES_PASSED_ARB));
checkGLcall("glEndQuery()");
LEAVE_GL();
context_release(context);
}
}
}
......
......@@ -97,11 +97,11 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
struct wined3d_context *context;
unsigned int sync;
int retval;
ActivateContext(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->wineD3DDevice, This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
/* Render the cursor onto the back buffer, using our nifty directdraw blitting code :-) */
if(This->wineD3DDevice->bCursorVisible && This->wineD3DDevice->cursorTexture) {
......@@ -320,6 +320,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
}
}
context_release(context);
TRACE("returning\n");
return WINED3D_OK;
}
......
......@@ -34,6 +34,7 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG
/* Override the IWineD3DResource PreLoad method. */
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
struct wined3d_context *context = NULL;
unsigned int i;
BOOL srgb_mode;
BOOL *dirty;
......@@ -62,9 +63,9 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG
if (!device->isInDraw)
{
/* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture,
/* context_acquire() sets isInDraw to TRUE when loading a pbuffer into a texture,
* thus no danger of recursive calls. */
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
}
if (This->resource.format_desc->format == WINED3DFMT_P8_UINT
......@@ -97,6 +98,8 @@ static void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRG
TRACE("(%p) Texture not dirty, nothing to do.\n", iface);
}
if (context) context_release(context);
/* No longer dirty. */
*dirty = FALSE;
}
......
......@@ -34,16 +34,14 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
struct wined3d_context *context = NULL;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE;
unsigned int i;
TRACE("(%p) : About to load texture.\n", This);
if (!device->isInDraw)
{
ActivateContext(device, NULL, CTXUSAGE_RESOURCELOAD);
}
if (!device->isInDraw) context = context_acquire(device, NULL, CTXUSAGE_RESOURCELOAD);
else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0)
{
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
......@@ -73,6 +71,8 @@ static void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINE
TRACE("(%p) Texture not dirty, nothing to do.\n", iface);
}
if (context) context_release(context);
/* No longer dirty */
This->baseTexture.texture_rgb.dirty = FALSE;
}
......
......@@ -1059,6 +1059,7 @@ struct wined3d_context
char *vshader_const_dirty, *pshader_const_dirty;
/* The actual opengl context */
UINT level;
HGLRC glCtx;
HWND win_handle;
HDC hdc;
......@@ -1161,11 +1162,11 @@ typedef enum ContextUsage {
CTXUSAGE_CLEAR = 4, /* Drawable and states are set up for clearing */
} ContextUsage;
struct wined3d_context *ActivateContext(IWineD3DDeviceImpl *This,
IWineD3DSurface *target, enum ContextUsage usage) DECLSPEC_HIDDEN;
struct wined3d_context *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, HWND win,
BOOL create_pbuffer, const WINED3DPRESENT_PARAMETERS *pPresentParms) DECLSPEC_HIDDEN;
void DestroyContext(IWineD3DDeviceImpl *This, struct wined3d_context *context) DECLSPEC_HIDDEN;
struct wined3d_context *context_acquire(IWineD3DDeviceImpl *This,
IWineD3DSurface *target, enum ContextUsage usage) DECLSPEC_HIDDEN;
void context_alloc_event_query(struct wined3d_context *context,
struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_alloc_occlusion_query(struct wined3d_context *context,
......@@ -1181,6 +1182,7 @@ void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
struct wined3d_context *context_get_current(void) DECLSPEC_HIDDEN;
DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
......
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