[PATCH 5/5] d3dx9: Add basic support for loading DXT formats to D3DXLoadSurfaceFromMemory().
Henri Verbeet
hverbeet at codeweavers.com
Thu Apr 26 14:11:55 CDT 2012
---
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 },
};
--
1.7.3.4
More information about the wine-patches
mailing list