Stefan Dösinger : wined3d: Prepare wined3d_format_convert_from_float for > 32bpp formats.

Alexandre Julliard julliard at winehq.org
Mon May 16 15:37:58 CDT 2022


Module: wine
Branch: master
Commit: 2465e1e1da03fc3ec5c6ab537d1d7549f932b280
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2465e1e1da03fc3ec5c6ab537d1d7549f932b280

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon May 16 12:58:03 2022 -0500

wined3d: Prepare wined3d_format_convert_from_float for > 32bpp formats.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/device.c          |  4 +--
 dlls/wined3d/resource.c        | 16 +++++------
 dlls/wined3d/utils.c           | 60 +++++++++++++++++++++++++++++-------------
 dlls/wined3d/wined3d_private.h |  4 +--
 4 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 8937c7fc0fc..d39634c49fc 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);
-            *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &diffuse_colour);
+            wined3d_format_convert_from_float(output_colour_format, &diffuse_colour, 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);
-            *((DWORD *)dest_ptr) = wined3d_format_convert_from_float(output_colour_format, &specular_colour);
+            wined3d_format_convert_from_float(output_colour_format, &specular_colour, dest_ptr);
             dest_ptr += sizeof(DWORD);
         }
 
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 7587a6455a4..073bc5b5834 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -621,7 +621,7 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
     const struct wined3d_format *format = resource->format;
     unsigned int w, h, d, x, y, z, bpp;
     uint8_t *dst, *dst2;
-    uint32_t c;
+    uint32_t c[4];
 
     w = box->right - box->left;
     h = box->bottom - box->top;
@@ -632,7 +632,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);
 
-    c = wined3d_format_convert_from_float(format, colour);
+    wined3d_format_convert_from_float(format, colour, c);
     bpp = format->byte_count;
 
     switch (bpp)
@@ -640,14 +640,14 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
         case 1:
             for (x = 0; x < w; ++x)
             {
-                dst[x] = c;
+                dst[x] = c[0];
             }
             break;
 
         case 2:
             for (x = 0; x < w; ++x)
             {
-                ((uint16_t *)dst)[x] = c;
+                ((uint16_t *)dst)[x] = c[0];
             }
             break;
 
@@ -656,16 +656,16 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource,
             dst2 = dst;
             for (x = 0; x < w; ++x, dst2 += 3)
             {
-                dst2[0] = (c      ) & 0xff;
-                dst2[1] = (c >>  8) & 0xff;
-                dst2[2] = (c >> 16) & 0xff;
+                dst2[0] = (c[0]      ) & 0xff;
+                dst2[1] = (c[0] >>  8) & 0xff;
+                dst2[2] = (c[0] >> 16) & 0xff;
             }
             break;
         }
         case 4:
             for (x = 0; x < w; ++x)
             {
-                ((uint32_t *)dst)[x] = c;
+                ((uint32_t *)dst)[x] = c[0];
             }
             break;
 
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 401d815a365..6fe792c015f 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6000,8 +6000,14 @@ uint32_t wined3d_format_pack(const struct wined3d_format *format, const struct w
 
 /* Note: It's the caller's responsibility to ensure values can be expressed
  * in the requested format. UNORM formats for example can only express values
- * in the range 0.0f -> 1.0f. */
-DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color)
+ * in the range 0.0f -> 1.0f.
+ *
+ * The code below assumes that no component crosses the 32 bit boundary (like
+ * e.g. a hypothetical, and totally braindead, B30G30R4 format would).
+ * 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)
 {
     static const struct
     {
@@ -6044,10 +6050,11 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con
     };
     enum wined3d_format_id format_id = format->id;
     struct wined3d_color colour_srgb;
+    struct wined3d_uvec4 idx, shift;
     unsigned int i;
-    DWORD ret;
 
     TRACE("Converting colour %s to format %s.\n", debug_color(color), debug_d3dformat(format_id));
+    memset(ret, 0, max(sizeof(uint32_t), format->byte_count));
 
     for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i)
     {
@@ -6062,37 +6069,54 @@ DWORD wined3d_format_convert_from_float(const struct wined3d_format *format, con
 
     for (i = 0; i < ARRAY_SIZE(float_conv); ++i)
     {
+        uint32_t *ret_i = ret;
+
         if (format_id != float_conv[i].format_id)
             continue;
 
-        ret = ((DWORD)((color->r * float_conv[i].mul.x) + 0.5f)) << float_conv[i].shift.x;
-        ret |= ((DWORD)((color->g * float_conv[i].mul.y) + 0.5f)) << float_conv[i].shift.y;
-        ret |= ((DWORD)((color->b * float_conv[i].mul.z) + 0.5f)) << float_conv[i].shift.z;
-        ret |= ((DWORD)((color->a * float_conv[i].mul.w) + 0.5f)) << float_conv[i].shift.w;
+        idx.x = float_conv[i].shift.x / 32;
+        idx.y = float_conv[i].shift.y / 32;
+        idx.z = float_conv[i].shift.z / 32;
+        idx.w = float_conv[i].shift.w / 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;
 
-        TRACE("Returning 0x%08x.\n", ret);
+        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;
 
-        return ret;
+        return;
     }
 
     for (i = 0; i < ARRAY_SIZE(double_conv); ++i)
     {
+        uint32_t *ret_i;
+
         if (format_id != double_conv[i].format_id)
             continue;
 
-        ret = ((DWORD)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x;
-        ret |= ((DWORD)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y;
-        ret |= ((DWORD)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z;
-        ret |= ((DWORD)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].shift.w;
+        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;
+
+        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;
 
-        TRACE("Returning 0x%08x.\n", ret);
-
-        return ret;
+        return;
     }
 
     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id));
-
-    return 0;
 }
 
 static float color_to_float(DWORD color, DWORD size, DWORD offset)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ba1dc2169b0..37cec7dd2c3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -6150,8 +6150,8 @@ void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigne
         unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN;
 UINT wined3d_format_calculate_size(const struct wined3d_format *format,
         UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN;
-DWORD wined3d_format_convert_from_float(const struct wined3d_format *format,
-        const struct wined3d_color *color) DECLSPEC_HIDDEN;
+void wined3d_format_convert_from_float(const struct wined3d_format *format,
+        const struct wined3d_color *color, 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;




More information about the wine-cvs mailing list