From b11d8db279d52e836f8f95a6b18cf12645622a77 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 26 Apr 2012 21:11:55 +0200 Subject: [PATCH] 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 95006e46ae9..a6c4fcdc9f2 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 49d4c1e0150..567282ca9e3 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 62ff99627bc..4dbf44ca927 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 }, };