[DDraw] Create GL texture id only on texture binding

Lionel Ulmer lionel.ulmer at free.fr
Sun Apr 3 09:36:14 CDT 2005


This helps for games like RO that does texture creation from a thread
different from the 'main' D3D thread.

Proper solution still in wait of someone to work on it :-)

          Lionel

Changelog:
  Create the GL texture id at texture-binding time

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: dlls/ddraw/d3dtexture.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3dtexture.c,v
retrieving revision 1.68
diff -u -r1.68 d3dtexture.c
--- dlls/ddraw/d3dtexture.c	10 Jan 2005 13:29:26 -0000	1.68
+++ dlls/ddraw/d3dtexture.c	3 Apr 2005 14:33:30 -0000
@@ -417,6 +417,8 @@
 	    ENTER_GL();
 	    
 	    glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex);
+	    /* This call is to create the actual texture name in GL (as we do 'late' ID creation) */
+	    gltex_get_tex_name(surf_ptr);
 	    glBindTexture(GL_TEXTURE_2D, gl_surf_ptr->tex_name);
 	    
 	    if ((gl_surf_ptr->dirty_flag == SURFACE_MEMORY_DIRTY) &&
@@ -706,9 +708,6 @@
 	        memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight);
 
 	    if (gl_dst_ptr != NULL) {
-	        /* If the GetHandle was not done, it is an error... */
-	        if (gl_dst_ptr->tex_name == 0) ERR("Unbound GL texture !!!\n");
-
 		/* Set this texture as dirty */
 		gl_dst_ptr->dirty_flag = SURFACE_MEMORY_DIRTY;
 		*(gl_dst_ptr->global_dirty_flag) = SURFACE_MEMORY_DIRTY;
@@ -875,6 +874,8 @@
         private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
 	if (private == NULL) return DDERR_OUTOFMEMORY;
 
+	surf->tex_private = private;
+	
 	private->final_release = surf->final_release;
 	private->lock_update = surf->lock_update;
 	private->unlock_update = surf->unlock_update;
@@ -885,7 +886,6 @@
 	surf->final_release = gltex_final_release;
 	surf->lock_update = gltex_lock_update;
 	surf->unlock_update = gltex_unlock_update;
-	surf->tex_private = private;
 	surf->aux_setcolorkey_cb = gltex_setcolorkey_cb;
 	surf->set_palette = gltex_set_palette;
 
@@ -895,25 +895,43 @@
 	surf->aux_bltfast = gltex_bltfast;
 	
 	TRACE(" GL texture created for surface %p (private data at %p)\n", surf, private);
-	
+
+	/* Do not create the OpenGL texture id here as some game generate textures from a different thread which
+	    cause problems.. */
+	private->tex_name = 0;
+	if (surf->mipmap_level == 0) {
+	    private->main = NULL;
+	    private->global_dirty_flag = &(private->__global_dirty_flag);
+	} else {
+	    private->main = main;
+	    private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (private->main->tex_private))->__global_dirty_flag);
+	}
+	private->initial_upload_done = FALSE;
+    }
+
+    return D3D_OK;
+}
+
+GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *surf)
+{
+    IDirect3DTextureGLImpl *private = (IDirect3DTextureGLImpl *) (surf->tex_private);
+    
+    if (private->tex_name == 0) {
+	/* The texture was not created yet... */	
 	ENTER_GL();
 	if (surf->mipmap_level == 0) {
 	    glGenTextures(1, &(private->tex_name));
 	    if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n");
 	    TRACE(" GL texture id is : %d.\n", private->tex_name);
-	    private->__global_dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY);
-	    private->global_dirty_flag = &(private->__global_dirty_flag);
+	    private->__global_dirty_flag = SURFACE_MEMORY_DIRTY;
 	} else {
-	    private->tex_name = ((IDirect3DTextureGLImpl *) (main->tex_private))->tex_name;
-	    TRACE(" GL texture id reusing id %d from surface %p (private at %p)).\n", private->tex_name, main, main->tex_private);
-	    private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (main->tex_private))->__global_dirty_flag);
+	    private->tex_name = gltex_get_tex_name(private->main);
+	    TRACE(" GL texture id reusing id %d from surface %p (private at %p)).\n", private->tex_name, private->main, private->main->tex_private);
 	}
 	LEAVE_GL();
 
 	/* And set the dirty flag accordingly */
-	private->dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY);
-	private->initial_upload_done = FALSE;
+	private->dirty_flag = SURFACE_MEMORY_DIRTY;
     }
-
-    return D3D_OK;
+    return ((IDirect3DTextureGLImpl *) (surf->tex_private))->tex_name;
 }
Index: dlls/ddraw/mesa_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/mesa_private.h,v
retrieving revision 1.63
diff -u -r1.63 mesa_private.h
--- dlls/ddraw/mesa_private.h	14 Feb 2005 11:09:47 -0000	1.63
+++ dlls/ddraw/mesa_private.h	3 Apr 2005 14:33:30 -0000
@@ -63,7 +63,8 @@
 {
     GLuint tex_name;
     BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */
-
+    IDirectDrawSurfaceImpl *main; /* Pointer to the 'main' surface of the mip-map set */
+    
     /* Texture upload management */
     BOOLEAN initial_upload_done;
     SURFACE_STATE dirty_flag;
@@ -201,6 +202,9 @@
 
 /* Used to upload the texture */
 extern HRESULT gltex_upload_texture(IDirectDrawSurfaceImpl *This, IDirect3DDeviceImpl *d3ddev, DWORD stage) ;
+
+/* Used to get the texture name */
+extern GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *This) ;
 
 /* Used to set-up our orthographic projection */
 extern void d3ddevice_set_ortho(IDirect3DDeviceImpl *This) ;
Index: dlls/ddraw/d3ddevice/mesa.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/d3ddevice/mesa.c,v
retrieving revision 1.169
diff -u -r1.169 mesa.c
--- dlls/ddraw/d3ddevice/mesa.c	24 Mar 2005 21:01:39 -0000	1.169
+++ dlls/ddraw/d3ddevice/mesa.c	3 Apr 2005 14:33:32 -0000
@@ -2257,7 +2257,7 @@
 		glBindTexture(GL_TEXTURE_2D, 0);
 		glDisable(GL_TEXTURE_2D);
 	    } else {
-		GLenum tex_name = ((IDirect3DTextureGLImpl *) surf_ptr->tex_private)->tex_name;
+		GLenum tex_name = gltex_get_tex_name(surf_ptr);
 		
 		unit = GL_TEXTURE0_WINE + stage;
 		if (unit != glThis->current_active_tex_unit) {


More information about the wine-patches mailing list