[PATCH 4/5] wined3d: Pass depth and stencil separately down the CPU fill path.

Stefan Dösinger wine at gitlab.winehq.org
Sun May 22 04:16:12 CDT 2022


From: Stefan Dösinger <stefan at codeweavers.com>

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>

---

Love it or leave it. Shouldn't affect the test behind it.

Eventually we can merge depth formats into the UNORM or FLOAT codepaths,
but right now the UNORM flag is specific to color formats. I'm also not
sure how we'd ever realistically clear a depth buffer to anything other
than zero in the CPU codepath. Tests show that depth locking is
unreliable, and even DEPTHFILL value vs actual Z test value in d3d7 is
vendor specific.

Merging depth-unorm and color-unorm as well as depth-float and
color-float handling works without this patch too. Just multiply and OR
color.r with mask_to_size(red) and mask_to_size(depth), as long as we
don't encounter a format that has both red and depth channels.
---
 dlls/wined3d/device.c          |  4 +--
 dlls/wined3d/resource.c        |  8 +++---
 dlls/wined3d/surface.c         | 12 +++++----
 dlls/wined3d/texture.c         | 19 ++++----------
 dlls/wined3d/utils.c           | 47 +++++++++++++++++++---------------
 dlls/wined3d/wined3d_private.h |  5 ++--
 6 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index d39634c49fc..a2782a570ad 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3689,7 +3689,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
                 diffuse_colour = material_diffuse;
             }
             wined3d_color_clamp(&diffuse_colour, &diffuse_colour, 0.0f, 1.0f);
-            wined3d_format_convert_from_float(output_colour_format, &diffuse_colour, dest_ptr);
+            wined3d_format_convert_from_float(output_colour_format, &diffuse_colour, 0.0f, 0, dest_ptr);
             dest_ptr += sizeof(DWORD);
         }
 
@@ -3713,7 +3713,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
             }
             update_fog_factor(&specular_colour.a, &ls);
             wined3d_color_clamp(&specular_colour, &specular_colour, 0.0f, 1.0f);
-            wined3d_format_convert_from_float(output_colour_format, &specular_colour, dest_ptr);
+            wined3d_format_convert_from_float(output_colour_format, &specular_colour, 0.0f, 0, dest_ptr);
             dest_ptr += sizeof(DWORD);
         }
 
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index fe77923f778..64af95e439f 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -616,7 +616,8 @@ void *resource_offset_map_pointer(struct wined3d_resource *resource, unsigned in
 
 void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
         const struct wined3d_map_desc *map, const struct wined3d_color *colour,
-        const struct wined3d_box *box, bool full_subresource)
+        float depth, unsigned int stencil, const struct wined3d_box *box,
+        bool full_subresource)
 {
     const struct wined3d_format *format = resource->format;
     unsigned int w, h, d, x, y, z, bpp;
@@ -626,7 +627,8 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
     /* Fast and simple path for setting everything to zero. The C library's memset is
      * more sophisticated than our code below. Also this works for block formats, which
      * we still need to zero-initialize for newly created resources. */
-    if (full_subresource && !colour->r && !colour->g && !colour->b && !colour->a)
+    if (full_subresource && !colour->r && !colour->g && !colour->b && !colour->a
+            && !depth && !stencil)
     {
         memset(map->data, 0, map->slice_pitch * box->back);
         return;
@@ -641,7 +643,7 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
             + ((box->top / format->block_height) * map->row_pitch)
             + ((box->left / format->block_width) * format->block_byte_count);
 
-    wined3d_format_convert_from_float(format, colour, c);
+    wined3d_format_convert_from_float(format, colour, depth, stencil, c);
     bpp = format->byte_count;
 
     switch (bpp)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 96aacb78e77..45687c9e7fe 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1175,7 +1175,8 @@ release:
 }
 
 static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view,
-        const struct wined3d_box *box, const struct wined3d_color *colour)
+        const struct wined3d_box *box, const struct wined3d_color *colour,
+        float depth, unsigned int stencil)
 {
     struct wined3d_device *device = view->resource->device;
     struct wined3d_context *context;
@@ -1224,7 +1225,8 @@ static void surface_cpu_blt_colour_fill(struct wined3d_rendertarget_view *view,
     range.offset = 0;
     range.size = texture->sub_resources[view->sub_resource_idx].size;
 
-    wined3d_resource_memory_colour_fill(view->resource, &map, colour, box, full_subresource);
+    wined3d_resource_memory_colour_fill(view->resource, &map, colour, depth, stencil,
+            box, full_subresource);
 
     wined3d_context_unmap_bo_address(context, &data, 1, &range);
     context_release(context);
@@ -1243,9 +1245,9 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
         unsigned int rt_count, const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects,
         const RECT *draw_rect, DWORD flags, const struct wined3d_color *colour, float depth, DWORD stencil)
 {
-    struct wined3d_color c = {depth, 0.0f, 0.0f, 0.0f};
     struct wined3d_box box, box_clip, box_view;
     struct wined3d_rendertarget_view *view;
+    static struct wined3d_color zero;
     unsigned int i, j;
 
     if (!rect_count)
@@ -1274,7 +1276,7 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
                 {
                     wined3d_rendertarget_view_get_box(view, &box_view);
                     if (wined3d_box_intersect(&box_clip, &box_view, &box))
-                        surface_cpu_blt_colour_fill(view, &box_clip, colour);
+                        surface_cpu_blt_colour_fill(view, &box_clip, colour, 0.0f, 0);
                 }
             }
         }
