wined3d: Control the onscreen depth stencil format in the swapchain.
authorStefan Dösinger <stefan@codeweavers.com>
Sun, 28 Mar 2010 14:25:04 +0000 (16:25 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 31 Mar 2010 14:12:31 +0000 (16:12 +0200)
This allows the swapchain to know what depth format its window contexts have to see if the
requested depth format is compatible or a FBO fallback is needed, and it will be needed to
set the onscreen format to the requested auto depth stencil format instead of the
let's-hope-it-fits D24_UNORM_S8_UINT format.

dlls/wined3d/context.c
dlls/wined3d/device.c
dlls/wined3d/swapchain.c
dlls/wined3d/wined3d_private.h

index f3729aefa13c1d07c3a79fde163bb32fbfff54e2..738746e24c484144da88070667089c44aba93078 100644 (file)
@@ -1087,23 +1087,6 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc,
         return 0;
     }
 
-    /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
-     * You are able to add a depth + stencil surface at a later stage when you need it.
-     * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
-     * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
-     * context, need torecreate shaders, textures and other resources.
-     *
-     * The context manager already takes care of the state problem and for the other tasks code from Reset
-     * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
-     * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
-     * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
-     * issue needs to be fixed. */
-    if (ds_format_desc->format != WINED3DFMT_D24_UNORM_S8_UINT)
-    {
-        FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n");
-        ds_format_desc = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, &This->adapter->gl_info);
-    }
-
     getDepthStencilBits(ds_format_desc, &depthBits, &stencilBits);
 
     for(matchtry = 0; matchtry < (sizeof(matches) / sizeof(matches[0])) && !iPixelFormat; matchtry++) {
@@ -1229,12 +1212,12 @@ static int WineD3D_ChoosePixelFormat(IWineD3DDeviceImpl *This, HDC hdc,
  *  pPresentParameters: contains the pixelformats to use for onscreen rendering
  *
  *****************************************************************************/
-struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target)
+struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
+        const struct wined3d_format_desc *ds_format_desc)
 {
     IWineD3DDeviceImpl *device = swapchain->device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     const struct wined3d_format_desc *color_format_desc;
-    const struct wined3d_format_desc *ds_format_desc;
     struct wined3d_context *ret;
     PIXELFORMATDESCRIPTOR pfd;
     BOOL auxBuffers = FALSE;
@@ -1260,7 +1243,6 @@ struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3
         goto out;
     }
 
-    ds_format_desc = getFormatDescEntry(WINED3DFMT_UNKNOWN, gl_info);
     color_format_desc = target->resource.format_desc;
 
     /* In case of ORM_BACKBUFFER, make sure to request an alpha component for
index aa1611833619507befaeb316fc46e458c6f154e1..06e95f0d237dba97cef3f6add210393e9fcf750e 100644 (file)
@@ -6318,7 +6318,7 @@ HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *
     }
 
     target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
-    if (!(context = context_create(swapchain, target)))
+    if (!(context = context_create(swapchain, target, swapchain->ds_format)))
     {
         WARN("Failed to create context.\n");
         HeapFree(GetProcessHeap(), 0, swapchain->context);
index bd44b03f636d4012d22affe85182a863671f4270..14a741b3f07b92ee2255795b2034ecd6fdd5dcfd 100644 (file)
@@ -795,7 +795,28 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
 
     if (surface_type == SURFACE_OPENGL)
     {
-        if (!(swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer)))
+        const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+
+        /* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
+         * You are able to add a depth + stencil surface at a later stage when you need it.
+         * In order to support this properly in WineD3D we need the ability to recreate the opengl context and
+         * drawable when this is required. This is very tricky as we need to reapply ALL opengl states for the new
+         * context, need torecreate shaders, textures and other resources.
+         *
+         * The context manager already takes care of the state problem and for the other tasks code from Reset
+         * can be used. These changes are way to risky during the 1.0 code freeze which is taking place right now.
+         * Likely a lot of other new bugs will be exposed. For that reason request a depth stencil surface all the
+         * time. It can cause a slight performance hit but fixes a lot of regressions. A fixme reminds of that this
+         * issue needs to be fixed. */
+        if (!present_parameters->EnableAutoDepthStencil
+                || swapchain->presentParms.AutoDepthStencilFormat != WINED3DFMT_D24_UNORM_S8_UINT)
+        {
+            FIXME("Add OpenGL context recreation support to SetDepthStencilSurface\n");
+        }
+        swapchain->ds_format = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, gl_info);
+        swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
+                swapchain->ds_format);
+        if (!swapchain->context[0])
         {
             WARN("Failed to create context.\n");
             hr = WINED3DERR_NOTAVAILABLE;
@@ -912,7 +933,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i
 
     TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
 
-    if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer)))
+    if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer, This->ds_format)))
     {
         ERR("Failed to create a new context for the swapchain\n");
         return NULL;
index eb9ae9ffc9c41207c086c5dbe910af627230ed1b..a812114344ed5e404e47aa4206375165149f3351 100644 (file)
@@ -1204,7 +1204,8 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
         GLenum fbo_target, IWineD3DSurface *depth_stencil, BOOL use_render_buffer) DECLSPEC_HIDDEN;
 void context_attach_surface_fbo(const struct wined3d_context *context,
         GLenum fbo_target, DWORD idx, IWineD3DSurface *surface) DECLSPEC_HIDDEN;
-struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target) DECLSPEC_HIDDEN;
+struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3DSurfaceImpl *target,
+        const struct wined3d_format_desc *ds_format_desc) DECLSPEC_HIDDEN;
 void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
 void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
@@ -2556,6 +2557,7 @@ struct IWineD3DSwapChainImpl
     WINED3DFORMAT             orig_fmt;
     WINED3DGAMMARAMP          orig_gamma;
     BOOL                      render_to_fbo;
+    const struct wined3d_format_desc *ds_format;
 
     long prev_time, frames;   /* Performance tracking */
     unsigned int vSyncCounter;