[D3D] Last (?) threading-related fixes for DungeonSiege
Lionel Ulmer
lionel.ulmer at free.fr
Mon May 26 07:50:15 CDT 2003
Hi all,
Please disregard my previous mail about the critical sections... It was my
fault, playing with two different sections and not taking care of the order
I entered them (and thus created a nice deadlock).
With this patch, I played DungeonSiege for quite some time without any
graphical glitches related to threading (there are still some texturing
issues). And as DungeonSiege is the most ugly game I know related to
threading, I suppose it must work relatively well now :-)
Changelog:
- remove some extraneous saving of the read buffer settings
- cleaned-up the GL / device critical section handling
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- dlls/ddraw_CVS/d3ddevice/mesa.c Mon May 26 13:50:09 2003
+++ dlls/ddraw/d3ddevice/mesa.c Mon May 26 14:36:43 2003
@@ -1099,27 +1099,24 @@
IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
int num_active_stages = 0;
+ /* This is to prevent 'thread contention' between a thread locking the device and another
+ doing 3D display on it... */
+ EnterCriticalSection(&(This->crit));
+
ENTER_GL();
if (glThis->state == SURFACE_MEMORY_DIRTY) {
This->flush_to_framebuffer(This, NULL, glThis->lock_surf);
}
- LEAVE_GL();
glThis->state = SURFACE_GL;
/* Compute the number of active texture stages */
while (This->current_texture[num_active_stages] != NULL) num_active_stages++;
- /* This is to prevent 'thread contention' between a thread locking the device and another
- doing 3D display on it... */
- EnterCriticalSection(&(This->crit));
-
if (TRACE_ON(ddraw)) {
TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
}
- ENTER_GL();
-
/* Just a hack for now.. Will have to find better algorithm :-/ */
if ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) {
vertex_lighted = TRUE;
@@ -1965,9 +1962,7 @@
}
if ((dwState & 0xFF) != D3DTTFF_DISABLE) {
- LEAVE_GL();
This->matrices_updated(This, TEXMAT0_CHANGED << dwStage);
- ENTER_GL();
}
if (handled == TRUE) {
@@ -2815,7 +2810,6 @@
/* If the surface is already in memory, no need to do anything here... */
GLenum buffer_type;
GLenum buffer_color;
- GLenum prev_read;
RECT loc_rect;
int y;
char *dst;
@@ -2826,18 +2820,6 @@
may only write to the device... But when we will blit it back to the screen, we need
also to blit correctly the parts the application did not overwrite... */
- ENTER_GL();
-
- glGetIntegerv(GL_READ_BUFFER, &prev_read);
- glFlush();
-
- if (is_front == TRUE)
- /* Application wants to lock the front buffer */
- glReadBuffer(GL_FRONT);
- else
- /* Application wants to lock the back buffer */
- glReadBuffer(GL_BACK);
-
if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) &&
(This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) &&
(This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) &&
@@ -2855,10 +2837,18 @@
glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
} else {
ERR(" unsupported pixel format at device locking.\n");
- LEAVE_GL();
return;
}
+ ENTER_GL();
+
+ if (is_front == TRUE)
+ /* Application wants to lock the front buffer */
+ glReadBuffer(GL_FRONT);
+ else
+ /* Application wants to lock the back buffer */
+ glReadBuffer(GL_BACK);
+
/* Just a hack while waiting for proper rectangle support */
pRect = NULL;
if (pRect == NULL) {
@@ -2881,7 +2871,6 @@
dst += This->surface_desc.u1.lPitch;
}
- glReadBuffer(prev_read);
glPixelStorei(GL_PACK_SWAP_BYTES, FALSE);
if (is_front)
@@ -2919,8 +2908,8 @@
GLint tex_state;
int x, y;
- /* This is to prevent another thread to actually lock the buffer while we flush it on screen */
- EnterCriticalSection(&(d3d_dev->crit));
+ /* Note : no need here to lock the 'device critical section' as we are already protected by
+ the GL critical section. */
loc_rect.top = 0;
loc_rect.left = 0;
@@ -2962,7 +2951,6 @@
glPixelStorei(GL_UNPACK_SWAP_BYTES, TRUE);
} else {
ERR(" unsupported pixel format at frame buffer flush.\n");
- LeaveCriticalSection(&(d3d_dev->crit));
return;
}
@@ -2972,6 +2960,8 @@
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_SCISSOR_TEST);
+ glDepthRange(0.0, 1.0);
+ glViewport(0, 0, d3d_dev->surface->surface_desc.dwWidth, d3d_dev->surface->surface_desc.dwHeight);
glScissor(loc_rect.left, surf->surface_desc.dwHeight - loc_rect.bottom,
loc_rect.right - loc_rect.left, loc_rect.bottom - loc_rect.top);
@@ -3039,9 +3029,11 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_tex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_env);
- LEAVE_GL();
+ glDepthRange(d3d_dev->active_viewport.dvMinZ, d3d_dev->active_viewport.dvMaxZ);
+ glViewport(d3d_dev->active_viewport.dwX,
+ d3d_dev->surface->surface_desc.dwHeight - (d3d_dev->active_viewport.dwHeight + d3d_dev->active_viewport.dwY),
+ d3d_dev->active_viewport.dwWidth, d3d_dev->active_viewport.dwHeight);
d3d_dev->matrices_updated(d3d_dev, TEXMAT0_CHANGED);
- ENTER_GL();
#if 0
/* I keep this code here as it's very useful to debug :-) */
{
@@ -3056,9 +3048,6 @@
}
}
#endif
-
- /* And leave the critical section... */
- LeaveCriticalSection(&(d3d_dev->crit));
}
static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
@@ -3236,9 +3225,7 @@
/* Initialisation */
TRACE(" setting current context\n");
- LEAVE_GL();
object->set_context(object);
- ENTER_GL();
TRACE(" current context set\n");
/* allocate the clipping planes */
--- dlls/ddraw_CVS/mesa.c Sat May 24 18:00:35 2003
+++ dlls/ddraw/mesa.c Mon May 26 14:06:20 2003
@@ -101,11 +101,9 @@
case D3DRENDERSTATE_TEXTUREHANDLE: { /* 1 */
IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState;
- LEAVE_GL();
IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
0,
ICOM_INTERFACE(tex, IDirectDrawSurface7));
- ENTER_GL();
} break;
case D3DRENDERSTATE_TEXTUREADDRESSU: /* 44 */
@@ -117,11 +115,9 @@
else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU;
else d3dTexStageStateType = D3DTSS_ADDRESSV;
- LEAVE_GL();
IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
0, d3dTexStageStateType,
dwRenderState);
- ENTER_GL();
} break;
case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */
@@ -218,9 +214,7 @@
}
if (tex_mag != 0xFFFFFFFF) {
- LEAVE_GL();
IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag);
- ENTER_GL();
}
} break;
@@ -239,9 +233,7 @@
}
if (tex_min != 0xFFFFFFFF) {
- LEAVE_GL();
IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min);
- ENTER_GL();
}
} break;
More information about the wine-patches
mailing list