[dx75] GetDeviceCaps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A number of games call Directx8 GetDeviceCaps prior to creating the device, and more worryingly prior to creating any windows. Hence there is no GL context yet. Currently the code queries GL which can either trap or return erroneous values (in which case it returns guessed values), but the 'proper' way to do it is to create a dummy GL context, use it to query the values, and then destroy the context - ddraw and opengl dlls do it already,

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;
 }
 

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux