Stefan Dösinger : wined3d: Support CPU clear of float16 formats.
Alexandre Julliard
julliard at winehq.org
Mon May 16 15:37:59 CDT 2022
Module: wine
Branch: master
Commit: e8c9588e2ad4168380fda86e7ebc3dfd56c3e863
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e8c9588e2ad4168380fda86e7ebc3dfd56c3e863
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Mon May 16 12:58:05 2022 -0500
wined3d: Support CPU clear of float16 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/surface.c | 63 -----------------------------------
dlls/wined3d/utils.c | 25 ++++++++++++++
dlls/wined3d/wined3d_private.h | 75 ++++++++++++++++++++++++++++++++++++++----
3 files changed, 93 insertions(+), 70 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 0d4809ea55b..29bdef9844f 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -39,69 +39,6 @@ static void get_color_masks(const struct wined3d_format *format, uint32_t *masks
masks[2] = wined3d_mask_from_size(format->blue_size) << format->blue_offset;
}
-/* See also float_16_to_32() in wined3d_private.h */
-static inline unsigned short float_32_to_16(const float *in)
-{
- int exp = 0;
- float tmp = fabsf(*in);
- unsigned int mantissa;
- unsigned short ret;
-
- /* Deal with special numbers */
- if (*in == 0.0f)
- return 0x0000;
- if (isnan(*in))
- return 0x7c01;
- if (isinf(*in))
- return (*in < 0.0f ? 0xfc00 : 0x7c00);
-
- if (tmp < (float)(1u << 10))
- {
- do
- {
- tmp = tmp * 2.0f;
- exp--;
- } while (tmp < (float)(1u << 10));
- }
- else if (tmp >= (float)(1u << 11))
- {
- do
- {
- tmp /= 2.0f;
- exp++;
- } while (tmp >= (float)(1u << 11));
- }
-
- mantissa = (unsigned int)tmp;
- if (tmp - mantissa >= 0.5f)
- ++mantissa; /* Round to nearest, away from zero. */
-
- exp += 10; /* Normalize the mantissa. */
- exp += 15; /* Exponent is encoded with excess 15. */
-
- if (exp > 30) /* too big */
- {
- ret = 0x7c00; /* INF */
- }
- else if (exp <= 0)
- {
- /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */
- while (exp <= 0)
- {
- mantissa = mantissa >> 1;
- ++exp;
- }
- ret = mantissa & 0x3ff;
- }
- else
- {
- ret = (exp << 10) | (mantissa & 0x3ff);
- }
-
- ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */
- return ret;
-}
-
static void convert_r32_float_r16_float(const BYTE *src, BYTE *dst,
DWORD pitch_in, DWORD pitch_out, unsigned int w, unsigned int h)
{
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 6d785c461d4..892020e2aa9 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -6137,6 +6137,31 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format,
return;
}
+ if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 16)
+ {
+ uint16_t *ret_s = ret;
+
+ switch (format->byte_count)
+ {
+ case 8:
+ ret_s[3] = float_32_to_16(&color->a);
+ ret_s[2] = float_32_to_16(&color->b);
+ /* fall through */
+ case 4:
+ ret_s[1] = float_32_to_16(&color->g);
+ /* fall through */
+ case 2:
+ ret_s[0] = float_32_to_16(&color->r);
+ break;
+
+ default:
+ ERR("Unexpected byte count %u, format %s.\n", format->byte_count, debug_d3dformat(format_id));
+ break;
+ }
+
+ return;
+ }
+
FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format_id));
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 37cec7dd2c3..1d8bb40cec4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -354,13 +354,12 @@ static inline GLenum wined3d_gl_min_mip_filter(enum wined3d_texture_filter_type
return minMipLookup[min_filter].mip[mip_filter];
}
-/* float_16_to_32() and float_32_to_16() (see implementation in
- * surface_base.c) convert 16 bit floats in the FLOAT16 data type
- * to standard C floats and vice versa. They do not depend on the encoding
- * of the C float, so they are platform independent, but slow. On x86 and
- * other IEEE 754 compliant platforms the conversion can be accelerated by
- * bit shifting the exponent and mantissa. There are also some SSE-based
- * assembly routines out there.
+/* float_16_to_32() and float_32_to_16() convert 16 bit floats in the
+ * FLOAT16 data type to standard C floats and vice versa. They do not
+ * depend on the encoding of the C float, so they are platform independent,
+ * but slow. On x86 and other IEEE 754 compliant platforms the conversion
+ * can be accelerated by bit shifting the exponent and mantissa. There are
+ * also some SSE-based assembly routines out there.
*
* See GL_NV_half_float for a reference of the FLOAT16 / GL_HALF format
*/
@@ -404,6 +403,68 @@ static inline float float_24_to_32(DWORD in)
}
}
+static inline unsigned short float_32_to_16(const float *in)
+{
+ int exp = 0;
+ float tmp = fabsf(*in);
+ unsigned int mantissa;
+ unsigned short ret;
+
+ /* Deal with special numbers */
+ if (*in == 0.0f)
+ return 0x0000;
+ if (isnan(*in))
+ return 0x7c01;
+ if (isinf(*in))
+ return (*in < 0.0f ? 0xfc00 : 0x7c00);
+
+ if (tmp < (float)(1u << 10))
+ {
+ do
+ {
+ tmp = tmp * 2.0f;
+ exp--;
+ } while (tmp < (float)(1u << 10));
+ }
+ else if (tmp >= (float)(1u << 11))
+ {
+ do
+ {
+ tmp /= 2.0f;
+ exp++;
+ } while (tmp >= (float)(1u << 11));
+ }
+
+ mantissa = (unsigned int)tmp;
+ if (tmp - mantissa >= 0.5f)
+ ++mantissa; /* Round to nearest, away from zero. */
+
+ exp += 10; /* Normalize the mantissa. */
+ exp += 15; /* Exponent is encoded with excess 15. */
+
+ if (exp > 30) /* too big */
+ {
+ ret = 0x7c00; /* INF */
+ }
+ else if (exp <= 0)
+ {
+ /* exp == 0: Non-normalized mantissa. Returns 0x0000 (=0.0) for too small numbers. */
+ while (exp <= 0)
+ {
+ mantissa = mantissa >> 1;
+ ++exp;
+ }
+ ret = mantissa & 0x3ff;
+ }
+ else
+ {
+ ret = (exp << 10) | (mantissa & 0x3ff);
+ }
+
+ ret |= ((*in < 0.0f ? 1 : 0) << 15); /* Add the sign */
+ return ret;
+}
+
static inline unsigned int wined3d_popcount(unsigned int x)
{
#if defined(__MINGW32__)
More information about the wine-cvs
mailing list