[PATCH 1/4] wined3d: Properly up-scale WINED3DFMT_R5G5_SNORM_L6_UNORM.
Stefan Dösinger
stefan at codeweavers.com
Mon Mar 2 15:29:09 CST 2015
Simply left-shifting is not enough in positive ranges. 0xff / 255 !=
0xff00 / 65535.
Using the compiler to read 5 bit signed values seems a lot easier than
operating with masks.
---
dlls/wined3d/utils.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 1ce23ac..67457d5 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -290,6 +290,15 @@ static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, U
}
}
+#include <pshpack1.h>
+struct r5g5l6
+{
+ signed r : 5;
+ signed g : 5;
+ unsigned l : 6;
+};
+#include <poppack.h>
+
static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
@@ -322,8 +331,8 @@ static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y, z;
- const WORD *Source;
- unsigned char *Dest;
+ unsigned char *texel_out, out_ds, out_dt;
+ const struct r5g5l6 *texel_in;
/* This makes the gl surface bigger(24 bit instead of 16), but it works with
* fixed function and shaders without further conversion once the surface is
@@ -333,27 +342,24 @@ static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_
{
for (y = 0; y < height; y++)
{
- Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
- Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
+ texel_in = (const struct r5g5l6 *)(src + z * src_slice_pitch + y * src_row_pitch);
+ texel_out = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
- short color = (*Source++);
- unsigned char l = ((color >> 10) & 0xfc);
- char v = ((color >> 5) & 0x3e);
- char u = ((color ) & 0x1f);
+ out_ds = texel_in->r << 3;
+ if (texel_in->r > 0)
+ out_ds |= texel_in->r >> 1;
- /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
- * and doubles the positive range. Thus shift left only once, gl does the 2nd
- * shift. GL reads a signed value and converts it into an unsigned value.
- */
- /* M */ Dest[2] = l << 1;
+ out_dt = texel_in->g << 3;
+ if (texel_in->g > 0)
+ out_dt |= texel_in->g >> 1;
- /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
- * from 5 bit values to 8 bit values.
- */
- /* V */ Dest[1] = v << 3;
- /* U */ Dest[0] = u << 3;
- Dest += 3;
+ texel_out[0] = out_ds;
+ texel_out[1] = out_dt;
+ texel_out[2] = texel_in->l << 1 | texel_in->l >> 5;
+
+ texel_out += 3;
+ texel_in++;
}
}
}
--
2.3.0
More information about the wine-patches
mailing list