d3dx9: Implement D3DXCreateVolumeTextureFromFileInMemoryEx.

This commit is contained in:
Józef Kucia 2012-06-29 14:17:01 +02:00 committed by Alexandre Julliard
parent 9e262e1a9b
commit 07b0f25404
4 changed files with 225 additions and 46 deletions

View File

@ -68,6 +68,8 @@ HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data,
DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) 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;
HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
/* debug helpers */
const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;

View File

@ -499,6 +499,58 @@ HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const vo
return D3D_OK;
}
HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info)
{
HRESULT hr;
UINT mip_level;
UINT mip_levels;
UINT src_slice_pitch;
UINT src_row_pitch;
D3DBOX src_box;
UINT width, height, depth;
IDirect3DVolume9 *volume;
const struct dds_header *header = src_data;
const BYTE *pixels = (BYTE *)(header + 1);
if (src_info->ResourceType != D3DRTYPE_VOLUMETEXTURE)
return D3DXERR_INVALIDDATA;
width = src_info->Width;
height = src_info->Height;
depth = src_info->Depth;
mip_levels = min(src_info->MipLevels, IDirect3DVolumeTexture9_GetLevelCount(volume_texture));
for (mip_level = 0; mip_level < mip_levels; mip_level++)
{
hr = calculate_dds_surface_size(src_info, width, height, &src_row_pitch, &src_slice_pitch);
if (FAILED(hr)) return hr;
hr = IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, mip_level, &volume);
if (FAILED(hr)) return hr;
src_box.Left = 0;
src_box.Top = 0;
src_box.Right = width;
src_box.Bottom = height;
src_box.Front = 0;
src_box.Back = depth;
hr = D3DXLoadVolumeFromMemory(volume, palette, NULL, pixels, src_info->Format,
src_row_pitch, src_slice_pitch, NULL, &src_box, filter, color_key);
IDirect3DVolume9_Release(volume);
if (FAILED(hr)) return hr;
pixels += depth * src_slice_pitch;
width = max(1, width / 2);
height = max(1, height / 2);
depth = max(1, depth / 2);
}
return D3D_OK;
}
/************************************************************
* D3DXGetImageInfoFromFileInMemory
*

View File

@ -1359,40 +1359,39 @@ static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *devic
IDirect3DVolumeTexture9 *volume_texture;
D3DVOLUME_DESC volume_desc;
todo_wine {
hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
if (SUCCEEDED(hr))
{
levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
if (SUCCEEDED(hr))
{
levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
ok(hr == D3D_OK, "GetLevelDesc returend %#x, expected %#x\n", hr, D3D_OK);
ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
ok(hr == D3D_OK, "GetLevelDesc returend %#x, expected %#x\n", hr, D3D_OK);
ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
ref = IDirect3DVolumeTexture9_Release(volume_texture);
ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
}
ref = IDirect3DVolumeTexture9_Release(volume_texture);
ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
}
}

View File

@ -977,40 +977,166 @@ HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
usage, format, pool, texture, NULL);
}
HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(LPDIRECT3DDEVICE9 device,
LPCVOID data,
UINT datasize,
LPDIRECT3DVOLUMETEXTURE9 *texture)
HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device,
const void *data,
UINT data_size,
IDirect3DVolumeTexture9 **volume_texture)
{
TRACE("(%p, %p, %u, %p)\n", device, data, datasize, texture);
TRACE("(%p, %p, %u, %p): relay\n", device, data, data_size, volume_texture);
return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, datasize, D3DX_DEFAULT, D3DX_DEFAULT,
return D3DXCreateVolumeTextureFromFileInMemoryEx(device, data, data_size, D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, texture);
0, NULL, NULL, volume_texture);
}
HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(LPDIRECT3DDEVICE9 device,
LPCVOID data,
UINT datasize,
HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device,
const void *data,
UINT data_size,
UINT width,
UINT height,
UINT depth,
UINT miplevels,
UINT mip_levels,
DWORD usage,
D3DFORMAT format,
D3DPOOL pool,
DWORD filter,
DWORD mipfilter,
D3DCOLOR colorkey,
D3DXIMAGE_INFO *imageinfo,
DWORD mip_filter,
D3DCOLOR color_key,
D3DXIMAGE_INFO *info,
PALETTEENTRY *palette,
LPDIRECT3DVOLUMETEXTURE9 *texture)
IDirect3DVolumeTexture9 **volume_texture)
{
FIXME("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p) : stub\n",
device, data, datasize, width, height, depth, miplevels, usage, format, pool,
filter, mipfilter, colorkey, imageinfo, palette, texture);
HRESULT hr;
D3DCAPS9 caps;
D3DXIMAGE_INFO image_info;
BOOL dynamic_texture;
BOOL file_width = FALSE;
BOOL file_height = FALSE;
BOOL file_depth = FALSE;
BOOL file_format = FALSE;
BOOL file_mip_levels = FALSE;
IDirect3DVolumeTexture9 *tex, *buftex;
return E_NOTIMPL;
TRACE("(%p, %p, %u, %u, %u, %u, %u, %#x, %#x, %#x, %#x, %#x, %#x, %p, %p, %p)\n",
device, data, data_size, width, height, depth, mip_levels, usage, format, pool,
filter, mip_filter, color_key, info, palette, volume_texture);
if (!device || !data || !data_size || !volume_texture)
return D3DERR_INVALIDCALL;
hr = D3DXGetImageInfoFromFileInMemory(data, data_size, &image_info);
if (FAILED(hr)) return hr;
if (image_info.ImageFileFormat != D3DXIFF_DDS)
return D3DXERR_INVALIDDATA;
if (width == 0 || width == D3DX_DEFAULT_NONPOW2)
width = image_info.Width;
if (width == D3DX_DEFAULT)
width = make_pow2(image_info.Width);
if (height == 0 || height == D3DX_DEFAULT_NONPOW2)
height = image_info.Height;
if (height == D3DX_DEFAULT)
height = make_pow2(image_info.Height);
if (depth == 0 || depth == D3DX_DEFAULT_NONPOW2)
depth = image_info.Depth;
if (depth == D3DX_DEFAULT)
depth = make_pow2(image_info.Depth);
if (format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT)
format = image_info.Format;
if (width == D3DX_FROM_FILE)
{
file_width = TRUE;
width = image_info.Width;
}
if (height == D3DX_FROM_FILE)
{
file_height = TRUE;
height = image_info.Height;
}
if (depth == D3DX_FROM_FILE)
{
file_depth = TRUE;
depth = image_info.Depth;
}
if (format == D3DFMT_FROM_FILE)
{
file_format = TRUE;
format = image_info.Format;
}
if (mip_levels == D3DX_FROM_FILE)
{
file_mip_levels = TRUE;
mip_levels = image_info.MipLevels;
}
hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mip_levels, usage, &format, pool);
if (FAILED(hr)) return hr;
if ((file_width && width != image_info.Width)
|| (file_height && height != image_info.Height)
|| (file_depth && depth != image_info.Depth)
|| (file_format && format != image_info.Format)
|| (file_mip_levels && mip_levels != image_info.MipLevels))
return D3DERR_NOTAVAILABLE;
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
if (FAILED(hr))
return D3DERR_INVALIDCALL;
if (mip_levels > image_info.MipLevels)
{
FIXME("Generation of mipmaps for volume textures is not implemented yet\n");
mip_levels = image_info.MipLevels;
}
dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC);
if (pool == D3DPOOL_DEFAULT && !dynamic_texture)
{
hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, D3DPOOL_SYSTEMMEM, &buftex);
tex = buftex;
}
else
{
hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
buftex = NULL;
}
if (FAILED(hr)) return hr;
hr = load_volume_texture_from_dds(tex, data, palette, filter, color_key, &image_info);
if (FAILED(hr))
{
IDirect3DVolumeTexture9_Release(tex);
return hr;
}
if (buftex)
{
hr = D3DXCreateVolumeTexture(device, width, height, depth, mip_levels, usage, format, pool, &tex);
if (FAILED(hr))
{
IDirect3DVolumeTexture9_Release(buftex);
return hr;
}
IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex);
IDirect3DVolumeTexture9_Release(buftex);
}
if (info)
*info = image_info;
*volume_texture = tex;
return D3D_OK;
}
HRESULT WINAPI D3DXFillTexture(LPDIRECT3DTEXTURE9 texture,