From acdc84e673d59feb87fc0df71c0d64f45af08af8 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Mon, 11 Apr 2005 12:51:22 +0000 Subject: [PATCH] Create the GL texture id at texture-binding time. --- dlls/ddraw/d3ddevice/mesa.c | 2 +- dlls/ddraw/d3dtexture.c | 52 +++++++++++++++++++++++++------------ dlls/ddraw/mesa_private.h | 6 ++++- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c index 4e4f575b494..fbdb344a057 100644 --- a/dlls/ddraw/d3ddevice/mesa.c +++ b/dlls/ddraw/d3ddevice/mesa.c @@ -2257,7 +2257,7 @@ draw_primitive_handle_textures(IDirect3DDeviceImpl *This) 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) { diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index fdc8bc40aa6..2a88e78c994 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -417,6 +417,8 @@ gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx, 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 @@ GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, 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 @@ HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BO 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 @@ HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BO 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 @@ HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BO surf->aux_bltfast = gltex_bltfast; TRACE(" GL texture created for surface %p (private data at %p)\n", surf, private); - - ENTER_GL(); + + /* 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) { - 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->main = NULL; private->global_dirty_flag = &(private->__global_dirty_flag); } 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->main = main; + private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (private->main->tex_private))->__global_dirty_flag); } - LEAVE_GL(); - - /* And set the dirty flag accordingly */ - private->dirty_flag = (at_creation == FALSE ? SURFACE_MEMORY_DIRTY : SURFACE_MEMORY); 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 = SURFACE_MEMORY_DIRTY; + } else { + 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 = SURFACE_MEMORY_DIRTY; + } + return ((IDirect3DTextureGLImpl *) (surf->tex_private))->tex_name; +} diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index e70ab8ca799..dff01b70577 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -63,7 +63,8 @@ typedef struct IDirect3DTextureGLImpl { 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; @@ -202,6 +203,9 @@ extern BOOL d3ddevice_init_at_startup(void *gl_handle); /* 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) ;