@@ -1287,7 +1289,7 @@ static void cpu_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_de
 
             wined3d_rendertarget_view_get_box(view, &box_view);
             if (wined3d_box_intersect(&box_clip, &box_view, &box))
-                surface_cpu_blt_colour_fill(view, &box_clip, &c);
+                surface_cpu_blt_colour_fill(view, &box_clip, &zero, depth, stencil);
         }
     }
 }
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 7dfedd65ecc..7765f74db46 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -826,19 +826,6 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
             unsigned int level_idx = sub_resource_idx % texture->level_count;
             struct wined3d_map_desc map;
             struct wined3d_box box;
-            struct wined3d_color c;
-
-            if (texture->resource.format->flags[WINED3D_GL_RES_TYPE_TEX_2D]
-                    & WINED3DFMT_FLAG_DEPTH_STENCIL)
-            {
-                c.r = texture->sub_resources[sub_resource_idx].clear_value.depth;
-                c.g = texture->sub_resources[sub_resource_idx].clear_value.stencil;
-                c.b = c.a = 0.0f;
-            }
-            else
-            {
-                c = texture->sub_resources[sub_resource_idx].clear_value.colour;
-            }
 
             wined3d_texture_get_pitch(texture, level_idx, &map.row_pitch, &map.slice_pitch);
             if (destination.buffer_object)
@@ -848,7 +835,11 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture,
                 map.data = destination.addr;
 
             wined3d_texture_get_level_box(texture, level_idx, &box);
-            wined3d_resource_memory_colour_fill(&texture->resource, &map, &c, &box, true);
+            wined3d_resource_memory_colour_fill(&texture->resource, &map,
+                    &texture->sub_resources[sub_resource_idx].clear_value.colour,
+                    texture->sub_resources[sub_resource_idx].clear_value.depth,
+                    texture->sub_resources[sub_resource_idx].clear_value.stencil,
+                    &box, true);
 
             if (destination.buffer_object)
                 wined3d_context_unmap_bo_address(context, &destination, 1, &range);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 3680bcf6425..6809efb041a 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6036,35 +6036,40 @@ void wined3d_format_colour_to_vk(const struct wined3d_format *format, const stru
  * This function writes at least sizeof(uint32_t) bytes, or format->byte_count,
  * whichever is larger. */
 void wined3d_format_convert_from_float(const struct wined3d_format *format,
-        const struct wined3d_color *color, void *ret)
+        const struct wined3d_color *color, float depth, unsigned int stencil, void *ret)
 {
     static const struct
     {
         enum wined3d_format_id format_id;
         struct wined3d_vec4 mul;
+        float dmul;
+        unsigned int smul;
         struct wined3d_uvec4 shift;
+        unsigned int dshift, sshift;
     }
     float_conv[] =
     {
-        {WINED3DFMT_P8_UINT,           {         0.0f,    0.0f,    0.0f, 255.0f}, { 0,  0,  0,  0}},
-        {WINED3DFMT_S1_UINT_D15_UNORM, {     32767.0f,    0.0f,    0.0f,   0.0f}, { 0,  0,  0,  0}},
-        {WINED3DFMT_D16_UNORM,         {     65535.0f,    0.0f,    0.0f,   0.0f}, { 0,  0,  0,  0}},
+        {WINED3DFMT_P8_UINT,           {0.0f, 0.0f, 0.0f, 255.0f},     0.0f, 0, {0,  0,  0,  0}, 0, 0},
+        {WINED3DFMT_S1_UINT_D15_UNORM, {0.0f, 0.0f, 0.0f,   0.0f}, 32767.0f, 1, {0,  0,  0,  0}, 0, 0},
+        {WINED3DFMT_D16_UNORM,         {0.0f, 0.0f, 0.0f,   0.0f}, 65535.0f, 0, {0,  0,  0,  0}, 0, 0},
     };
     static const struct
     {
         enum wined3d_format_id format_id;
-        struct wined3d_dvec4 mul;
-        struct wined3d_uvec4 shift;
+        double dmul;
+        unsigned int smul;
+        unsigned int dshift, sshift;
     }
     double_conv[] =
     {
-        {WINED3DFMT_D24_UNORM_S8_UINT, {  16777215.0, 1.0, 0.0, 0.0}, {8, 0, 0, 0}},
-        {WINED3DFMT_X8D24_UNORM,       {  16777215.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}},
-        {WINED3DFMT_D32_UNORM,         {4294967295.0, 0.0, 0.0, 0.0}, {0, 0, 0, 0}},
+        {WINED3DFMT_D24_UNORM_S8_UINT, 16777215.0, 1, 8, 0},
+        {WINED3DFMT_X8D24_UNORM,       16777215.0, 0, 0, 0},
+        {WINED3DFMT_D32_UNORM,         4294967295.0, 0, 0, 0},
     };
     enum wined3d_format_id format_id = format->id;
     struct wined3d_color colour_srgb;
     struct wined3d_uvec4 idx, shift;
+    unsigned int dshift, didx, sshift, sidx;
     unsigned int i;
 
     TRACE("Converting colour %s to format %s.\n", debug_color(color), debug_d3dformat(format_id));
@@ -6092,15 +6097,21 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format,
         idx.y = float_conv[i].shift.y / 32;
         idx.z = float_conv[i].shift.z / 32;
         idx.w = float_conv[i].shift.w / 32;
+        didx = float_conv[i].dshift / 32;
+        sidx = float_conv[i].sshift / 32;
         shift.x = float_conv[i].shift.x % 32;
         shift.y = float_conv[i].shift.y % 32;
         shift.z = float_conv[i].shift.z % 32;
         shift.w = float_conv[i].shift.w % 32;
+        dshift = float_conv[i].dshift % 32;
+        sshift = float_conv[i].sshift % 32;
 
         ret_i[idx.x] = ((uint32_t)((color->r * float_conv[i].mul.x) + 0.5f)) << shift.x;
         ret_i[idx.y] |= ((uint32_t)((color->g * float_conv[i].mul.y) + 0.5f)) << shift.y;
         ret_i[idx.z] |= ((uint32_t)((color->b * float_conv[i].mul.z) + 0.5f)) << shift.z;
         ret_i[idx.w] |= ((uint32_t)((color->a * float_conv[i].mul.w) + 0.5f)) << shift.w;
+        ret_i[didx] |= ((uint32_t)((depth * float_conv[i].dmul) + 0.5f)) << dshift;
+        ret_i[sidx] |= ((uint32_t)(stencil * float_conv[i].smul)) << sshift;
 
         return;
     }
