[PATCH] d3dx9: Add support for QWVU formats in filter_copy_simple_data
Tony Wasserka
tony.wasserka at freenet.de
Wed Jul 15 10:41:24 CDT 2009
---
dlls/d3dx9_36/d3dx9_36_private.h | 1 +
dlls/d3dx9_36/surface.c | 44 ++++++++++++++++++++++++++++++++-----
dlls/d3dx9_36/util.c | 7 ++++++
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 6dff2a9..8474ef5 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -34,6 +34,7 @@
typedef enum _StaticFormatType {
FORMAT_ARGB,
FORMAT_ABGR,
+ FORMAT_QWVU,
FORMAT_UNKNOWN
} StaticFormatType;
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 635d412..b8530e9 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -328,7 +328,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromResourceW(LPDIRECT3DSURFACE9 pDestSurface,
* get_masks
*
* Returns the masks necessary to split a pixel into its components.
- * Works only for ARGB and ABGR formats with 1 - 4 bytes per pixel.
+ * Works only for ARGB, ABGR and QWVU formats with 1 - 4 bytes per pixel.
*
*/
void get_masks(StaticPixelFormatDesc format, DWORD *amask, DWORD *rmask, DWORD *gmask, DWORD *bmask)
@@ -338,7 +338,7 @@ void get_masks(StaticPixelFormatDesc format, DWORD *amask, DWORD *rmask, DWORD *
*rmask = ((1 << format.rbits) - 1) << (format.gbits + format.bbits);
*gmask = ((1 << format.gbits) - 1) << (format.bbits);
*bmask = (1 << format.bbits) - 1;
- } else if(format.type == FORMAT_ABGR) {
+ } else if(format.type == FORMAT_ABGR || format.type == FORMAT_QWVU) {
*amask = ((1 << format.abits) - 1) << (format.bbits + format.gbits + format.rbits);
*bmask = ((1 << format.bbits) - 1) << (format.gbits + format.rbits);
*gmask = ((1 << format.gbits) - 1) << (format.rbits);
@@ -347,11 +347,31 @@ void get_masks(StaticPixelFormatDesc format, DWORD *amask, DWORD *rmask, DWORD *
}
/************************************************************
+ * get_sign_mask
+ *
+ * Returns the masks necessary to convert a pixel to unsigned-only channels.
+ * Works only for QWVU formats with 1 - 4 bytes per pixel.
+ *
+ * Converting is done like this: col ^= mask
+ *
+ */
+void get_sign_mask(StaticPixelFormatDesc format, DWORD *mask)
+{
+ if(format.format == D3DFMT_V8U8) *mask = (1 << 7) | (1 << 15);
+ else if(format.format == D3DFMT_L6V5U5) *mask = (1 << 4) | (1 << 9);
+ else if(format.format == D3DFMT_V16U16) *mask = (1 << 15) | (1 << 31);
+ else if(format.format == D3DFMT_X8L8V8U8) *mask = (1 << 7) | (1 << 15);
+ else if(format.format == D3DFMT_A2W10V10U10) *mask = (1 << 9) | (1 << 19) | (1 << 29);
+ else if(format.format == D3DFMT_Q8W8V8U8) *mask = (1 << 7) | (1 << 15) | (1<<23) | (1<<31);
+ else *mask = 0;
+}
+
+/************************************************************
* get_shifts
*
* Returns the (nonnegative) shifts necessary to extract each component of a pixel
* and scale it to the destination format's bits per channel.
- * Works only for ARGB and ABGR formats.
+ * Works only for ARGB, ABGR and QWVU formats.
*
*/
void get_shifts(StaticPixelFormatDesc srcformat, StaticPixelFormatDesc destformat, DWORD *ashift, DWORD *rshift, DWORD *gshift, DWORD *bshift)
@@ -361,13 +381,12 @@ void get_shifts(StaticPixelFormatDesc srcformat, StaticPixelFormatDesc destforma
*rshift = srcformat.gbits + srcformat.bbits + max(srcformat.rbits - destformat.rbits, 0);
*gshift = srcformat.bbits + max(srcformat.gbits - destformat.gbits, 0);
*bshift = max(srcformat.bbits - destformat.bbits, 0);
- } else if(srcformat.type == FORMAT_ABGR) {
+ } else if(srcformat.type == FORMAT_ABGR || srcformat.type == FORMAT_QWVU) {
*ashift = srcformat.bbits + srcformat.gbits + srcformat.rbits + max(srcformat.abits - destformat.abits, 0);
*bshift = srcformat.gbits + srcformat.rbits + max(srcformat.bbits - destformat.bbits, 0);
*gshift = srcformat.rbits + max(srcformat.gbits - destformat.gbits, 0);
*rshift = max(srcformat.rbits - destformat.rbits, 0);
}
-
}
/************************************************************
@@ -382,6 +401,7 @@ void convert_a8r8g8b8_to_format(DWORD *col, DWORD *mask, StaticPixelFormatDesc d
DWORD srcshifta, srcshiftr, srcshiftg, srcshiftb;
DWORD destshifta, destshiftr, destshiftg, destshiftb;
DWORD amask, rmask, gmask, bmask;
+ DWORD signmask;
StaticPixelFormatDesc srcformat;
get_format_info(D3DFMT_A8R8G8B8, &srcformat);
@@ -390,12 +410,14 @@ void convert_a8r8g8b8_to_format(DWORD *col, DWORD *mask, StaticPixelFormatDesc d
get_shifts(destformat, srcformat, &destshifta, &destshiftr, &destshiftg, &destshiftb);
get_masks(destformat, &amask, &rmask, &gmask, &bmask);
+ get_sign_mask(destformat, &signmask);
*col = (((*col >> srcshifta) << destshifta) & amask) +
(((*col >> srcshiftr) << destshiftr) & rmask) +
(((*col >> srcshiftg) << destshiftg) & gmask) +
(((*col >> srcshiftb) << destshiftb) & bmask);
+ *col ^= signmask;
*mask = amask + rmask + gmask + bmask;
}
@@ -404,7 +426,7 @@ void convert_a8r8g8b8_to_format(DWORD *col, DWORD *mask, StaticPixelFormatDesc d
*
* Copies the source buffer to the destination buffer, performing
* any necessary format conversion and color keying.
- * Works only for ARGB and ABGR formats with 1 - 4 bytes per pixel.
+ * Works only for ARGB, ABGR and QWVU formats with 1 - 4 bytes per pixel.
*/
void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, StaticPixelFormatDesc SrcFormat,
LPBYTE pDest, UINT DestPitch, POINT DestSize, StaticPixelFormatDesc DestFormat,
@@ -412,6 +434,7 @@ void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, Stati
{
DWORD SrcShiftA, SrcShiftR, SrcShiftG, SrcShiftB;
DWORD DestShiftA, DestShiftR, DestShiftG, DestShiftB;
+ DWORD SrcSignMask, DestSignMask;
DWORD MaskA, MaskR, MaskG, MaskB;
UINT MinWidth, MinHeight;
BYTE *pSrcPtr, *pDestPtr;
@@ -424,6 +447,9 @@ void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, Stati
get_masks(DestFormat, &MaskA, &MaskR, &MaskG, &MaskB);
if(dwColorKey) convert_a8r8g8b8_to_format(&dwColorKey, &CK_Mask, SrcFormat);
+ get_sign_mask( SrcFormat, &SrcSignMask);
+ get_sign_mask(DestFormat, &DestSignMask);
+
MinWidth = (SrcSize.x < DestSize.x) ? SrcSize.x : DestSize.x;
MinHeight = (SrcSize.y < DestSize.y) ? SrcSize.y : DestSize.y;
@@ -443,6 +469,9 @@ void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, Stati
continue;
}
+ /* convert to unsigned if necessary */
+ if(SrcSignMask) Col ^= SrcSignMask;
+
/* convert bits per channel */
if(SrcFormat.abits) *pPixel = ((Col >> SrcShiftA) << DestShiftA) & MaskA;
else *pPixel = MaskA;
@@ -456,6 +485,9 @@ void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, Stati
if(SrcFormat.bbits) *pPixel += ((Col >> SrcShiftB) << DestShiftB) & MaskB;
else *pPixel |= MaskB;
+ /* convert to signed if necessary */
+ if(DestSignMask) *pPixel ^= DestSignMask;
+
pSrcPtr += SrcFormat.bpp;
pDestPtr += DestFormat.bpp;
}
diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c
index 210d66f..27c66e1 100644
--- a/dlls/d3dx9_36/util.c
+++ b/dlls/d3dx9_36/util.c
@@ -48,6 +48,13 @@ static const StaticPixelFormatDesc formats[] =
{ D3DFMT_A2R10G10B10, 2, 10, 10, 10, 4, FORMAT_ARGB },
{ D3DFMT_A16B16G16R16, 16, 16, 16, 16, 8, FORMAT_ABGR },
+ { D3DFMT_Q8W8V8U8, 8, 8, 8, 8, 4, FORMAT_QWVU },
+ { D3DFMT_X8L8V8U8, 8, 8, 8, 0, 4, FORMAT_QWVU },
+ { D3DFMT_V16U16, 0, 16, 16, 0, 4, FORMAT_QWVU },
+ { D3DFMT_V8U8, 0, 8, 8, 0, 2, FORMAT_QWVU },
+ { D3DFMT_L6V5U5, 6, 5, 5, 0, 2, FORMAT_QWVU },
+ { D3DFMT_A2W10V10U10, 2, 10, 10, 10, 4, FORMAT_QWVU },
+
{ D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, FORMAT_UNKNOWN }, /* marks last element */
};
--
1.6.0.2
--------------030707060201050508050600--
More information about the wine-patches
mailing list