mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:31:39 +00:00
d3dx9: Add support for specifying which mip level to get pixel data from to d3dx_image_get_pixels().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
be746bee64
commit
1215ee0241
|
@ -123,7 +123,7 @@ struct d3dx_image
|
|||
HRESULT d3dx_image_init(const void *src_data, uint32_t src_data_size, struct d3dx_image *image,
|
||||
uint32_t starting_mip_level, uint32_t flags);
|
||||
void d3dx_image_cleanup(struct d3dx_image *image);
|
||||
HRESULT d3dx_image_get_pixels(struct d3dx_image *image, struct d3dx_pixels *pixels);
|
||||
HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, struct d3dx_pixels *pixels);
|
||||
void d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image);
|
||||
|
||||
struct d3dx_include_from_file
|
||||
|
@ -172,8 +172,6 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
|
|||
BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
|
||||
const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette);
|
||||
|
||||
HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key,
|
||||
const struct d3dx_image *image, unsigned int *loaded_miplevels);
|
||||
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);
|
||||
HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
|
||||
|
|
|
@ -584,42 +584,6 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *d
|
|||
row_pitch, slice_pitch, NULL, src_box, filter, color_key);
|
||||
}
|
||||
|
||||
HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key,
|
||||
const struct d3dx_image *image, unsigned int *loaded_miplevels)
|
||||
{
|
||||
HRESULT hr;
|
||||
RECT src_rect;
|
||||
UINT src_pitch;
|
||||
UINT mip_level;
|
||||
UINT mip_levels;
|
||||
UINT mip_level_size;
|
||||
IDirect3DSurface9 *surface;
|
||||
const BYTE *pixels = image->pixels;
|
||||
struct volume mip_size = image->size;
|
||||
|
||||
mip_levels = min(image->mip_levels, IDirect3DTexture9_GetLevelCount(texture));
|
||||
for (mip_level = 0; mip_level < mip_levels; ++mip_level)
|
||||
{
|
||||
hr = d3dx_calculate_pixels_size(image->format, mip_size.width, mip_size.height, &src_pitch, &mip_level_size);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
SetRect(&src_rect, 0, 0, mip_size.width, mip_size.height);
|
||||
IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface);
|
||||
hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels, image->format, src_pitch,
|
||||
NULL, &src_rect, filter, color_key);
|
||||
IDirect3DSurface9_Release(surface);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
pixels += mip_level_size * mip_size.depth;
|
||||
d3dx_get_next_mip_level_size(&mip_size);
|
||||
}
|
||||
|
||||
*loaded_miplevels = mip_levels;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1163,19 +1127,37 @@ void d3dx_image_cleanup(struct d3dx_image *image)
|
|||
free(image->palette);
|
||||
}
|
||||
|
||||
HRESULT d3dx_image_get_pixels(struct d3dx_image *image, struct d3dx_pixels *pixels)
|
||||
HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, struct d3dx_pixels *pixels)
|
||||
{
|
||||
uint32_t row_pitch, slice_pitch;
|
||||
struct volume mip_level_size = image->size;
|
||||
const BYTE *pixels_ptr = image->pixels;
|
||||
uint32_t row_pitch, slice_pitch, i;
|
||||
RECT unaligned_rect;
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = d3dx_calculate_pixels_size(image->format, image->size.width, image->size.height, &row_pitch, &slice_pitch);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
if (mip_level >= image->mip_levels)
|
||||
{
|
||||
ERR("Tried to retrieve mip level %u, but image only has %u mip levels.\n", mip_level, image->mip_levels);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
SetRect(&unaligned_rect, 0, 0, image->size.width, image->size.height);
|
||||
set_d3dx_pixels(pixels, image->pixels, row_pitch, slice_pitch, image->palette, image->size.width, image->size.height,
|
||||
image->size.depth, &unaligned_rect);
|
||||
slice_pitch = row_pitch = 0;
|
||||
for (i = 0; i < image->mip_levels; i++)
|
||||
{
|
||||
hr = d3dx_calculate_pixels_size(image->format, mip_level_size.width, mip_level_size.height, &row_pitch, &slice_pitch);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (i == mip_level)
|
||||
break;
|
||||
|
||||
pixels_ptr += slice_pitch * mip_level_size.depth;
|
||||
d3dx_get_next_mip_level_size(&mip_level_size);
|
||||
}
|
||||
|
||||
SetRect(&unaligned_rect, 0, 0, mip_level_size.width, mip_level_size.height);
|
||||
set_d3dx_pixels(pixels, pixels_ptr, row_pitch, slice_pitch, image->palette, mip_level_size.width,
|
||||
mip_level_size.height, mip_level_size.depth, &unaligned_rect);
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
@ -1384,7 +1366,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface,
|
|||
else
|
||||
SetRect(&src_rect, 0, 0, img_info.Width, img_info.Height);
|
||||
|
||||
hr = d3dx_image_get_pixels(&image, &pixels);
|
||||
hr = d3dx_image_get_pixels(&image, 0, &pixels);
|
||||
if (FAILED(hr))
|
||||
goto exit;
|
||||
|
||||
|
|
|
@ -2158,7 +2158,7 @@ static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
|
|||
type = IDirect3DTexture9_GetType(texture);
|
||||
ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
|
||||
level_count = IDirect3DBaseTexture9_GetLevelCount((IDirect3DBaseTexture9 *)texture);
|
||||
todo_wine ok(level_count == 3, "Texture has %lu mip levels, 3 expected.\n", level_count);
|
||||
ok(level_count == 3, "Texture has %lu mip levels, 3 expected.\n", level_count);
|
||||
hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
|
||||
ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#lx, expected %#lx.\n", hr, D3D_OK);
|
||||
ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
|
||||
|
@ -2192,19 +2192,18 @@ static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
|
|||
*/
|
||||
hr = D3DXCreateTextureFromFileInMemory(device, dds_volume_dxt3_4_4_4, sizeof(dds_volume_dxt3_4_4_4), &texture);
|
||||
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
|
||||
check_texture_mip_levels(texture, 3, TRUE);
|
||||
check_texture_mip_levels(texture, 3, FALSE);
|
||||
if (has_2d_dxt3)
|
||||
{
|
||||
struct surface_readback surface_rb;
|
||||
uint32_t mip_level;
|
||||
|
||||
check_texture_level_desc(texture, 0, D3DFMT_DXT3, 0, D3DPOOL_MANAGED, 0, 0, 4, 4, FALSE);
|
||||
check_texture_level_desc(texture, 1, D3DFMT_DXT3, 0, D3DPOOL_MANAGED, 0, 0, 2, 2, TRUE);
|
||||
check_texture_level_desc(texture, 2, D3DFMT_DXT3, 0, D3DPOOL_MANAGED, 0, 0, 1, 1, TRUE);
|
||||
check_texture_level_desc(texture, 1, D3DFMT_DXT3, 0, D3DPOOL_MANAGED, 0, 0, 2, 2, FALSE);
|
||||
check_texture_level_desc(texture, 2, D3DFMT_DXT3, 0, D3DPOOL_MANAGED, 0, 0, 1, 1, FALSE);
|
||||
for (mip_level = 0; mip_level < ARRAY_SIZE(dds_volume_dxt3_4_4_4_expected_uncompressed); ++mip_level)
|
||||
{
|
||||
const uint32_t expected_color = dds_volume_dxt3_4_4_4_expected_uncompressed[mip_level];
|
||||
BOOL todo = !!mip_level;
|
||||
uint32_t x, y;
|
||||
|
||||
IDirect3DTexture9_GetLevelDesc(texture, mip_level, &desc);
|
||||
|
@ -2213,7 +2212,7 @@ static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
|
|||
{
|
||||
for (x = 0; x < desc.Width; ++x)
|
||||
{
|
||||
check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, todo);
|
||||
check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE);
|
||||
}
|
||||
}
|
||||
release_surface_readback(&surface_rb);
|
||||
|
@ -2487,16 +2486,15 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
|
|||
D3DX_DEFAULT, D3DX_DEFAULT, 0, &img_info, NULL, &texture);
|
||||
ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
check_texture_mip_levels(texture, 3, TRUE);
|
||||
check_texture_mip_levels(texture, 3, FALSE);
|
||||
check_image_info(&img_info, 4, 4, 4, 3, D3DFMT_DXT3, D3DRTYPE_VOLUMETEXTURE, D3DXIFF_DDS, FALSE);
|
||||
check_texture_level_desc(texture, 0, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, 4, FALSE);
|
||||
check_texture_level_desc(texture, 1, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, 2, TRUE);
|
||||
check_texture_level_desc(texture, 2, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 1, 1, TRUE);
|
||||
check_texture_level_desc(texture, 1, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, 2, FALSE);
|
||||
check_texture_level_desc(texture, 2, D3DFMT_DXT3, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 1, 1, FALSE);
|
||||
|
||||
for (mip_level = 0; mip_level < ARRAY_SIZE(dds_volume_dxt3_4_4_4_expected_uncompressed); ++mip_level)
|
||||
{
|
||||
const uint32_t expected_color = dds_volume_dxt3_4_4_4_expected_uncompressed[mip_level];
|
||||
BOOL todo = !!mip_level;
|
||||
uint32_t x, y;
|
||||
|
||||
IDirect3DTexture9_GetLevelDesc(texture, mip_level, &desc);
|
||||
|
@ -2505,7 +2503,7 @@ static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
|
|||
{
|
||||
for (x = 0; x < desc.Width; ++x)
|
||||
{
|
||||
check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, todo);
|
||||
check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE);
|
||||
}
|
||||
}
|
||||
release_surface_readback(&surface_rb);
|
||||
|
|
|
@ -567,10 +567,10 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
|
|||
D3DPOOL pool, DWORD filter, DWORD mipfilter, D3DCOLOR colorkey, D3DXIMAGE_INFO *srcinfo,
|
||||
PALETTEENTRY *palette, struct IDirect3DTexture9 **texture)
|
||||
{
|
||||
const struct pixel_format_desc *src_fmt_desc, *dst_fmt_desc;
|
||||
BOOL dynamic_texture, format_specified = FALSE;
|
||||
unsigned int loaded_miplevels, skip_levels;
|
||||
uint32_t loaded_miplevels, skip_levels, i;
|
||||
IDirect3DTexture9 *staging_tex, *tex;
|
||||
IDirect3DSurface9 *surface;
|
||||
struct d3dx_image image;
|
||||
D3DXIMAGE_INFO imginfo;
|
||||
D3DCAPS9 caps;
|
||||
|
@ -619,13 +619,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
|
|||
if (colorkey && !format_specified)
|
||||
format = get_alpha_replacement_format(format);
|
||||
|
||||
if (imginfo.ResourceType == D3DRTYPE_VOLUMETEXTURE
|
||||
&& D3DFMT_DXT1 <= imginfo.Format && imginfo.Format <= D3DFMT_DXT5 && miplevels > 1)
|
||||
{
|
||||
FIXME("Generation of mipmaps for compressed volume textures is not implemented yet.\n");
|
||||
miplevels = 1;
|
||||
}
|
||||
|
||||
if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
|
||||
{
|
||||
hr = D3DERR_INVALIDCALL;
|
||||
|
@ -652,24 +645,33 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
|
|||
}
|
||||
|
||||
TRACE("Texture created correctly. Now loading the texture data into it.\n");
|
||||
if (imginfo.ImageFileFormat != D3DXIFF_DDS)
|
||||
dst_fmt_desc = get_format_info(format);
|
||||
src_fmt_desc = get_format_info(imginfo.Format);
|
||||
loaded_miplevels = min(imginfo.MipLevels, IDirect3DTexture9_GetLevelCount(tex));
|
||||
for (i = 0; i < loaded_miplevels; i++)
|
||||
{
|
||||
const RECT src_rect = { 0, 0, imginfo.Width, imginfo.Height };
|
||||
struct d3dx_pixels pixels;
|
||||
struct d3dx_pixels src_pixels, dst_pixels;
|
||||
D3DSURFACE_DESC dst_surface_desc;
|
||||
D3DLOCKED_RECT dst_locked_rect;
|
||||
RECT dst_rect;
|
||||
|
||||
hr = d3dx_image_get_pixels(&image, &pixels);
|
||||
hr = d3dx_image_get_pixels(&image, i, &src_pixels);
|
||||
if (FAILED(hr))
|
||||
goto err;
|
||||
break;
|
||||
|
||||
IDirect3DTexture9_GetSurfaceLevel(tex, 0, &surface);
|
||||
hr = D3DXLoadSurfaceFromMemory(surface, palette, NULL, pixels.data, imginfo.Format,
|
||||
pixels.row_pitch, pixels.palette, &src_rect, filter, colorkey);
|
||||
IDirect3DSurface9_Release(surface);
|
||||
loaded_miplevels = min(IDirect3DTexture9_GetLevelCount(tex), imginfo.MipLevels);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = load_texture_from_dds(tex, palette, filter, colorkey, &image, &loaded_miplevels);
|
||||
hr = IDirect3DTexture9_LockRect(tex, i, &dst_locked_rect, NULL, 0);
|
||||
if (FAILED(hr))
|
||||
break;
|
||||
|
||||
IDirect3DTexture9_GetLevelDesc(tex, i, &dst_surface_desc);
|
||||
SetRect(&dst_rect, 0, 0, dst_surface_desc.Width, dst_surface_desc.Height);
|
||||
set_d3dx_pixels(&dst_pixels, dst_locked_rect.pBits, dst_locked_rect.Pitch, 0, palette,
|
||||
dst_surface_desc.Width, dst_surface_desc.Height, 1, &dst_rect);
|
||||
|
||||
hr = d3dx_load_pixels_from_pixels(&dst_pixels, dst_fmt_desc, &src_pixels, src_fmt_desc, filter, colorkey);
|
||||
IDirect3DTexture9_UnlockRect(tex, i);
|
||||
if (FAILED(hr))
|
||||
break;
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
|
Loading…
Reference in a new issue