Commit b11d8db2 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

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

parent e9255530
...@@ -48,6 +48,9 @@ typedef struct _PixelFormatDesc { ...@@ -48,6 +48,9 @@ typedef struct _PixelFormatDesc {
BYTE bits[4]; BYTE bits[4];
BYTE shift[4]; BYTE shift[4];
UINT bytes_per_pixel; UINT bytes_per_pixel;
UINT block_width;
UINT block_height;
UINT block_byte_count;
FormatType type; FormatType type;
void (*from_rgba)(const struct vec4 *src, struct vec4 *dst); void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
void (*to_rgba)(const struct vec4 *src, struct vec4 *dst); void (*to_rgba)(const struct vec4 *src, struct vec4 *dst);
......
...@@ -983,21 +983,34 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface, ...@@ -983,21 +983,34 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
&& destsize.x == srcsize.x && destsize.x == srcsize.x
&& destsize.y == srcsize.y) /* Simple copy. */ && 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; const BYTE *src_addr;
BYTE *dst_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))) if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
return D3DXERR_INVALIDDATA; return D3DXERR_INVALIDDATA;
src_addr = pSrcMemory; src_addr = pSrcMemory;
src_addr += pSrcRect->top * SrcPitch; src_addr += (pSrcRect->top / srcformatdesc->block_height) * SrcPitch;
src_addr += pSrcRect->left * srcformatdesc->bytes_per_pixel; src_addr += (pSrcRect->left / srcformatdesc->block_width) * srcformatdesc->block_byte_count;
dst_addr = lockrect.pBits; 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; src_addr += SrcPitch;
dst_addr += lockrect.Pitch; dst_addr += lockrect.Pitch;
} }
...@@ -1010,6 +1023,10 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface, ...@@ -1010,6 +1023,10 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
return E_NOTIMPL; return E_NOTIMPL;
if (destformatdesc->bytes_per_pixel > 4) if (destformatdesc->bytes_per_pixel > 4)
return E_NOTIMPL; 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))) if (FAILED(hr = IDirect3DSurface9_LockRect(pDestSurface, &lockrect, pDestRect, 0)))
return D3DXERR_INVALIDDATA; return D3DXERR_INVALIDDATA;
......
...@@ -44,26 +44,31 @@ static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba) ...@@ -44,26 +44,31 @@ static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
*/ */
static const PixelFormatDesc formats[] = static const PixelFormatDesc formats[] =
{ {
/* format bpc shifts bpp type from_rgba to_rgba */ /* format bpc shifts bpp blocks type from_rgba to_rgba */
{D3DFMT_R8G8B8, {0, 8, 8, 8}, { 0, 16, 8, 0}, 3, FORMAT_ARGB, NULL, NULL }, {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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, FORMAT_ARGB, la_from_rgba, la_to_rgba}, {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 */ /* 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 },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment