[PATCH 2/3] wined3d: Update a part of the texture if dirty regions are tracked.

Henri Verbeet hverbeet at codeweavers.com
Tue Dec 10 11:56:16 CST 2019


From: Akihiro Sagawa <sagawa.aki at gmail.com>

Wine-Bugs: https://bugs.winehq.org/show_bug.cgi?id=35205
Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 175195.

 dlls/d3d9/tests/visual.c | 12 ++++-----
 dlls/wined3d/device.c    | 67 ++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 0a9fb0acc29..c87337057ea 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19340,7 +19340,7 @@ static void add_dirty_rect_test(void)
     ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
     add_dirty_rect_test_draw(device);
     color = getPixelColor(device, 320, 240);
-    todo_wine ok(color_match(color, 0x00ff0000, 1),
+    ok(color_match(color, 0x00ff0000, 1),
             "Expected color 0x00ff0000, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
@@ -19353,7 +19353,7 @@ static void add_dirty_rect_test(void)
     ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
     add_dirty_rect_test_draw(device);
     color = getPixelColor(device, 320, 240);
-    todo_wine ok(color_match(color, 0x00ff0000, 1),
+    ok(color_match(color, 0x00ff0000, 1),
             "Expected color 0x00ff0000, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
@@ -19365,7 +19365,7 @@ static void add_dirty_rect_test(void)
     ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
     add_dirty_rect_test_draw(device);
     color = getPixelColor(device, 320, 240);
-    todo_wine ok(color_match(color, 0x00ff0000, 1),
+    ok(color_match(color, 0x00ff0000, 1),
             "Expected color 0x00ff0000, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
@@ -19382,7 +19382,7 @@ static void add_dirty_rect_test(void)
     ok(color_match(color, 0x0000ff00, 1),
             "Expected color 0x0000ff00, got 0x%08x.\n", color);
     color = getPixelColor(device, 1, 1);
-    todo_wine ok(color_match(color, 0x00ff0000, 1),
+    ok(color_match(color, 0x00ff0000, 1),
             "Expected color 0x00ff0000, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
@@ -19404,7 +19404,7 @@ static void add_dirty_rect_test(void)
     ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
     add_dirty_rect_test_draw(device);
     color = getPixelColor(device, 320, 240);
-    todo_wine ok(color_match(color, 0x0000ff00, 1),
+    ok(color_match(color, 0x0000ff00, 1),
             "Expected color 0x0000ff00, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
@@ -19416,7 +19416,7 @@ static void add_dirty_rect_test(void)
     ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
     add_dirty_rect_test_draw(device);
     color = getPixelColor(device, 320, 240);
-    todo_wine ok(color_match(color, 0x0000ff00, 1),
+    ok(color_match(color, 0x0000ff00, 1),
             "Expected color 0x0000ff00, got 0x%08x.\n", color);
     hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
     ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index dc92d4f4b74..89134207243 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4141,19 +4141,66 @@ HRESULT CDECL wined3d_device_update_texture(struct wined3d_device *device,
         }
     }
 
-    if (!entire_texture)
-        FIXME("Ignoring dirty regions.\n");
-
     /* Update every surface level of the texture. */
-    for (i = 0; i < level_count; ++i)
+    if (entire_texture)
     {
-        wined3d_texture_get_level_box(dst_texture, i, &box);
-        for (j = 0; j < layer_count; ++j)
+        for (i = 0; i < level_count; ++i)
+        {
+            wined3d_texture_get_level_box(dst_texture, i, &box);
+            for (j = 0; j < layer_count; ++j)
+            {
+                wined3d_cs_emit_blt_sub_resource(device->cs,
+                        &dst_texture->resource, j * dst_level_count + i, &box,
+                        &src_texture->resource, j * src_level_count + i + src_skip_levels, &box,
+                        0, NULL, WINED3D_TEXF_POINT);
+            }
+        }
+    }
+    else
+    {
+        unsigned int src_level, box_count, k;
+        const struct wined3d_box *boxes;
+        struct wined3d_box b;
+
+        for (i = 0; i < layer_count; ++i)
         {
-            wined3d_cs_emit_blt_sub_resource(device->cs,
-                    &dst_texture->resource, j * dst_level_count + i, &box,
-                    &src_texture->resource, j * src_level_count + i + src_skip_levels, &box,
-                    0, NULL, WINED3D_TEXF_POINT);
+            boxes = regions[i].boxes;
+            box_count = regions[i].box_count;
+            if (regions[i].box_count >= WINED3D_MAX_DIRTY_REGION_COUNT)
+            {
+                boxes = &b;
+                box_count = 1;
+                wined3d_texture_get_level_box(dst_texture, i, &b);
+            }
+
+            for (j = 0; j < level_count; ++j)
+            {
+                src_level = j + src_skip_levels;
+
+                /* TODO: We could pass an array of boxes here to avoid
+                 * multiple context acquisitions for the same resource. */
+                for (k = 0; k < box_count; ++k)
+                {
+                    box = boxes[k];
+                    if (src_level)
+                    {
+                        box.left >>= src_level;
+                        box.top >>= src_level;
+                        box.right = min((box.right + (1u << src_level) - 1) >> src_level,
+                                wined3d_texture_get_level_width(src_texture, src_level));
+                        box.bottom = min((box.bottom + (1u << src_level) - 1) >> src_level,
+                                wined3d_texture_get_level_height(src_texture, src_level));
+                        box.front >>= src_level;
+                        box.back = min((box.back + (1u << src_level) - 1) >> src_level,
+                                wined3d_texture_get_level_depth(src_texture, src_level));
+                    }
+
+                    wined3d_cs_emit_blt_sub_resource(device->cs,
+                            &dst_texture->resource, i * dst_level_count + j, &box,
+                            &src_texture->resource, i * src_level_count + src_level, &box,
+                            0, NULL, WINED3D_TEXF_POINT);
+                }
+            }
         }
     }
 
-- 
2.11.0




More information about the wine-devel mailing list