d3dx9: Handle pixel formats larger than 32 bits in surface loading / filtering functions.
This commit is contained in:
parent
73e4f6200e
commit
950c40b117
|
@ -98,6 +98,7 @@ HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, co
|
||||||
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
|
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN;
|
unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN;
|
||||||
|
float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* debug helpers */
|
/* debug helpers */
|
||||||
const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;
|
const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -2226,7 +2226,7 @@ D3DXFLOAT16 *WINAPI D3DXFloat32To16Array(D3DXFLOAT16 *pout, const FLOAT *pin, UI
|
||||||
|
|
||||||
/* Native d3dx9's D3DXFloat16to32Array lacks support for NaN and Inf. Specifically, e = 16 is treated as a
|
/* Native d3dx9's D3DXFloat16to32Array lacks support for NaN and Inf. Specifically, e = 16 is treated as a
|
||||||
* regular number - e.g., 0x7fff is converted to 131008.0 and 0xffff to -131008.0. */
|
* regular number - e.g., 0x7fff is converted to 131008.0 and 0xffff to -131008.0. */
|
||||||
static inline float float_16_to_32(const unsigned short in)
|
float float_16_to_32(const unsigned short in)
|
||||||
{
|
{
|
||||||
const unsigned short s = (in & 0x8000);
|
const unsigned short s = (in & 0x8000);
|
||||||
const unsigned short e = (in & 0x7C00) >> 10;
|
const unsigned short e = (in & 0x7C00) >> 10;
|
||||||
|
|
|
@ -1339,33 +1339,6 @@ static void init_argb_conversion_info(const struct pixel_format_desc *srcformat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD dword_from_bytes(const BYTE *src, UINT bytes_per_pixel)
|
|
||||||
{
|
|
||||||
DWORD ret = 0;
|
|
||||||
static BOOL fixme_once;
|
|
||||||
|
|
||||||
if(bytes_per_pixel > sizeof(DWORD)) {
|
|
||||||
if(!fixme_once++) FIXME("Unsupported image: %u bytes per pixel\n", bytes_per_pixel);
|
|
||||||
bytes_per_pixel = sizeof(DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&ret, src, bytes_per_pixel);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dword_to_bytes(BYTE *dst, DWORD dword, UINT bytes_per_pixel)
|
|
||||||
{
|
|
||||||
static BOOL fixme_once;
|
|
||||||
|
|
||||||
if(bytes_per_pixel > sizeof(DWORD)) {
|
|
||||||
if(!fixme_once++) FIXME("Unsupported image: %u bytes per pixel\n", bytes_per_pixel);
|
|
||||||
ZeroMemory(dst, bytes_per_pixel);
|
|
||||||
bytes_per_pixel = sizeof(DWORD);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dst, &dword, bytes_per_pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
* get_relevant_argb_components
|
* get_relevant_argb_components
|
||||||
*
|
*
|
||||||
|
@ -1403,55 +1376,78 @@ static DWORD make_argb_color(const struct argb_conversion_info *info, const DWOR
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void format_to_vec4(const struct pixel_format_desc *format, const DWORD *src, struct vec4 *dst)
|
/* It doesn't work for components bigger than 32 bits (or somewhat smaller but unaligned). */
|
||||||
|
static void format_to_vec4(const struct pixel_format_desc *format, const BYTE *src, struct vec4 *dst)
|
||||||
{
|
{
|
||||||
DWORD mask;
|
DWORD mask, tmp;
|
||||||
|
unsigned int c;
|
||||||
|
|
||||||
if (format->bits[1])
|
for (c = 0; c < 4; ++c)
|
||||||
{
|
{
|
||||||
mask = (1 << format->bits[1]) - 1;
|
static const unsigned int component_offsets[4] = {3, 0, 1, 2};
|
||||||
dst->x = (float)((*src >> format->shift[1]) & mask) / mask;
|
float *dst_component = (float *)dst + component_offsets[c];
|
||||||
}
|
|
||||||
else
|
|
||||||
dst->x = 1.0f;
|
|
||||||
|
|
||||||
if (format->bits[2])
|
if (format->bits[c])
|
||||||
{
|
{
|
||||||
mask = (1 << format->bits[2]) - 1;
|
mask = ~0u >> (32 - format->bits[c]);
|
||||||
dst->y = (float)((*src >> format->shift[2]) & mask) / mask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dst->y = 1.0f;
|
|
||||||
|
|
||||||
if (format->bits[3])
|
memcpy(&tmp, src + format->shift[c] / 8,
|
||||||
{
|
min(sizeof(DWORD), (format->shift[c] % 8 + format->bits[c] + 7) / 8));
|
||||||
mask = (1 << format->bits[3]) - 1;
|
|
||||||
dst->z = (float)((*src >> format->shift[3]) & mask) / mask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dst->z = 1.0f;
|
|
||||||
|
|
||||||
if (format->bits[0])
|
if (format->type == FORMAT_ARGBF16)
|
||||||
{
|
*dst_component = float_16_to_32(tmp);
|
||||||
mask = (1 << format->bits[0]) - 1;
|
else if (format->type == FORMAT_ARGBF)
|
||||||
dst->w = (float)((*src >> format->shift[0]) & mask) / mask;
|
*dst_component = *(float *)&tmp;
|
||||||
|
else
|
||||||
|
*dst_component = (float)((tmp >> format->shift[c] % 8) & mask) / mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*dst_component = 1.0f;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
dst->w = 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void format_from_vec4(const struct pixel_format_desc *format, const struct vec4 *src, DWORD *dst)
|
/* It doesn't work for components bigger than 32 bits. */
|
||||||
|
static void format_from_vec4(const struct pixel_format_desc *format, const struct vec4 *src, BYTE *dst)
|
||||||
{
|
{
|
||||||
*dst = 0;
|
DWORD v, mask32;
|
||||||
|
unsigned int c, i;
|
||||||
|
|
||||||
if (format->bits[1])
|
memset(dst, 0, format->bytes_per_pixel);
|
||||||
*dst |= (DWORD)(src->x * ((1 << format->bits[1]) - 1) + 0.5f) << format->shift[1];
|
|
||||||
if (format->bits[2])
|
for (c = 0; c < 4; ++c)
|
||||||
*dst |= (DWORD)(src->y * ((1 << format->bits[2]) - 1) + 0.5f) << format->shift[2];
|
{
|
||||||
if (format->bits[3])
|
static const unsigned int component_offsets[4] = {3, 0, 1, 2};
|
||||||
*dst |= (DWORD)(src->z * ((1 << format->bits[3]) - 1) + 0.5f) << format->shift[3];
|
const float src_component = *((const float *)src + component_offsets[c]);
|
||||||
if (format->bits[0])
|
|
||||||
*dst |= (DWORD)(src->w * ((1 << format->bits[0]) - 1) + 0.5f) << format->shift[0];
|
if (!format->bits[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mask32 = ~0u >> (32 - format->bits[c]);
|
||||||
|
|
||||||
|
if (format->type == FORMAT_ARGBF16)
|
||||||
|
v = float_32_to_16(src_component);
|
||||||
|
else if (format->type == FORMAT_ARGBF)
|
||||||
|
v = *(DWORD *)&src_component;
|
||||||
|
else
|
||||||
|
v = (DWORD)(src_component * ((1 << format->bits[c]) - 1) + 0.5f);
|
||||||
|
|
||||||
|
for (i = format->shift[c] / 8 * 8; i < format->shift[c] + format->bits[c]; i += 8)
|
||||||
|
{
|
||||||
|
BYTE mask, byte;
|
||||||
|
|
||||||
|
if (format->shift[c] > i)
|
||||||
|
{
|
||||||
|
mask = mask32 << (format->shift[c] - i);
|
||||||
|
byte = (v << (format->shift[c] - i)) & mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = mask32 >> (i - format->shift[c]);
|
||||||
|
byte = (v >> (i - format->shift[c])) & mask;
|
||||||
|
}
|
||||||
|
dst[i / 8] |= byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
|
@ -1500,7 +1496,7 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
|
||||||
{
|
{
|
||||||
struct argb_conversion_info conv_info, ck_conv_info;
|
struct argb_conversion_info conv_info, ck_conv_info;
|
||||||
const struct pixel_format_desc *ck_format = NULL;
|
const struct pixel_format_desc *ck_format = NULL;
|
||||||
DWORD channels[4], pixel;
|
DWORD channels[4];
|
||||||
UINT min_width, min_height, min_depth;
|
UINT min_width, min_height, min_depth;
|
||||||
UINT x, y, z;
|
UINT x, y, z;
|
||||||
|
|
||||||
|
@ -1525,30 +1521,32 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
|
||||||
for (y = 0; y < min_height; y++) {
|
for (y = 0; y < min_height; y++) {
|
||||||
const BYTE *src_ptr = src_slice_ptr + y * src_row_pitch;
|
const BYTE *src_ptr = src_slice_ptr + y * src_row_pitch;
|
||||||
BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
|
BYTE *dst_ptr = dst_slice_ptr + y * dst_row_pitch;
|
||||||
DWORD val;
|
|
||||||
|
|
||||||
for (x = 0; x < min_width; x++) {
|
for (x = 0; x < min_width; x++) {
|
||||||
/* extract source color components */
|
if (!src_format->to_rgba && !dst_format->from_rgba
|
||||||
pixel = dword_from_bytes(src_ptr, src_format->bytes_per_pixel);
|
&& src_format->bytes_per_pixel <= 4 && dst_format->bytes_per_pixel <= 4)
|
||||||
|
|
||||||
if (!src_format->to_rgba && !dst_format->from_rgba)
|
|
||||||
{
|
{
|
||||||
get_relevant_argb_components(&conv_info, pixel, channels);
|
DWORD val;
|
||||||
|
|
||||||
|
get_relevant_argb_components(&conv_info, *(DWORD *)src_ptr, channels);
|
||||||
val = make_argb_color(&conv_info, channels);
|
val = make_argb_color(&conv_info, channels);
|
||||||
|
|
||||||
if (color_key)
|
if (color_key)
|
||||||
{
|
{
|
||||||
get_relevant_argb_components(&ck_conv_info, pixel, channels);
|
DWORD ck_pixel;
|
||||||
pixel = make_argb_color(&ck_conv_info, channels);
|
|
||||||
if (pixel == color_key)
|
get_relevant_argb_components(&ck_conv_info, *(DWORD *)src_ptr, channels);
|
||||||
|
ck_pixel = make_argb_color(&ck_conv_info, channels);
|
||||||
|
if (ck_pixel == color_key)
|
||||||
val &= ~conv_info.destmask[0];
|
val &= ~conv_info.destmask[0];
|
||||||
}
|
}
|
||||||
|
memcpy(dst_ptr, &val, dst_format->bytes_per_pixel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct vec4 color, tmp;
|
struct vec4 color, tmp;
|
||||||
|
|
||||||
format_to_vec4(src_format, &pixel, &color);
|
format_to_vec4(src_format, src_ptr, &color);
|
||||||
if (src_format->to_rgba)
|
if (src_format->to_rgba)
|
||||||
src_format->to_rgba(&color, &tmp, palette);
|
src_format->to_rgba(&color, &tmp, palette);
|
||||||
else
|
else
|
||||||
|
@ -1556,8 +1554,10 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
|
||||||
|
|
||||||
if (ck_format)
|
if (ck_format)
|
||||||
{
|
{
|
||||||
format_from_vec4(ck_format, &tmp, &pixel);
|
DWORD ck_pixel;
|
||||||
if (pixel == color_key)
|
|
||||||
|
format_from_vec4(ck_format, &tmp, (BYTE *)&ck_pixel);
|
||||||
|
if (ck_pixel == color_key)
|
||||||
tmp.w = 0.0f;
|
tmp.w = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1566,11 +1566,10 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
|
||||||
else
|
else
|
||||||
color = tmp;
|
color = tmp;
|
||||||
|
|
||||||
format_from_vec4(dst_format, &color, &val);
|
format_from_vec4(dst_format, &color, dst_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
dword_to_bytes(dst_ptr, val, dst_format->bytes_per_pixel);
|
src_ptr += src_format->bytes_per_pixel;
|
||||||
src_ptr += src_format->bytes_per_pixel;
|
|
||||||
dst_ptr += dst_format->bytes_per_pixel;
|
dst_ptr += dst_format->bytes_per_pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,7 +1599,7 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
||||||
{
|
{
|
||||||
struct argb_conversion_info conv_info, ck_conv_info;
|
struct argb_conversion_info conv_info, ck_conv_info;
|
||||||
const struct pixel_format_desc *ck_format = NULL;
|
const struct pixel_format_desc *ck_format = NULL;
|
||||||
DWORD channels[4], pixel;
|
DWORD channels[4];
|
||||||
UINT x, y, z;
|
UINT x, y, z;
|
||||||
|
|
||||||
ZeroMemory(channels, sizeof(channels));
|
ZeroMemory(channels, sizeof(channels));
|
||||||
|
@ -1626,29 +1625,31 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
||||||
for (x = 0; x < dst_size->width; x++)
|
for (x = 0; x < dst_size->width; x++)
|
||||||
{
|
{
|
||||||
const BYTE *src_ptr = src_row_ptr + (x * src_size->width / dst_size->width) * src_format->bytes_per_pixel;
|
const BYTE *src_ptr = src_row_ptr + (x * src_size->width / dst_size->width) * src_format->bytes_per_pixel;
|
||||||
DWORD val;
|
|
||||||
|
|
||||||
/* extract source color components */
|
if (!src_format->to_rgba && !dst_format->from_rgba
|
||||||
pixel = dword_from_bytes(src_ptr, src_format->bytes_per_pixel);
|
&& src_format->bytes_per_pixel <= 4 && dst_format->bytes_per_pixel <= 4)
|
||||||
|
|
||||||
if (!src_format->to_rgba && !dst_format->from_rgba)
|
|
||||||
{
|
{
|
||||||
get_relevant_argb_components(&conv_info, pixel, channels);
|
DWORD val;
|
||||||
|
|
||||||
|
get_relevant_argb_components(&conv_info, *(DWORD *)src_ptr, channels);
|
||||||
val = make_argb_color(&conv_info, channels);
|
val = make_argb_color(&conv_info, channels);
|
||||||
|
|
||||||
if (color_key)
|
if (color_key)
|
||||||
{
|
{
|
||||||
get_relevant_argb_components(&ck_conv_info, pixel, channels);
|
DWORD ck_pixel;
|
||||||
pixel = make_argb_color(&ck_conv_info, channels);
|
|
||||||
if (pixel == color_key)
|
get_relevant_argb_components(&ck_conv_info, *(DWORD *)src_ptr, channels);
|
||||||
|
ck_pixel = make_argb_color(&ck_conv_info, channels);
|
||||||
|
if (ck_pixel == color_key)
|
||||||
val &= ~conv_info.destmask[0];
|
val &= ~conv_info.destmask[0];
|
||||||
}
|
}
|
||||||
|
memcpy(dst_ptr, &val, dst_format->bytes_per_pixel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct vec4 color, tmp;
|
struct vec4 color, tmp;
|
||||||
|
|
||||||
format_to_vec4(src_format, &pixel, &color);
|
format_to_vec4(src_format, src_ptr, &color);
|
||||||
if (src_format->to_rgba)
|
if (src_format->to_rgba)
|
||||||
src_format->to_rgba(&color, &tmp, palette);
|
src_format->to_rgba(&color, &tmp, palette);
|
||||||
else
|
else
|
||||||
|
@ -1656,8 +1657,10 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
||||||
|
|
||||||
if (ck_format)
|
if (ck_format)
|
||||||
{
|
{
|
||||||
format_from_vec4(ck_format, &tmp, &pixel);
|
DWORD ck_pixel;
|
||||||
if (pixel == color_key)
|
|
||||||
|
format_from_vec4(ck_format, &tmp, (BYTE *)&ck_pixel);
|
||||||
|
if (ck_pixel == color_key)
|
||||||
tmp.w = 0.0f;
|
tmp.w = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1666,10 +1669,9 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
||||||
else
|
else
|
||||||
color = tmp;
|
color = tmp;
|
||||||
|
|
||||||
format_from_vec4(dst_format, &color, &val);
|
format_from_vec4(dst_format, &color, dst_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
dword_to_bytes(dst_ptr, val, dst_format->bytes_per_pixel);
|
|
||||||
dst_ptr += dst_format->bytes_per_pixel;
|
dst_ptr += dst_format->bytes_per_pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue