Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
Version 2: Don't insist on a 16 byte output buffer.
Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/wined3d/device.c | 4 +-- dlls/wined3d/resource.c | 16 ++++----- dlls/wined3d/utils.c | 61 ++++++++++++++++++++++++---------- dlls/wined3d/wined3d_private.h | 4 +-- 4 files changed, 56 insertions(+), 29 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..3017265ccb0 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6000,8 +6000,12 @@ 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.) */ +void wined3d_format_convert_from_float(const struct wined3d_format *format, const struct wined3d_color *color, + void *ret) { static const struct { @@ -6044,10 +6048,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, format->byte_count);
for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) { @@ -6062,37 +6067,59 @@ 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; + + 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;
- TRACE("Returning 0x%08x.\n", ret); + TRACE("Returning 0x%08x 0x%08x 0x%08x 0x%08x.\n", + ret_i[0], ret_i[1], ret_i[2], ret_i[3]);
- 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;
- TRACE("Returning 0x%08x.\n", ret); + 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;
- return ret; + TRACE("Returning 0x%08x 0x%08x 0x%08x 0x%08x.\n", ret_i[0], ret_i[1], ret_i[2], ret_i[3]); + + 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 05d71140a16..c5c2a51bc5e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -6151,8 +6151,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;