[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