Henri Verbeet : d3dx9: Add basic support for loading DXT formats to D3DXLoadSurfaceFromMemory().

Alexandre Julliard julliard at winehq.org
Fri Apr 27 10:55:45 CDT 2012


Module: wine
Branch: master
Commit: b11d8db279d52e836f8f95a6b18cf12645622a77
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b11d8db279d52e836f8f95a6b18cf12645622a77

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Apr 26 21:11:55 2012 +0200

d3dx9: Add basic support for loading DXT formats to D3DXLoadSurfaceFromMemory().

---

 dlls/d3dx9_36/d3dx9_36_private.h |    3 ++
 dlls/d3dx9_36/surface.c          |   27 +++++++++++++++++++----
 dlls/d3dx9_36/util.c             |   43 +++++++++++++++++++++----------------
 3 files changed, 49 insertions(+), 24 deletions(-)

diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 95006e4..a6c4fcd 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -48,6 +48,9 @@ typedef struct _PixelFormatDesc {
     BYTE bits[4];
     BYTE shift[4];
     UINT bytes_per_pixel;
+    UINT block_width;
+    UINT block_height;
+    UINT block_byte_count;
     FormatType type;
     void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
     void (*to_rgba)(const struct vec4 *src, struct vec4 *dst);
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index 49d4c1e..567282c 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -983,21 +983,34 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
             && destsize.x == srcsize.x
             && destsize.y == srcsize.y) /* Simple copy. */
     {
+        UINT row_block_count = ((srcsize.x + srcformatdesc->block_width - 1) / srcformatdesc->block_width);
+        UINT row_count = (srcsize.y + srcformatdesc->block_height - 1) / srcformatdesc->block_height;
         const BYTE *src_addr;
         BYTE *dst_addr;
-        UINT y;
+        UINT row;
+
+        if (pSrcRect->left & (srcformatdesc->block_width - 1)
+                || pSrcRect->top & (srcformatdesc->block_height - 1)
+                || (pSrcRect->right & (srcformatdesc->block_width - 1)
+                    && srcsize.x != surfdesc.Width)
+                || (pSrcRect->bottom & (srcformatdesc->block_height - 1)
+                    && srcsize.y != surfdesc.Height))
+        {
+            WARN("Source rect %s is misaligned.\n", wine_dbgstr_rect(pSrcRect));
+            return D3DXERR_INVALIDDATA;
+        }
 
         if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
             return D3DXERR_INVALIDDATA;
 
         src_addr = pSrcMemory;
-        src_addr += pSrcRect->top * SrcPitch;
-        src_addr += pSrcRect->left * srcformatdesc->bytes_per_pixel;
+        src_addr += (pSrcRect->top / srcformatdesc->block_height) * SrcPitch;
+        src_addr += (pSrcRect->left / srcformatdesc->block_width) * srcformatdesc->block_byte_count;
         dst_addr = lockrect.pBits;
 
-        for (y = 0; y < srcsize.y; ++y)
+        for (row = 0; row < row_count; ++row)
         {
-            memcpy(dst_addr, src_addr, srcsize.x * srcformatdesc->bytes_per_pixel);
+            memcpy(dst_addr, src_addr, row_block_count * srcformatdesc->block_byte_count);
             src_addr += SrcPitch;
             dst_addr += lockrect.Pitch;
         }
@@ -1010,6 +1023,10 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
             return E_NOTIMPL;
         if (destformatdesc->bytes_per_pixel > 4)
             return E_NOTIMPL;
+        if (srcformatdesc->block_height != 1 || srcformatdesc->block_width != 1)
+            return E_NOTIMPL;
+        if (destformatdesc->block_height != 1 || destformatdesc->block_width != 1)
+            return E_NOTIMPL;
 
         if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
             return D3DXERR_INVALIDDATA;
diff --git a/dlls/d3dx9_36/util.c b/dlls/d3dx9_36/util.c
index 62ff996..4dbf44c 100644
--- a/dlls/d3dx9_36/util.c
+++ b/dlls/d3dx9_36/util.c
@@ -44,26 +44,31 @@ static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
  */
 static const PixelFormatDesc formats[] =
 {
-    /* format            bpc              shifts            bpp type            from_rgba     to_rgba */
-    {D3DFMT_R8G8B8,      {0,  8,  8,  8}, { 0, 16,  8,  0}, 3,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A8R8G8B8,    {8,  8,  8,  8}, {24, 16,  8,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_X8R8G8B8,    {0,  8,  8,  8}, { 0, 16,  8,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A8B8G8R8,    {8,  8,  8,  8}, {24,  0,  8, 16}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_X8B8G8R8,    {0,  8,  8,  8}, { 0,  0,  8, 16}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_R5G6B5,      {0,  5,  6,  5}, { 0, 11,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_X1R5G5B5,    {0,  5,  5,  5}, { 0, 10,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A1R5G5B5,    {1,  5,  5,  5}, {15, 10,  5,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_R3G3B2,      {0,  3,  3,  2}, { 0,  5,  2,  0}, 1,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A8R3G3B2,    {8,  3,  3,  2}, { 8,  5,  2,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A4R4G4B4,    {4,  4,  4,  4}, {12,  8,  4,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_X4R4G4B4,    {0,  4,  4,  4}, { 0,  8,  4,  0}, 2,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A2R10G10B10, {2, 10, 10, 10}, {30, 20, 10,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A2B10G10R10, {2, 10, 10, 10}, {30,  0, 10, 20}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_G16R16,      {0, 16, 16,  0}, { 0,  0, 16,  0}, 4,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A8,          {8,  0,  0,  0}, { 0,  0,  0,  0}, 1,  FORMAT_ARGB,    NULL,         NULL      },
-    {D3DFMT_A8L8,        {8,  8,  0,  0}, { 8,  0,  0,  0}, 2,  FORMAT_ARGB,    la_from_rgba, la_to_rgba},
+    /* format            bpc              shifts            bpp blocks   type            from_rgba     to_rgba */
+    {D3DFMT_R8G8B8,      {0,  8,  8,  8}, { 0, 16,  8,  0}, 3, 1, 1,  3, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A8R8G8B8,    {8,  8,  8,  8}, {24, 16,  8,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_X8R8G8B8,    {0,  8,  8,  8}, { 0, 16,  8,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A8B8G8R8,    {8,  8,  8,  8}, {24,  0,  8, 16}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_X8B8G8R8,    {0,  8,  8,  8}, { 0,  0,  8, 16}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_R5G6B5,      {0,  5,  6,  5}, { 0, 11,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_X1R5G5B5,    {0,  5,  5,  5}, { 0, 10,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A1R5G5B5,    {1,  5,  5,  5}, {15, 10,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_R3G3B2,      {0,  3,  3,  2}, { 0,  5,  2,  0}, 1, 1, 1,  1, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A8R3G3B2,    {8,  3,  3,  2}, { 8,  5,  2,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A4R4G4B4,    {4,  4,  4,  4}, {12,  8,  4,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_X4R4G4B4,    {0,  4,  4,  4}, { 0,  8,  4,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A2R10G10B10, {2, 10, 10, 10}, {30, 20, 10,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A2B10G10R10, {2, 10, 10, 10}, {30,  0, 10, 20}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_G16R16,      {0, 16, 16,  0}, { 0,  0, 16,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A8,          {8,  0,  0,  0}, { 0,  0,  0,  0}, 1, 1, 1,  1, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_A8L8,        {8,  8,  0,  0}, { 8,  0,  0,  0}, 2, 1, 1,  2, FORMAT_ARGB,    la_from_rgba, la_to_rgba},
+    {D3DFMT_DXT1,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4,  8, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_DXT2,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_DXT3,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_DXT4,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
+    {D3DFMT_DXT5,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
     /* marks last element */
-    {D3DFMT_UNKNOWN,     {0,  0,  0,  0}, { 0,  0,  0,  0}, 0,  FORMAT_UNKNOWN, NULL,         NULL      },
+    {D3DFMT_UNKNOWN,     {0,  0,  0,  0}, { 0,  0,  0,  0}, 0, 1, 1,  0, FORMAT_UNKNOWN, NULL,         NULL      },
 };
 
 




More information about the wine-cvs mailing list