[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