>From f39d89c97db66a473a19ea7e6e5c87782194a93f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefandoesinger@gmx.at>
Date: Sun, 14 Feb 2016 20:19:38 +0000
Subject: [PATCH 07/10] wined3d: Rotate through swapchain buffers (v2).
Reply-To: wine-devel <wine-devel@winehq.org>

Version 2: Flip multisample RBs too for multisampled swapchains.

Going back to square one and moving around texture resources. Anything
that's based on reassigning client library resources will make d3d11
deferred contexts very difficult.
---
 dlls/d3d8/tests/visual.c | 10 +++++-----
 dlls/d3d9/tests/visual.c | 10 +++++-----
 dlls/wined3d/swapchain.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/dlls/d3d8/tests/visual.c b/dlls/d3d8/tests/visual.c
index 856df5d..bb644d3 100644
--- a/dlls/d3d8/tests/visual.c
+++ b/dlls/d3d8/tests/visual.c
@@ -8041,9 +8041,9 @@ static void test_flip(void)
 
     /* Contents were changed. */
     color = get_surface_color(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
     color = get_surface_color(back_buffers[1], 1, 1);
-    todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
     ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
@@ -8052,15 +8052,15 @@ static void test_flip(void)
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
 
     color = get_surface_color(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
     color = get_surface_color(back_buffers[1], 1, 1);
-    todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
 
     color = get_surface_color(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
 
     for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
         IDirect3DSurface8_Release(back_buffers[i]);
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 274777b..b96ccd1 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -20185,9 +20185,9 @@ static void test_flip(void)
 
     /* Contents were changed. */
     color = getPixelColorFromSurface(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
     color = getPixelColorFromSurface(back_buffers[1], 1, 1);
-    todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
     ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
@@ -20196,15 +20196,15 @@ static void test_flip(void)
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
 
     color = getPixelColorFromSurface(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
     color = getPixelColorFromSurface(back_buffers[1], 1, 1);
-    todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
 
     color = getPixelColorFromSurface(back_buffers[0], 1, 1);
-    todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
+    ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
 
     for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
         IDirect3DSurface9_Release(back_buffers[i]);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 6e56def..becad97 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -422,6 +422,51 @@ static void swapchain_blit(const struct wined3d_swapchain *swapchain,
     }
 }
 
+/* Context activation is done by the caller. */
+static void wined3d_swapchain_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context *context)
+{
+    struct gl_texture tex0;
+    GLuint rb0;
+    DWORD locations0;
+    struct wined3d_surface *surface, *surface_prev;
+    unsigned int i;
+    static const DWORD supported_locations = WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_RB_MULTISAMPLE;
+
+    if (swapchain->desc.backbuffer_count < 2 || !swapchain->render_to_fbo)
+        return;
+
+    surface_prev = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[0], 0));
+
+    /* Back buffer 0 is already in the draw binding. */
+    tex0 = swapchain->back_buffers[0]->texture_rgb;
+    rb0 = surface_prev->rb_multisample;
+    locations0 = surface_prev->locations;
+
+    for (i = 1; i < swapchain->desc.backbuffer_count; ++i)
+    {
+        surface = surface_from_resource(wined3d_texture_get_sub_resource(swapchain->back_buffers[i], 0));
+
+        if (!(surface->locations & supported_locations))
+            surface_load_location(surface, context, swapchain->back_buffers[i]->resource.draw_binding);
+
+        swapchain->back_buffers[i - 1]->texture_rgb = swapchain->back_buffers[i]->texture_rgb;
+        surface_prev->rb_multisample = surface->rb_multisample;
+
+        surface_validate_location(surface_prev, surface->locations & supported_locations);
+        surface_invalidate_location(surface_prev, ~(surface->locations & supported_locations));
+
+        surface_prev = surface;
+    }
+
+    swapchain->back_buffers[i - 1]->texture_rgb = tex0;
+    surface_prev->rb_multisample = rb0;
+
+    surface_validate_location(surface_prev, locations0 & supported_locations);
+    surface_invalidate_location(surface_prev, ~(locations0 & supported_locations));
+
+    device_invalidate_state(swapchain->device, STATE_FRAMEBUFFER);
+}
+
 static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect_in,
         const RECT *dst_rect_in, const RGNDATA *dirty_region, DWORD flags)
 {
@@ -549,7 +594,9 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT
         gl_info->gl_ops.gl.p_glFinish();
 
     /* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
-    gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
+    gl_info->gl_ops.wgl.p_wglSwapBuffers(context->hdc);
+
+    wined3d_swapchain_rotate(swapchain, context);
 
     TRACE("SwapBuffers called, Starting new frame\n");
     /* FPS support */
-- 
2.4.10

