[D3D] Some more formats added for surface locking

Lionel Ulmer lionel.ulmer at free.fr
Sat May 17 16:28:42 CDT 2003


All,

With this patch, DungeonSiege is now starting to work and displays stuff. It
now gives me a lot of warnings about stuff not implemented (yeah :-) ).

There is still one *huge* problem : basically, it gives us completely bogus
lock rectangles at the first time it locks the front buffer to display the
mouse cursor... This means that for the game to work, you need an ugly hack
that 'sanitizes' the Lock rectangles (available on request :-) ).

                   Lionel

Changelog:
 - added RGB 32 surface locking (seems to work fine without resorting to
   Alpha hacks)

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- dlls/ddraw_CVS/d3ddevice/mesa.c	Sat May 17 17:02:36 2003
+++ dlls/ddraw/d3ddevice/mesa.c	Sat May 17 23:16:14 2003
@@ -2578,6 +2578,7 @@
 	((is_front == FALSE) && (gl_d3d_dev->state       != SURFACE_MEMORY))) {
         /* 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;
@@ -2601,8 +2602,21 @@
 	    /* Application wants to lock the back buffer */
 	    glReadBuffer(GL_BACK);
 
-	if (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+	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) &&
+	    (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
+	    (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
 	    buffer_type = GL_UNSIGNED_SHORT_5_6_5;
+	    buffer_color = GL_RGB;
+	} else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) &&
+		   (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
+		   (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
+		   (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
+		   (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+	    buffer_type = GL_UNSIGNED_BYTE;
+	    buffer_color = GL_BGRA;
+	    glPixelStorei(GL_PACK_SWAP_BYTES, TRUE);
 	} else {
 	    ERR(" unsupported pixel format at device locking.\n");
 	    LEAVE_GL();
@@ -2627,17 +2641,33 @@
 	     y--) {
 	    glReadPixels(loc_rect.left, y,
 			 loc_rect.right - loc_rect.left, 1,
-			 GL_RGB, buffer_type, dst);
+			 buffer_color, buffer_type, dst);
 	    dst += This->surface_desc.u1.lPitch;
 	}
 
 	glReadBuffer(prev_read);
-
+	glPixelStorei(GL_PACK_SWAP_BYTES, FALSE);
+	
 	if (is_front)
 	    gl_d3d_dev->front_state = SURFACE_MEMORY;
 	else
 	    gl_d3d_dev->state = SURFACE_MEMORY;
 	
+#if 0
+	/* I keep this code here as it's very useful to debug :-) */
+	{
+	    static int flush_count = 0;
+	    char buf[128];
+	    FILE *f;
+	    
+	    if ((++flush_count % 50) == 0) {
+	        sprintf(buf, "lock_%06d.pnm", flush_count);
+		f = fopen(buf, "wb");
+		DDRAW_dump_surface_to_disk(This, f);
+	    }
+	}
+#endif
+	
 	LEAVE_GL();
     }
 }
@@ -2645,26 +2675,28 @@
 #define UNLOCK_TEX_SIZE 256
 
 static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect) {
-    GLenum buffer_type;
+    GLenum buffer_type, buffer_color;
     RECT loc_rect;
     IDirectDrawSurfaceImpl *surf = d3d_dev->surface;
     IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev;
-    GLint depth_test, alpha_test, cull_face, lighting, min_tex, max_tex, tex_env;
+    GLint depth_test, alpha_test, cull_face, lighting, min_tex, max_tex, tex_env, blend, stencil_test;
     GLuint initial_texture;
     GLint tex_state;
     int x, y;
-	
+
     loc_rect.top = 0;
     loc_rect.left = 0;
     loc_rect.bottom = surf->surface_desc.dwHeight;
     loc_rect.right = surf->surface_desc.dwWidth;
 
-    TRACE(" flushing memory back to the frame-buffer.\n");
+    TRACE(" flushing memory back to the frame-buffer (%ld,%ld) x (%ld,%ld).\n", loc_rect.top, loc_rect.left, loc_rect.right, loc_rect.bottom);
 	
     glGetIntegerv(GL_DEPTH_TEST, &depth_test);
     glGetIntegerv(GL_ALPHA_TEST, &alpha_test);
+    glGetIntegerv(GL_STENCIL_TEST, &stencil_test);
     glGetIntegerv(GL_CULL_FACE, &cull_face);
     glGetIntegerv(GL_LIGHTING, &lighting);
+    glGetIntegerv(GL_BLEND, &blend);
     glGetIntegerv(GL_TEXTURE_BINDING_2D, &initial_texture);
     glGetIntegerv(GL_TEXTURE_2D, &tex_state);
     glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &max_tex);
