Commit 69b94181 authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

d3dx9: Implement D3DXCreateCubeTextureFromFileInMemoryEx.

parent f53ce181
...@@ -62,6 +62,9 @@ HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer, ...@@ -62,6 +62,9 @@ HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer,
const PixelFormatDesc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN; const PixelFormatDesc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
const PixelFormatDesc *get_format_info_idx(int idx) DECLSPEC_HIDDEN; const PixelFormatDesc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
/* debug helpers */ /* debug helpers */
const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN; const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;
const char *debug_d3dxparameter_type(D3DXPARAMETER_TYPE t) DECLSPEC_HIDDEN; const char *debug_d3dxparameter_type(D3DXPARAMETER_TYPE t) DECLSPEC_HIDDEN;
......
...@@ -95,6 +95,9 @@ static const GUID *d3dformat_to_wic_guid(D3DFORMAT format) ...@@ -95,6 +95,9 @@ static const GUID *d3dformat_to_wic_guid(D3DFORMAT format)
#define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x2000 #define DDS_CAPS2_CUBEMAP_NEGATIVEY 0x2000
#define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x4000 #define DDS_CAPS2_CUBEMAP_POSITIVEZ 0x4000
#define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x8000 #define DDS_CAPS2_CUBEMAP_NEGATIVEZ 0x8000
#define DDS_CAPS2_CUBEMAP_ALL_FACES ( DDS_CAPS2_CUBEMAP_POSITIVEX | DDS_CAPS2_CUBEMAP_NEGATIVEX \
| DDS_CAPS2_CUBEMAP_POSITIVEY | DDS_CAPS2_CUBEMAP_NEGATIVEY \
| DDS_CAPS2_CUBEMAP_POSITIVEZ | DDS_CAPS2_CUBEMAP_NEGATIVEZ )
#define DDS_CAPS2_VOLUME 0x200000 #define DDS_CAPS2_VOLUME 0x200000
/* dds_pixel_format.flags */ /* dds_pixel_format.flags */
...@@ -374,6 +377,59 @@ static HRESULT get_image_info_from_dds(const void *buffer, UINT length, D3DXIMAG ...@@ -374,6 +377,59 @@ static HRESULT get_image_info_from_dds(const void *buffer, UINT length, D3DXIMAG
return D3D_OK; return D3D_OK;
} }
HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
{
HRESULT hr;
int face;
int mip_level;
UINT size;
RECT src_rect;
UINT src_pitch;
UINT mip_levels;
UINT mip_level_size;
IDirect3DSurface9 *surface;
const struct dds_header *header = src_data;
const BYTE *pixels = (BYTE *)(header + 1);
if (src_info->ResourceType != D3DRTYPE_CUBETEXTURE)
return D3DXERR_INVALIDDATA;
if ((header->caps2 & DDS_CAPS2_CUBEMAP_ALL_FACES) != DDS_CAPS2_CUBEMAP_ALL_FACES)
{
WARN("Only full cubemaps are supported\n");
return D3DXERR_INVALIDDATA;
}
mip_levels = min(src_info->MipLevels, IDirect3DCubeTexture9_GetLevelCount(cube_texture));
for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; face++)
{
size = src_info->Width;
for (mip_level = 0; mip_level < src_info->MipLevels; mip_level++)
{
hr = calculate_dds_surface_size(src_info, size, size, &src_pitch, &mip_level_size);
if (FAILED(hr)) return hr;
/* if texture has fewer mip levels than DDS file, skip excessive mip levels */
if (mip_level < mip_levels)
{
SetRect(&src_rect, 0, 0, size, size);
IDirect3DCubeTexture9_GetCubeMapSurface(cube_texture, face, mip_level, &surface);
hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, src_info->Format, src_pitch,
NULL, &src_rect, filter, color_key);
IDirect3DSurface9_Release(surface);
if (FAILED(hr)) return hr;
}
pixels += mip_level_size;
size = max(1, size / 2);
}
}
return D3D_OK;
}
/************************************************************ /************************************************************
* D3DXGetImageInfoFromFileInMemory * D3DXGetImageInfoFromFileInMemory
* *
......
...@@ -1114,37 +1114,35 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device) ...@@ -1114,37 +1114,35 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
IDirect3DCubeTexture9 *cube_texture; IDirect3DCubeTexture9 *cube_texture;
D3DSURFACE_DESC surface_desc; D3DSURFACE_DESC surface_desc;
todo_wine { hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture); hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture); hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL); hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture); hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture); levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount); todo_wine ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc); hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK); ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width); ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height); ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 3, &surface_desc); hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 3, &surface_desc);
ok(hr == D3DERR_INVALIDCALL, "GetLevelDesc returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); todo_wine ok(hr == D3DERR_INVALIDCALL, "GetLevelDesc returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
ref = IDirect3DCubeTexture9_Release(cube_texture); ref = IDirect3DCubeTexture9_Release(cube_texture);
ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref); ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
} else skip("Couldn't create cube texture\n"); } else skip("Couldn't create cube texture\n");
}
} }
static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device) static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
......
...@@ -1078,16 +1078,141 @@ HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture, ...@@ -1078,16 +1078,141 @@ HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,
return D3D_OK; return D3D_OK;
} }
HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 pDevice, LPCVOID pSrcData, UINT SrcDataSize, HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
UINT Size, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, const void *src_data,
D3DXIMAGE_INFO *pSrcInfo, PALETTEENTRY *pPalette, LPDIRECT3DCUBETEXTURE9 *ppCubeTexture) UINT src_data_size,
UINT size,
UINT mip_levels,
DWORD usage,
D3DFORMAT format,
D3DPOOL pool,
DWORD filter,
DWORD mip_filter,
D3DCOLOR color_key,
D3DXIMAGE_INFO *src_info,
PALETTEENTRY *palette,
IDirect3DCubeTexture9 **cube_texture)
{ {
FIXME("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p): stub\n", pDevice, pSrcData, SrcDataSize, Size, MipLevels, HRESULT hr;
Usage, Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture); D3DCAPS9 caps;
UINT loaded_miplevels;
D3DXIMAGE_INFO img_info;
BOOL file_size = FALSE;
BOOL file_format = FALSE;
BOOL file_mip_levels = FALSE;
IDirect3DCubeTexture9 *tex, *buftex;
TRACE("(%p, %p, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n", device,
src_data, src_data_size, size, mip_levels, usage, format, pool, filter, mip_filter,
color_key, src_info, palette, cube_texture);
if (!device || !cube_texture || !src_data || !src_data_size)
return D3DERR_INVALIDCALL;
return E_NOTIMPL; hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info);
if (FAILED(hr))
return hr;
if (img_info.ImageFileFormat != D3DXIFF_DDS)
return D3DXERR_INVALIDDATA;
if (img_info.Width != img_info.Height)
return D3DXERR_INVALIDDATA;
if (size == 0 || size == D3DX_DEFAULT_NONPOW2)
size = img_info.Width;
if (size == D3DX_DEFAULT)
size = make_pow2(img_info.Width);
if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
format = img_info.Format;
if (size == D3DX_FROM_FILE)
{
file_size = TRUE;
size = img_info.Width;
}
if (format == D3DFMT_FROM_FILE)
{
file_format = TRUE;
format = img_info.Format;
}
if (mip_levels == D3DX_FROM_FILE)
{
file_mip_levels = TRUE;
mip_levels = img_info.MipLevels;
}
hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool);
if (FAILED(hr))
return hr;
if ((file_size && size != img_info.Width)
|| (file_format && format != img_info.Format)
|| (file_mip_levels && mip_levels != img_info.MipLevels))
return D3DERR_NOTAVAILABLE;
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
if (FAILED(hr))
return D3DERR_INVALIDCALL;
if (mip_levels > img_info.MipLevels && (D3DFMT_DXT1 <= img_info.Format && img_info.Format <= D3DFMT_DXT5))
{
FIXME("Generation of mipmaps for compressed pixel formats not supported yet\n");
mip_levels = img_info.MipLevels;
}
if (pool == D3DPOOL_DEFAULT && !((caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && usage == D3DUSAGE_DYNAMIC))
{
hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
tex = buftex;
}
else
{
hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
buftex = NULL;
}
if (FAILED(hr))
return hr;
hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info);
if (FAILED(hr))
{
IDirect3DCubeTexture9_Release(tex);
return hr;
}
loaded_miplevels = min(mip_levels, img_info.MipLevels);
hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter);
if (FAILED(hr))
{
IDirect3DCubeTexture9_Release(tex);
return hr;
}
if (buftex)
{
hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex);
if (FAILED(hr))
{
IDirect3DCubeTexture9_Release(buftex);
return hr;
}
IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
IDirect3DCubeTexture9_Release(buftex);
}
if (src_info)
*src_info = img_info;
*cube_texture = tex;
return D3D_OK;
} }
HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device, HRESULT WINAPI D3DXCreateCubeTextureFromFileA(IDirect3DDevice9 *device,
const char *src_filename, const char *src_filename,
IDirect3DCubeTexture9 **cube_texture) IDirect3DCubeTexture9 **cube_texture)
......
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