@@ -6112,20 +6123,14 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format,
         if (format_id != double_conv[i].format_id)
             continue;
 
-        idx.x = double_conv[i].shift.x / 32;
-        idx.y = double_conv[i].shift.y / 32;
-        idx.z = double_conv[i].shift.z / 32;
-        idx.w = double_conv[i].shift.w / 32;
-        shift.x = double_conv[i].shift.x % 32;
-        shift.y = double_conv[i].shift.y % 32;
-        shift.z = double_conv[i].shift.z % 32;
-        shift.w = double_conv[i].shift.w % 32;
+        didx = double_conv[i].dshift / 32;
+        sidx = double_conv[i].sshift / 32;
+        dshift = double_conv[i].dshift % 32;
+        sshift = double_conv[i].sshift % 32;
 
         ret_i = ret;
-        ret_i[idx.x] = ((uint32_t)((color->r * double_conv[i].mul.x) + 0.5)) << shift.x;
-        ret_i[idx.y] |= ((uint32_t)((color->g * double_conv[i].mul.y) + 0.5)) << shift.y;
-        ret_i[idx.z] |= ((uint32_t)((color->b * double_conv[i].mul.z) + 0.5)) << shift.z;
-        ret_i[idx.w] |= ((uint32_t)((color->a * double_conv[i].mul.w) + 0.5)) << shift.w;
+        ret_i[didx] = ((uint32_t)((depth * double_conv[i].dmul) + 0.5)) << dshift;
+        ret_i[sidx] |= ((uint32_t)(stencil * double_conv[i].smul)) << sshift;
 
         return;
     }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 835a1346d03..1a8bab5ea52 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4428,7 +4428,8 @@ BOOL wined3d_resource_prepare_sysmem(struct wined3d_resource *resource) DECLSPEC
 void wined3d_resource_update_draw_binding(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
         const struct wined3d_map_desc *map, const struct wined3d_color *colour,
-        const struct wined3d_box *box, bool full_subresource) DECLSPEC_HIDDEN;
+        float depth, unsigned int stencil, const struct wined3d_box *box,
+        bool full_subresource) DECLSPEC_HIDDEN;
 
 /* Tests show that the start address of resources is 32 byte aligned */
 #define RESOURCE_ALIGNMENT 16
@@ -6223,7 +6224,7 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format,
 void wined3d_format_colour_to_vk(const struct wined3d_format *format, const struct wined3d_color *c,
         VkClearColorValue *retval) DECLSPEC_HIDDEN;
 void wined3d_format_convert_from_float(const struct wined3d_format *format,
-        const struct wined3d_color *color, void *ret) DECLSPEC_HIDDEN;
+        const struct wined3d_color *color, float depth, unsigned int stencil, void *ret) DECLSPEC_HIDDEN;
 void wined3d_format_copy_data(const struct wined3d_format *format, const uint8_t *src,
         unsigned int src_row_pitch, unsigned int src_slice_pitch, uint8_t *dst, unsigned int dst_row_pitch,
         unsigned int dst_slice_pitch, unsigned int w, unsigned int h, unsigned int d) DECLSPEC_HIDDEN;
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/109



More information about the wine-devel mailing list