@@ -2672,10 +2704,23 @@
     glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env);
     /* TODO: scissor test if ever we use it ! */
     
-    if (surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) {
+    if ((surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) &&
+	(surf->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask ==        0xF800) &&
+	(surf->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask ==        0x07E0) &&
+	(surf->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask ==        0x001F) &&
+	(surf->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) {
         buffer_type = GL_UNSIGNED_SHORT_5_6_5;
+	buffer_color = GL_RGB;
+    } else if ((surf->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) &&
+	       (surf->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask ==        0x00FF0000) &&
+	       (surf->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask ==        0x0000FF00) &&
+	       (surf->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask ==        0x000000FF) &&
+	       (surf->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) {
+        buffer_type = GL_UNSIGNED_BYTE;
+	buffer_color = GL_BGRA;
+	glPixelStorei(GL_UNPACK_SWAP_BYTES, TRUE);
     } else {
-        WARN(" unsupported pixel format.\n");
+        ERR(" unsupported pixel format at frame buffer flush.\n");
 	return;
     }
 
@@ -2703,9 +2748,11 @@
     glDisable(GL_LIGHTING);
     glDisable(GL_CULL_FACE);
     glDisable(GL_ALPHA_TEST);
+    glDisable(GL_STENCIL_TEST);
+    glDisable(GL_BLEND);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    
+
     for (x = loc_rect.left; x < loc_rect.right; x += UNLOCK_TEX_SIZE) {
         for (y = loc_rect.top; y < loc_rect.bottom; y += UNLOCK_TEX_SIZE) {
 	    /* First, upload the texture... */
@@ -2715,7 +2762,7 @@
 			    0,
 			    0, 0,
 			    w, h,
-			    GL_RGB,
+			    buffer_color,
 			    buffer_type,
 			    ((char *) surf->surface_desc.lpSurface) + (x * GET_BPP(surf->surface_desc)) + (y * surf->surface_desc.u1.lPitch));
 	    glBegin(GL_QUADS);
@@ -2737,14 +2784,32 @@
     if (depth_test != 0) glEnable(GL_DEPTH_TEST);
     if (lighting != 0) glEnable(GL_LIGHTING);
     if (alpha_test != 0) glEnable(GL_ALPHA_TEST);
+    if (stencil_test != 0) glEnable(GL_STENCIL_TEST);
     if (cull_face != 0) glEnable(GL_CULL_FACE);
+    if (blend != 0) glEnable(GL_BLEND);
     glBindTexture(GL_TEXTURE_2D, initial_texture);
     if (tex_state == 0) glDisable(GL_TEXTURE_2D);
     glDisable(GL_SCISSOR_TEST);
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE);
     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);
+
+#if 0
+    /* I keep this code here as it's very useful to debug :-) */
+    {
+        static int flush_count = 0;
+	char buf[128];
+	FILE *f;
+
+	if ((++flush_count % 50) == 0) {
+	    sprintf(buf, "flush_%06d.pnm", flush_count);
+	    f = fopen(buf, "wb");
+	    DDRAW_dump_surface_to_disk(surf, f);
+	}
+    }
+#endif
 }
 
 static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)


More information about the wine-patches mailing list