One note: On my machine, this works UNLESS certain dlls are loaded beforehand in which case it traps. However, this patch doesnt cause the problem - I have pinned it down to linking with -lpthreads. If I manually remove these from the Makefile in d3d8 and d3d9, I have no problems, but if it is there, a simple program which loadlibrary(user32.dll ), freelibrary(), loadlibrary(d3d8.dll) causes a trap deep inside GL. (FYI : I did not put --with-nptl on the ./configure anymore, so I am unsure where it has come from... to be investigated).
Changelog
Use a dummy GL context if one is not available when GetDeviceCaps is called Remove the compiler warnings introduced in the last DXTn patch
Jason
Index: dlls/d3d8/d3d8_main.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/d3d8_main.c,v retrieving revision 1.12 diff -u -r1.12 d3d8_main.c --- dlls/d3d8/d3d8_main.c 15 Aug 2003 03:50:09 -0000 1.12 +++ dlls/d3d8/d3d8_main.c 30 Aug 2003 16:29:28 -0000 @@ -61,7 +61,7 @@ /* At process attach */ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) { - TRACE("fdwReason=%ld\n", fdwReason); + TRACE("D3D8 DLLMain Reason=%ld\n", fdwReason); if (fdwReason == DLL_PROCESS_ATTACH) { HMODULE mod; @@ -77,3 +77,4 @@ } return TRUE; } + Index: dlls/d3d8/directx.c =================================================================== RCS file: /home/wine/wine/dlls/d3d8/directx.c,v retrieving revision 1.47 diff -u -r1.47 directx.c --- dlls/d3d8/directx.c 15 Aug 2003 03:50:08 -0000 1.47 +++ dlls/d3d8/directx.c 30 Aug 2003 16:29:30 -0000 @@ -326,6 +326,8 @@ case D3DFMT_DXT3: case D3DFMT_DXT5: return D3D_OK; + default: + break; /* Avoid compiler warnings */ } } @@ -397,9 +399,91 @@ } HRESULT WINAPI IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) { + + BOOL gotContext = FALSE; + BOOL created = FALSE; + GLint gl_tex_size = 0; + GLXContext gl_context = 0; + Display *display = NULL; ICOM_THIS(IDirect3D8Impl,iface); + TRACE("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps); + /* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created + ie there is no GL Context - Get a default rendering context to enable the + function query some info from GL */ + if (glXGetCurrentContext() == NULL) { + + XVisualInfo template; + XVisualInfo *vis; + HDC device_context; + Visual *visual; + Drawable drawable = (Drawable) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window"); + XWindowAttributes win_attr; + BOOL failed = FALSE; + int num; + + /* Get the display */ + device_context = GetDC(0); + display = get_display(device_context); + ReleaseDC(0, device_context); + + /* Get the X visual */ + ENTER_GL(); + if (XGetWindowAttributes(display, drawable, &win_attr)) { + visual = win_attr.visual; + } else { + visual = DefaultVisual(display, DefaultScreen(display)); + } + template.visualid = XVisualIDFromVisual(visual); + vis = XGetVisualInfo(display, VisualIDMask, &template, &num); + if (vis == NULL) { + LEAVE_GL(); + WARN("Error creating visual info for capabilities initialization\n"); + failed = TRUE; + } + + /* Create a GL context */ + if (!failed) { + gl_context = glXCreateContext(display, vis, NULL, GL_TRUE); + + if (gl_context == NULL) { + LEAVE_GL(); + WARN("Error creating default context for capabilities initialization\n"); + failed = TRUE; + } + } + + /* Make it the current GL context */ + if (!failed && glXMakeCurrent(display, drawable, gl_context) == False) { + glXDestroyContext(display, gl_context); + LEAVE_GL(); + WARN("Error setting default context as current for capabilities initialization\n"); + failed = TRUE; + } + + /* It worked! Wow... */ + if (!failed) { + gotContext = TRUE; + created = TRUE; + } + } + + if (gotContext == FALSE) { + + FIXME("GetDeviceCaps called but no GL Context - Returning dummy values\n"); + gl_tex_size=65535; + pCaps->MaxTextureBlendStages = 2; + pCaps->MaxSimultaneousTextures = 2; + pCaps->MaxUserClipPlanes = 8; + pCaps->MaxActiveLights = 8; + pCaps->MaxVertexBlendMatrices = 0; + pCaps->MaxVertexBlendMatrixIndex = 1; + pCaps->MaxAnisotropy = 0; + pCaps->MaxPointSize = 255.0; + } else { + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_tex_size); + } pCaps->DeviceType = (DeviceType == D3DDEVTYPE_HAL) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF; /* Not quite true, but use h/w supported by opengl I suppose */ pCaps->AdapterOrdinal = Adapter; @@ -495,12 +579,8 @@ D3DLINECAPS_ALPHACMP D3DLINECAPS_FOG */ - { - GLint gl_tex_size; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_tex_size); - pCaps->MaxTextureWidth = gl_tex_size; - pCaps->MaxTextureHeight = gl_tex_size; - } + pCaps->MaxTextureWidth = gl_tex_size; + pCaps->MaxTextureHeight = gl_tex_size; pCaps->MaxVolumeExtent = 0; @@ -558,10 +638,9 @@ D3DTEXOPCAPS_MULTIPLYADD D3DTEXOPCAPS_PREMODULATE */ - { + if (gotContext) { GLint gl_max; GLfloat gl_float; - #if defined(GL_VERSION_1_3) glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gl_max); #else @@ -628,6 +707,12 @@ pCaps->MaxPixelShaderValue = 0.0; #endif + /* If we created a dummy context, throw it away */ + if (created) { + glXMakeCurrent(display, None, NULL); + glXDestroyContext(display, gl_context); + LEAVE_GL(); + } return D3D_OK; }