Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 3: Remove traces that might read beyond the input buffer, add a comment on the input size. Version 2: Don't insist on a 16 byte output buffer. --- 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..26698b1ab04 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 = 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; + + ret_i = ret; + ret_i[idx.x] = ((uint32_t)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x; + ret_i[idx.y] |= ((uint32_t)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y; + ret_i[idx.z] |= ((uint32_t)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z; + ret_i[idx.w] |= ((uint32_t)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].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;
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 2: Check for WINED3DFMT_FLAG_FLOAT instead of explicitly listing expected float formats. --- dlls/wined3d/resource.c | 6 ++++++ dlls/wined3d/utils.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 073bc5b5834..ed5d5d63250 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -668,6 +668,12 @@ void wined3d_resource_memory_colour_fill(struct wined3d_resource *resource, ((uint32_t *)dst)[x] = c[0]; } break; + case 8: + case 12: + case 16: + for (x = 0; x < w; ++x) + memcpy(((uint8_t *)map->data) + x * bpp, c, bpp); + break;
default: FIXME("Not implemented for bpp %u.\n", bpp); diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 26698b1ab04..6a21ca4dcc5 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6116,6 +6116,27 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, cons return; }
+ /* 32 bit float formats. We don't handle D32_FLOAT and D32_FLOAT_S8X24_UINT for now. */ + if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 32) + { + float *ret_f = ret; + + switch (format->byte_count) + { + case 16: ret_f[3] = color->a; + case 12: ret_f[2] = color->b; + case 8: ret_f[1] = color->g; + case 4: ret_f[0] = 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)); }
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 2: Like in the float32 patch, don't explicitly list the formats. --- 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 6a21ca4dcc5..61a86082249 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, cons 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__)
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
wined3d_typed_format_info seems like the wrong place for this because these formats do not have matching typeless formats. --- dlls/wined3d/utils.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 61a86082249..29bebcf0cfc 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -345,7 +345,16 @@ static const struct wined3d_format_base_flags format_base_flags[] = {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_CAST_TO_BLOCK}, {WINED3DFMT_R32_UINT, WINED3DFMT_FLAG_CAST_TO_BLOCK | WINED3DFMT_FLAG_INDEX_BUFFER}, {WINED3DFMT_R32_SINT, WINED3DFMT_FLAG_CAST_TO_BLOCK}, - {WINED3DFMT_R16_UINT, WINED3DFMT_FLAG_INDEX_BUFFER}, + {WINED3DFMT_A8_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B10G10R10A2_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B2G3R3_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_NORMALISED}, + {WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_FLAG_NORMALISED}, };
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b)
On 5/15/22 07:29, Stefan Dösinger wrote:
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
wined3d_typed_format_info seems like the wrong place for this because these formats do not have matching typeless formats.
dlls/wined3d/utils.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 61a86082249..29bebcf0cfc 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -345,7 +345,16 @@ static const struct wined3d_format_base_flags format_base_flags[] = {WINED3DFMT_R32_FLOAT, WINED3DFMT_FLAG_CAST_TO_BLOCK}, {WINED3DFMT_R32_UINT, WINED3DFMT_FLAG_CAST_TO_BLOCK | WINED3DFMT_FLAG_INDEX_BUFFER}, {WINED3DFMT_R32_SINT, WINED3DFMT_FLAG_CAST_TO_BLOCK},
- {WINED3DFMT_R16_UINT, WINED3DFMT_FLAG_INDEX_BUFFER},
I assume this deletion is accidental; I'll send a new revision with the line restored.
{WINED3DFMT_A8_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B10G10R10A2_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B2G3R3_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B4G4R4A4_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B4G4R4X4_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B5G5R5A1_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B5G5R5X1_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B5G6R5_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_B8G8R8_UNORM, WINED3DFMT_FLAG_NORMALISED},
{WINED3DFMT_R10G10B10A2_UNORM, WINED3DFMT_FLAG_NORMALISED}, };
static void rgb888_from_rgb565(WORD rgb565, BYTE *r, BYTE *g, BYTE *b)
Am 16.05.2022 um 08:49 schrieb Zebediah Figura zfigura@codeweavers.com:
I assume this deletion is accidental; I'll send a new revision with the line restored.
Indeed, thanks for catching it...
Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 2: Instead of extending the table with 16 bit formats look at the format properties. --- dlls/wined3d/utils.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 29bebcf0cfc..e7a1fbe4c7a 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6026,21 +6026,6 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, cons } float_conv[] = { - {WINED3DFMT_B8G8R8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B8G8R8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B8G8R8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, {16, 8, 0, 24}}, - {WINED3DFMT_B5G6R5_UNORM, { 31.0f, 63.0f, 31.0f, 0.0f}, {11, 5, 0, 0}}, - {WINED3DFMT_B5G5R5A1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, - {WINED3DFMT_B5G5R5X1_UNORM, { 31.0f, 31.0f, 31.0f, 1.0f}, {10, 5, 0, 15}}, - {WINED3DFMT_R8_UNORM, { 255.0f, 0.0f, 0.0f, 0.0f}, { 0, 0, 0, 0}}, - {WINED3DFMT_A8_UNORM, { 0.0f, 0.0f, 0.0f, 255.0f}, { 0, 0, 0, 0}}, - {WINED3DFMT_B4G4R4A4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, - {WINED3DFMT_B4G4R4X4_UNORM, { 15.0f, 15.0f, 15.0f, 15.0f}, { 8, 4, 0, 12}}, - {WINED3DFMT_B2G3R3_UNORM, { 7.0f, 7.0f, 3.0f, 0.0f}, { 5, 2, 0, 0}}, - {WINED3DFMT_R8G8B8A8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, - {WINED3DFMT_R8G8B8X8_UNORM, { 255.0f, 255.0f, 255.0f, 255.0f}, { 0, 8, 16, 24}}, - {WINED3DFMT_B10G10R10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, {20, 10, 0, 30}}, - {WINED3DFMT_R10G10B10A2_UNORM, { 1023.0f, 1023.0f, 1023.0f, 3.0f}, { 0, 10, 20, 30}}, {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}}, @@ -6125,6 +6110,27 @@ void wined3d_format_convert_from_float(const struct wined3d_format *format, cons return; }
+ if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_NORMALISED)) + { + uint32_t *ret_i = ret; + + idx.x = format->red_offset / 32; + idx.y = format->green_offset / 32; + idx.z = format->blue_offset / 32; + idx.w = format->alpha_offset / 32; + shift.x = format->red_offset % 32; + shift.y = format->green_offset % 32; + shift.z = format->blue_offset % 32; + shift.w = format->alpha_offset % 32; + + ret_i[idx.x] = ((uint32_t)((color->r * wined3d_mask_from_size(format->red_size)) + 0.5f)) << shift.x; + ret_i[idx.y] |= ((uint32_t)((color->g * wined3d_mask_from_size(format->green_size)) + 0.5f)) << shift.y; + ret_i[idx.z] |= ((uint32_t)((color->b * wined3d_mask_from_size(format->blue_size)) + 0.5f)) << shift.z; + ret_i[idx.w] |= ((uint32_t)((color->a * wined3d_mask_from_size(format->alpha_size)) + 0.5f)) << shift.w; + + return; + } + /* 32 bit float formats. We don't handle D32_FLOAT and D32_FLOAT_S8X24_UINT for now. */ if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT) && format->red_size == 32) {
On 5/15/22 07:29, Stefan Dösinger wrote:
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 = 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;
ret_i = ret;
ret_i[idx.x] = ((uint32_t)((color->r * double_conv[i].mul.x) + 0.5)) << double_conv[i].shift.x;
ret_i[idx.y] |= ((uint32_t)((color->g * double_conv[i].mul.y) + 0.5)) << double_conv[i].shift.y;
ret_i[idx.z] |= ((uint32_t)((color->b * double_conv[i].mul.z) + 0.5)) << double_conv[i].shift.z;
ret_i[idx.w] |= ((uint32_t)((color->a * double_conv[i].mul.w) + 0.5)) << double_conv[i].shift.w;
There seem to be some copy-paste (or failure-to-copy-paste) errors here. I'll send a new revision.