[PATCH 2/4] wined3d: Always use screen-sized frontbuffers.

Stefan Dösinger stefan at codeweavers.com
Fri Jul 17 05:13:18 CDT 2015


Currently the WGL -> sysmem copy code assumes window size == surface size.
That's OK because it is only hit by GetFrontBufferData. The texture<->WGL
blit code assumes the surface size is the screen size. It is only called by
ddraw with pre-clipped coordinates, so that's OK in practice. But overall
this is a mess.

Things will be a lot more tricky when the ddraw shadow frontbuffer goes away
and ddraw blits and GetFrontBufferData run through the same codepaths. Always
having the frontbuffer window sized may sound appealing but won't work for
ddraw.
---
 dlls/wined3d/device.c    |  6 +++---
 dlls/wined3d/surface.c   | 22 +++++++++++++++++-----
 dlls/wined3d/swapchain.c | 27 +++++++++++++--------------
 3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 56cf325..e5f3b26 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4546,9 +4546,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     {
         UINT i;
 
-        if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, swapchain->desc.backbuffer_width,
-                swapchain->desc.backbuffer_height, swapchain->desc.backbuffer_format,
-                swapchain->desc.multisample_type, swapchain->desc.multisample_quality, NULL, 0)))
+        if (FAILED(hr = wined3d_texture_update_desc(swapchain->front_buffer, m.width, m.height,
+                swapchain->desc.backbuffer_format, swapchain->desc.multisample_type,
+                swapchain->desc.multisample_quality, NULL, 0)))
             return hr;
 
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 57610bd..f1ae2ba 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -2725,6 +2725,9 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
     int i;
     BOOL srcIsUpsideDown;
     struct wined3d_bo_address data;
+    ULONG_PTR offset = 0;
+    RECT rect = {0, 0, surface->resource.width, surface->resource.height};
+    DWORD pitch = wined3d_surface_get_pitch(surface);
 
     surface_get_memory(surface, &data, dst_location);
 
@@ -2752,6 +2755,16 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
         gl_info->gl_ops.gl.p_glReadBuffer(buffer);
         checkGLcall("glReadBuffer");
         srcIsUpsideDown = FALSE;
+
+        if (buffer == GL_FRONT)
+        {
+            POINT p = {0, 0};
+            memset(surface->resource.heap_memory, 0xaa, surface->resource.size);
+            GetClientRect(context->win_handle, &rect);
+            ClientToScreen(context->win_handle, &p);
+            offset = pitch * (surface->resource.height - p.y - rect.bottom)
+                    + surface->resource.format->byte_count * p.x;
+        }
     }
 
     if (data.buffer_object)
@@ -2761,14 +2774,13 @@ static void read_from_framebuffer(struct wined3d_surface *surface, DWORD dst_loc
     }
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
-    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH,
-            wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count);
+    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, pitch / surface->resource.format->byte_count);
     checkGLcall("glPixelStorei");
 
-    gl_info->gl_ops.gl.p_glReadPixels(0, 0,
-            surface->resource.width, surface->resource.height,
+    gl_info->gl_ops.gl.p_glReadPixels(rect.left, rect.top,
+            rect.right - rect.left, rect.bottom - rect.top,
             surface->resource.format->glFormat,
-            surface->resource.format->glType, data.addr);
+            surface->resource.format->glType, data.addr + offset);
     checkGLcall("glReadPixels");
 
     /* Reset previous pixel store pack state */
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 5a5ba6b..638d89d 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -159,22 +159,11 @@ HRESULT CDECL wined3d_swapchain_get_front_buffer_data(const struct wined3d_swapc
         struct wined3d_surface *dst_surface)
 {
     struct wined3d_surface *src_surface;
-    RECT src_rect, dst_rect;
 
     TRACE("swapchain %p, dst_surface %p.\n", swapchain, dst_surface);
 
     src_surface = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->front_buffer, 0));
-    SetRect(&src_rect, 0, 0, src_surface->resource.width, src_surface->resource.height);
-    dst_rect = src_rect;
-
-    if (swapchain->desc.windowed)
-    {
-        MapWindowPoints(swapchain->win_handle, NULL, (POINT *)&dst_rect, 2);
-        FIXME("Using destination rect %s in windowed mode, this is likely wrong.\n",
-                wine_dbgstr_rect(&dst_rect));
-    }
-
-    return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, 0, NULL, WINED3D_TEXF_POINT);
+    return wined3d_surface_blt(dst_surface, NULL, src_surface, NULL, 0, NULL, WINED3D_TEXF_POINT);
 }
 
 struct wined3d_surface * CDECL wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
@@ -849,8 +838,16 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     surface_desc.multisample_quality = swapchain->desc.multisample_quality;
     surface_desc.usage = 0;
     surface_desc.pool = WINED3D_POOL_DEFAULT;
-    surface_desc.width = swapchain->desc.backbuffer_width;
-    surface_desc.height = swapchain->desc.backbuffer_height;
+    if (desc->windowed)
+    {
+        surface_desc.width = swapchain->original_mode.width;
+        surface_desc.height = swapchain->original_mode.height;
+    }
+    else
+    {
+        surface_desc.width = swapchain->desc.backbuffer_width;
+        surface_desc.height = swapchain->desc.backbuffer_height;
+    }
     surface_desc.depth = 1;
     surface_desc.size = 0;
 
@@ -960,6 +957,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
         }
 
         surface_desc.usage |= WINED3DUSAGE_RENDERTARGET;
+        surface_desc.width = swapchain->desc.backbuffer_width;
+        surface_desc.height = swapchain->desc.backbuffer_height;
         for (i = 0; i < swapchain->desc.backbuffer_count; ++i)
         {
             struct wined3d_surface *back_buffer;
-- 
2.3.6




More information about the wine-patches mailing list