Alexandre Julliard pushed to branch master at wine / wine
Commits: 2b042ca3 by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9/tests: Make some test structures static const.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - 093b2c96 by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9/tests: Reorder test structure members.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - d714f1b2 by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9/tests: Add more D3DXCreateCubeTextureFromFileInMemory{Ex}() tests.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - ecb2f3ce by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9: Refactor texture creation and cleanup in D3DXCreateCubeTextureFromFileInMemoryEx().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - 15e9113c by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9: Cleanup texture value argument handling in D3DXCreateCubeTextureFromFileInMemoryEx().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - 416f11ea by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9: Use d3dx_image structure inside of D3DXCreateCubeTextureFromFileInMemoryEx().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - f023fd35 by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9: Add support for specifying which array layer to get pixel data from to d3dx_image_get_pixels().
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - - 0c1c8c29 by Connor McAdams at 2024-07-24T20:15:44+02:00 d3dx9: Add support for loading non-square cubemap DDS files into cube textures.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
- - - - -
7 changed files:
- dlls/d3dx9_36/d3dx9_private.h - dlls/d3dx9_36/surface.c - dlls/d3dx9_36/tests/d3dx9_test_images.h - dlls/d3dx9_36/tests/surface.c - dlls/d3dx9_36/tests/texture.c - dlls/d3dx9_36/texture.c - dlls/d3dx9_36/volume.c
Changes:
===================================== dlls/d3dx9_36/d3dx9_private.h ===================================== @@ -106,8 +106,10 @@ struct d3dx_image
struct volume size; uint32_t mip_levels; + uint32_t layer_count;
BYTE *pixels; + uint32_t layer_pitch;
/* * image_buf and palette are pointers to allocated memory used to store @@ -123,7 +125,8 @@ 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, uint32_t mip_level, struct d3dx_pixels *pixels); +HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, 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 +175,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_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 lock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect, D3DLOCKED_RECT *lock, IDirect3DSurface9 **temp_surface, BOOL write); HRESULT unlock_surface(IDirect3DSurface9 *surface, const RECT *surface_rect,
===================================== dlls/d3dx9_36/surface.c ===================================== @@ -475,6 +475,23 @@ static HRESULT d3dx_calculate_pixels_size(D3DFORMAT format, uint32_t width, uint return D3D_OK; }
+static uint32_t d3dx_calculate_layer_pixels_size(D3DFORMAT format, uint32_t width, uint32_t height, uint32_t depth, + uint32_t mip_levels) +{ + uint32_t layer_size, row_pitch, slice_pitch, i; + struct volume dims = { width, height, depth }; + + layer_size = 0; + for (i = 0; i < mip_levels; ++i) + { + d3dx_calculate_pixels_size(format, dims.width, dims.height, &row_pitch, &slice_pitch); + layer_size += slice_pitch * dims.depth; + d3dx_get_next_mip_level_size(&dims); + } + + return layer_size; +} + static UINT calculate_dds_file_size(D3DFORMAT format, UINT width, UINT height, UINT depth, UINT miplevels, UINT faces) { @@ -566,65 +583,11 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur 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; - UINT 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 = d3dx_calculate_pixels_size(src_info->Format, 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; -} - static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src_data_size, struct d3dx_image *image, uint32_t starting_mip_level) { const struct dds_header *header = src_data; uint32_t expected_src_data_size; - uint32_t faces = 1;
if (src_data_size < sizeof(*header) || header->pixel_format.size != sizeof(header->pixel_format)) return D3DXERR_INVALIDDATA; @@ -633,6 +596,7 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src set_volume_struct(&image->size, header->width, header->height, 1); image->mip_levels = header->miplevels ? header->miplevels : 1; image->format = dds_pixel_format_to_d3dformat(&header->pixel_format); + image->layer_count = 1;
if (image->format == D3DFMT_UNKNOWN) return D3DXERR_INVALIDDATA; @@ -651,14 +615,15 @@ static HRESULT d3dx_initialize_image_from_dds(const void *src_data, uint32_t src return D3DXERR_INVALIDDATA; }
- faces = 6; + image->layer_count = 6; image->resource_type = D3DRTYPE_CUBETEXTURE; } else image->resource_type = D3DRTYPE_TEXTURE;
- expected_src_data_size = calculate_dds_file_size(image->format, image->size.width, image->size.height, - image->size.depth, image->mip_levels, faces); + image->layer_pitch = d3dx_calculate_layer_pixels_size(image->format, image->size.width, image->size.height, + image->size.depth, image->mip_levels); + expected_src_data_size = (image->layer_pitch * image->layer_count) + sizeof(*header); if (src_data_size < expected_src_data_size) { WARN("File is too short %u, expected at least %u bytes.\n", src_data_size, expected_src_data_size); @@ -1020,6 +985,7 @@ static HRESULT d3dx_initialize_image_from_wic(const void *src_data, uint32_t src
image->size.depth = 1; image->mip_levels = 1; + image->layer_count = 1; image->resource_type = D3DRTYPE_TEXTURE;
exit: @@ -1055,7 +1021,8 @@ void d3dx_image_cleanup(struct d3dx_image *image) free(image->palette); }
-HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, struct d3dx_pixels *pixels) +HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t layer, uint32_t mip_level, + struct d3dx_pixels *pixels) { struct volume mip_level_size = image->size; const BYTE *pixels_ptr = image->pixels; @@ -1069,6 +1036,12 @@ HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, stru return E_FAIL; }
+ if (layer >= image->layer_count) + { + ERR("Tried to retrieve layer %u, but image only has %u layers.\n", layer, image->layer_count); + return E_FAIL; + } + slice_pitch = row_pitch = 0; for (i = 0; i < image->mip_levels; i++) { @@ -1083,6 +1056,7 @@ HRESULT d3dx_image_get_pixels(struct d3dx_image *image, uint32_t mip_level, stru d3dx_get_next_mip_level_size(&mip_level_size); }
+ pixels_ptr += (layer * image->layer_pitch); 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); @@ -1294,7 +1268,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9 *pDestSurface, else SetRect(&src_rect, 0, 0, img_info.Width, img_info.Height);
- hr = d3dx_image_get_pixels(&image, 0, &pixels); + hr = d3dx_image_get_pixels(&image, 0, 0, &pixels); if (FAILED(hr)) goto exit;
===================================== dlls/d3dx9_36/tests/d3dx9_test_images.h ===================================== @@ -254,6 +254,99 @@ static const uint8_t dds_cube_map[] = 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55 };
+/* 4x2 cube map DDS file. */ +static const uint8_t dds_cube_map_4_2[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x00,0x00,0x02,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +/* 2x4 cube map DDS file. */ +static const uint8_t dds_cube_map_2_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x00,0x00,0x04,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +/* 4x4 cube map DDS file with 2 mips. */ +static const uint8_t dds_cube_map_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x0f,0x10,0x02,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00, + 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00, + 0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00, + 0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00, + 0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00, + 0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x00, +}; + /* 4x4x2 volume map dds, 2 mipmaps */ static const uint8_t dds_volume_map[] = {
===================================== dlls/d3dx9_36/tests/surface.c ===================================== @@ -251,7 +251,7 @@ static void test_dds_header_handling(void) BYTE data[4096 * 1024]; } *dds;
- struct + static const struct { struct dds_pixel_format pixel_format; DWORD flags; @@ -355,7 +355,7 @@ static void test_dds_header_handling(void) { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 9, 262146, { D3D_OK, 9 } }, { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 10, 262146, { D3D_OK, 10 } }, }; - struct + static const struct { uint32_t flags; uint32_t width; @@ -375,40 +375,40 @@ static void test_dds_header_handling(void) D3DRESOURCETYPE resource_type; } expected; + uint32_t pixel_data_size; BOOL todo_hr; BOOL todo_info; - uint32_t pixel_data_size; } info_tests[] = { /* Depth value set to 4, but no caps bits are set. Depth is ignored. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 }, /* The volume texture caps2 field is ignored. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 4, (4 * 4), 3, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), DDS_CAPS2_VOLUME, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_TEXTURE, }, 292 }, /* * The DDS_DEPTH flag is the only thing checked to determine if a DDS * file represents a volume texture. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 }, /* Even if the depth field is set to 0, it's still a volume texture. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 0, (4 * 4), 3, 0, 0, - { D3D_OK, 4, 4, 1, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, 292 }, + { D3D_OK, 4, 4, 1, 3, D3DRTYPE_VOLUMETEXTURE, }, 292 }, /* The DDS_DEPTH flag overrides cubemap caps. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT | DDS_DEPTH), 4, 4, 4, (4 * 4), 3, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), - { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, FALSE, FALSE, (292 * 6) }, + { D3D_OK, 4, 4, 4, 3, D3DRTYPE_VOLUMETEXTURE, }, (292 * 6) }, /* Cubemap where width field does not equal height. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 5, 1, (4 * 4), 1, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_ALL_FACES), - { D3D_OK, 4, 5, 1, 1, D3DRTYPE_CUBETEXTURE, }, FALSE, FALSE, (80 * 6) }, + { D3D_OK, 4, 5, 1, 1, D3DRTYPE_CUBETEXTURE, }, (80 * 6) }, /* Partial cubemaps are not supported. */ { (DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT), 4, 4, 1, (4 * 4), 1, (DDS_CAPS_TEXTURE | DDS_CAPS_COMPLEX), (DDS_CAPS2_CUBEMAP | DDS_CAPS2_CUBEMAP_POSITIVEX), - { D3DXERR_INVALIDDATA, }, FALSE, FALSE, (64 * 6) }, + { D3DXERR_INVALIDDATA, }, (64 * 6) }, };
dds = calloc(1, sizeof(*dds));
===================================== dlls/d3dx9_36/tests/texture.c ===================================== @@ -48,6 +48,38 @@ static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, got->x, got->y, got->z, got->w); }
+static inline void check_surface_desc(uint32_t line, D3DFORMAT format, uint32_t usage, D3DPOOL pool, + D3DMULTISAMPLE_TYPE multi_sample_type, uint32_t multi_sample_quality, uint32_t width, uint32_t height, + const D3DSURFACE_DESC *desc, BOOL wine_todo) +{ + const D3DSURFACE_DESC expected_desc = { format, D3DRTYPE_SURFACE, usage, pool, multi_sample_type, + multi_sample_quality, width, height }; + BOOL matched; + + matched = !memcmp(&expected_desc, desc, sizeof(*desc)); + todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected surface desc values.\n"); + if (matched) + return; + + todo_wine_if(wine_todo && desc->Format != format) + ok_(__FILE__, line)(desc->Format == format, "Expected surface format %d, got %d.\n", format, desc->Format); + ok_(__FILE__, line)(desc->Type == D3DRTYPE_SURFACE, "Expected D3DRTYPE_SURFACE, got %d.\n", desc->Type); + todo_wine_if(wine_todo && desc->Usage != usage) + ok_(__FILE__, line)(desc->Usage == usage, "Expected usage %u, got %lu.\n", usage, desc->Usage); + todo_wine_if(wine_todo && desc->Pool != pool) + ok_(__FILE__, line)(desc->Pool == pool, "Expected pool %d, got %d.\n", pool, desc->Pool); + todo_wine_if(wine_todo && desc->MultiSampleType != multi_sample_type) + ok_(__FILE__, line)(desc->MultiSampleType == multi_sample_type, "Expected multi sample type %d, got %d.\n", + multi_sample_type, desc->MultiSampleType); + todo_wine_if(wine_todo && desc->MultiSampleQuality != multi_sample_quality) + ok_(__FILE__, line)(desc->MultiSampleQuality == multi_sample_quality, "Expected multi sample quality %u, got %lu.\n", + multi_sample_quality, desc->MultiSampleQuality); + todo_wine_if(wine_todo && desc->Width != width) + ok_(__FILE__, line)(desc->Width == width, "Expected width %d, got %d.\n", width, desc->Width); + todo_wine_if(wine_todo && desc->Height != height) + ok_(__FILE__, line)(desc->Height == height, "Expected height %d, got %d.\n", height, desc->Height); +} + #define check_texture_level_desc(tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, width, \ height, wine_todo) \ check_texture_level_desc_(__LINE__, tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, \ @@ -56,10 +88,7 @@ static inline void check_texture_level_desc_(uint32_t line, IDirect3DTexture9 *t uint32_t usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multi_sample_type, uint32_t multi_sample_quality, uint32_t width, uint32_t height, BOOL wine_todo) { - const D3DSURFACE_DESC expected_desc = { format, D3DRTYPE_SURFACE, usage, pool, multi_sample_type, - multi_sample_quality, width, height }; D3DSURFACE_DESC desc; - BOOL matched; HRESULT hr;
hr = IDirect3DTexture9_GetLevelDesc(tex, level, &desc); @@ -68,28 +97,28 @@ static inline void check_texture_level_desc_(uint32_t line, IDirect3DTexture9 *t if (FAILED(hr)) return;
- matched = !memcmp(&expected_desc, &desc, sizeof(desc)); - todo_wine_if(wine_todo) ok_(__FILE__, line)(matched, "Got unexpected surface desc values.\n"); - if (matched) + check_surface_desc(line, format, usage, pool, multi_sample_type, multi_sample_quality, width, height, &desc, + wine_todo); +} + +#define check_cube_texture_level_desc(tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, size, \ + wine_todo) \ + check_cube_texture_level_desc_(__LINE__, tex, level, format, usage, pool, multi_sample_type, multi_sample_quality, \ + size, wine_todo) +static inline void check_cube_texture_level_desc_(uint32_t line, IDirect3DCubeTexture9 *tex, uint32_t level, + D3DFORMAT format, uint32_t usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multi_sample_type, + uint32_t multi_sample_quality, uint32_t size, BOOL wine_todo) +{ + D3DSURFACE_DESC desc; + HRESULT hr; + + hr = IDirect3DCubeTexture9_GetLevelDesc(tex, level, &desc); + todo_wine_if(wine_todo && FAILED(hr)) + ok_(__FILE__, line)(hr == S_OK, "Failed to get cube texture level desc with hr %#lx.\n", hr); + if (FAILED(hr)) return;
- todo_wine_if(wine_todo && desc.Format != format) - ok_(__FILE__, line)(desc.Format == format, "Expected surface format %d, got %d.\n", format, desc.Format); - ok_(__FILE__, line)(desc.Type == D3DRTYPE_SURFACE, "Expected D3DRTYPE_SURFACE, got %d.\n", desc.Type); - todo_wine_if(wine_todo && desc.Usage != usage) - ok_(__FILE__, line)(desc.Usage == usage, "Expected usage %u, got %lu.\n", usage, desc.Usage); - todo_wine_if(wine_todo && desc.Pool != pool) - ok_(__FILE__, line)(desc.Pool == pool, "Expected pool %d, got %d.\n", pool, desc.Pool); - todo_wine_if(wine_todo && desc.MultiSampleType != multi_sample_type) - ok_(__FILE__, line)(desc.MultiSampleType == multi_sample_type, "Expected multi sample type %d, got %d.\n", - multi_sample_type, desc.MultiSampleType); - todo_wine_if(wine_todo && desc.MultiSampleQuality != multi_sample_quality) - ok_(__FILE__, line)(desc.MultiSampleQuality == multi_sample_quality, "Expected multi sample quality %u, got %lu.\n", - multi_sample_quality, desc.MultiSampleQuality); - todo_wine_if(wine_todo && desc.Width != width) - ok_(__FILE__, line)(desc.Width == width, "Expected width %u, got %u.\n", width, desc.Width); - todo_wine_if(wine_todo && desc.Height != height) - ok_(__FILE__, line)(desc.Height == height, "Expected height %u, got %u.\n", height, desc.Height); + check_surface_desc(line, format, usage, pool, multi_sample_type, multi_sample_quality, size, size, &desc, wine_todo); }
#define check_volume_texture_level_desc(tex, level, format, usage, pool, width, height, depth, wine_todo) \ @@ -177,21 +206,11 @@ static void release_surface_readback(struct surface_readback *rb) IDirect3DSurface9_Release(rb->surface); }
-static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DTexture9 *texture, uint32_t mip_level, - struct surface_readback *rb) +static void get_surface_readback(IDirect3DDevice9 *device, IDirect3DSurface9 *surface, struct surface_readback *rb) { - IDirect3DSurface9 *surface; D3DSURFACE_DESC desc; HRESULT hr;
- memset(rb, 0, sizeof(*rb)); - hr = IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface); - if (FAILED(hr)) - { - trace("Failed to get surface for mip level %d, hr %#lx.\n", mip_level, hr); - return; - } - hr = IDirect3DSurface9_GetDesc(surface, &desc); if (FAILED(hr)) { @@ -219,7 +238,6 @@ static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DText trace("Can't lock the readback surface, hr %#lx.\n", hr);
exit: - IDirect3DSurface9_Release(surface); if (FAILED(hr)) { if (rb->surface) @@ -228,6 +246,42 @@ exit: } }
+static void get_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DTexture9 *texture, uint32_t mip_level, + struct surface_readback *rb) +{ + IDirect3DSurface9 *surface; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + hr = IDirect3DTexture9_GetSurfaceLevel(texture, mip_level, &surface); + if (FAILED(hr)) + { + trace("Failed to get surface for mip level %d, hr %#lx.\n", mip_level, hr); + return; + } + + get_surface_readback(device, surface, rb); + IDirect3DSurface9_Release(surface); +} + +static void get_cube_texture_surface_readback(IDirect3DDevice9 *device, IDirect3DCubeTexture9 *texture, uint32_t face, + uint32_t mip_level, struct surface_readback *rb) +{ + IDirect3DSurface9 *surface; + HRESULT hr; + + memset(rb, 0, sizeof(*rb)); + hr = IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, mip_level, &surface); + if (FAILED(hr)) + { + trace("Failed to get surface for face %d mip level %d, hr %#lx.\n", face, mip_level, hr); + return; + } + + get_surface_readback(device, surface, rb); + IDirect3DSurface9_Release(surface); +} + #define check_readback_pixel_4bpp(rb, x, y, color, todo) _check_readback_pixel_4bpp(__LINE__, rb, x, y, color, todo) static inline void _check_readback_pixel_4bpp(uint32_t line, struct surface_readback *rb, uint32_t x, uint32_t y, uint32_t expected_color, BOOL todo) @@ -2367,6 +2421,12 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device) hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL); ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#lx, expected %#lx\n", hr, D3DERR_INVALIDCALL);
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &cube_texture); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + + hr = D3DXCreateCubeTextureFromFileInMemory(device, bmp_32bpp_4_4_argb, sizeof(bmp_32bpp_4_4_argb), &cube_texture); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture); if (SUCCEEDED(hr)) { @@ -2385,7 +2445,20 @@ static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device) { + static const uint32_t dds_cube_map_non_square_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xffff00ff, 0xff000000, + }; + static const uint32_t dds_cube_map_4_4_expected[] = + { + 0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffff00, 0xffff00ff, 0xff00ffff, + 0xffffffff, 0xff000000, 0xff800000, 0xff008000, 0xff000080, 0xff808000 + }; IDirect3DCubeTexture9 *cube_texture; + struct surface_readback surface_rb; + D3DSURFACE_DESC desc; + D3DXIMAGE_INFO info; + uint32_t i, x, y; HRESULT hr;
hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT, @@ -2405,6 +2478,176 @@ static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture); ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); IDirect3DCubeTexture9_Release(cube_texture); + + /* + * Cubemap file with a width of 4 and a height of 2. The largest value is + * used for the size of the created cubemap. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + if (y < info.Height) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + + /* + * Load the same cubemap, but this time with a point filter. Source image + * is scaled to cover the entire 4x4 cubemap texture faces. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_2, sizeof(dds_cube_map_4_2), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_POINT, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 4, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + + /* + * Cubemap file with a width of 2 and a height of 4. + */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_2_4, sizeof(dds_cube_map_2_4), D3DX_DEFAULT, 1, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_FILTER_NONE, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 2, 4, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_non_square_expected[i]; + + winetest_push_context("Face %u", i); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + if (x < info.Width) + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + else + check_readback_pixel_4bpp(&surface_rb, x, y, 0xff000000, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); + + /* Multi-mip cubemap DDS file. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, D3DX_FROM_FILE, + D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 2, FALSE); + check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 4, FALSE); + check_cube_texture_level_desc(cube_texture, 1, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, FALSE); + + for (i = 0; i < 6; ++i) + { + uint32_t mip_level; + + for (mip_level = 0; mip_level < 2; ++mip_level) + { + const uint32_t expected_color = dds_cube_map_4_4_expected[(i * 2) + mip_level]; + + winetest_push_context("Face %u, mip level %u", i, mip_level); + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, mip_level, &desc); + get_cube_texture_surface_readback(device, cube_texture, i, mip_level, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + } + IDirect3DCubeTexture9_Release(cube_texture); + + /* Skip level bits are bits 30-26. Bit 31 needs to be ignored. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, + D3DX_FROM_FILE, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, + D3DX_FILTER_POINT | (0x20u << D3DX_SKIP_DDS_MIP_LEVELS_SHIFT), 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + check_image_info(&info, 4, 4, 1, 2, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + IDirect3DCubeTexture9_Release(cube_texture); + + /* Multi-mip cubemap DDS file with mip skipping. */ + hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map_4_4, sizeof(dds_cube_map_4_4), D3DX_DEFAULT, + D3DX_FROM_FILE, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, + D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_DEFAULT), 0, &info, NULL, &cube_texture); + ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr); + + check_texture_mip_levels(cube_texture, 1, FALSE); + check_image_info(&info, 2, 2, 1, 1, D3DFMT_X8R8G8B8, D3DRTYPE_CUBETEXTURE, D3DXIFF_DDS, FALSE); + check_cube_texture_level_desc(cube_texture, 0, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT, 0, 0, 2, FALSE); + + for (i = 0; i < 6; ++i) + { + const uint32_t expected_color = dds_cube_map_4_4_expected[(i * 2) + 1]; + + winetest_push_context("Face %u", i); + IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &desc); + get_cube_texture_surface_readback(device, cube_texture, i, 0, &surface_rb); + for (y = 0; y < desc.Height; ++y) + { + for (x = 0; x < desc.Width; ++x) + { + check_readback_pixel_4bpp(&surface_rb, x, y, expected_color, FALSE); + } + } + release_surface_readback(&surface_rb); + winetest_pop_context(); + } + IDirect3DCubeTexture9_Release(cube_texture); }
static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
===================================== dlls/d3dx9_36/texture.c ===================================== @@ -656,7 +656,7 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi D3DLOCKED_RECT dst_locked_rect; RECT dst_rect;
- hr = d3dx_image_get_pixels(&image, i, &src_pixels); + hr = d3dx_image_get_pixels(&image, 0, i, &src_pixels); if (FAILED(hr)) break;
@@ -1185,7 +1185,7 @@ HRESULT WINAPI D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *devic D3DLOCKED_BOX dst_locked_box; RECT dst_rect;
- hr = d3dx_image_get_pixels(&image, i, &src_pixels); + hr = d3dx_image_get_pixels(&image, 0, i, &src_pixels); if (FAILED(hr)) break;
@@ -1378,15 +1378,14 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, DWORD filter, DWORD mip_filter, D3DCOLOR color_key, D3DXIMAGE_INFO *src_info, PALETTEENTRY *palette, IDirect3DCubeTexture9 **cube_texture) { - HRESULT hr; - D3DCAPS9 caps; - UINT loaded_miplevels; + const struct pixel_format_desc *src_fmt_desc, *dst_fmt_desc; + BOOL dynamic_texture, format_specified = FALSE; + uint32_t loaded_miplevels, skip_levels, i; + IDirect3DCubeTexture9 *tex, *staging_tex; + struct d3dx_image image; D3DXIMAGE_INFO img_info; - BOOL dynamic_texture; - BOOL file_size = FALSE; - BOOL file_format = FALSE; - BOOL file_mip_levels = FALSE; - IDirect3DCubeTexture9 *tex, *buftex; + D3DCAPS9 caps; + HRESULT hr;
TRACE("device %p, src_data %p, src_data_size %u, size %u, mip_levels %u, usage %#lx, " "format %#x, pool %#x, filter %#lx, mip_filter %#lx, color_key 0x%08lx, src_info %p, " @@ -1397,102 +1396,145 @@ HRESULT WINAPI D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device, if (!device || !cube_texture || !src_data || !src_data_size) return D3DERR_INVALIDCALL;
- hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &img_info); + staging_tex = tex = *cube_texture = NULL; + skip_levels = mip_filter != D3DX_DEFAULT ? mip_filter >> D3DX_SKIP_DDS_MIP_LEVELS_SHIFT : 0; + skip_levels &= D3DX_SKIP_DDS_MIP_LEVELS_MASK; + hr = d3dx_image_init(src_data, src_data_size, &image, skip_levels, 0); 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; + FIXME("Unrecognized file format, returning failure.\n"); + return hr; }
- if (format == D3DFMT_FROM_FILE) + d3dximage_info_from_d3dx_image(&img_info, &image); + if (img_info.ResourceType != D3DRTYPE_CUBETEXTURE) { - file_format = TRUE; - format = img_info.Format; + hr = E_FAIL; + goto err; }
- if (mip_levels == D3DX_FROM_FILE) - { - file_mip_levels = TRUE; - mip_levels = img_info.MipLevels; - } + /* Handle default values. */ + if (!size || size == D3DX_DEFAULT_NONPOW2 || size == D3DX_FROM_FILE) + size = max(img_info.Width, img_info.Height); + else if (size == D3DX_DEFAULT) + size = make_pow2(max(img_info.Width, img_info.Height)); + + format_specified = (format != D3DFMT_UNKNOWN && format != D3DX_DEFAULT); + if (format == D3DFMT_FROM_FILE || format == D3DFMT_UNKNOWN || format == D3DX_DEFAULT) + format = img_info.Format; + mip_levels = (mip_levels == D3DX_FROM_FILE) ? img_info.MipLevels : mip_levels;
hr = D3DXCheckCubeTextureRequirements(device, &size, &mip_levels, usage, &format, pool); if (FAILED(hr)) - return hr; + { + FIXME("Couldn't find suitable texture parameters.\n"); + goto err; + }
- if ((file_size && size != img_info.Width) - || (file_format && format != img_info.Format) - || (file_mip_levels && mip_levels != img_info.MipLevels)) - return D3DERR_NOTAVAILABLE; + if (color_key && !format_specified) + format = get_alpha_replacement_format(format);
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps); if (FAILED(hr)) - return D3DERR_INVALIDCALL; + { + hr = D3DERR_INVALIDCALL; + goto err; + }
dynamic_texture = (caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) && (usage & D3DUSAGE_DYNAMIC); if (pool == D3DPOOL_DEFAULT && !dynamic_texture) { - hr = D3DXCreateCubeTexture(device, size, mip_levels, 0, format, D3DPOOL_SYSTEMMEM, &buftex); - tex = buftex; + TRACE("Creating staging texture.\n"); + hr = D3DXCreateCubeTexture(device, size, mip_levels, 0, format, D3DPOOL_SYSTEMMEM, &staging_tex); + tex = staging_tex; } else { hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex); - buftex = NULL; } + if (FAILED(hr)) - return hr; + { + FIXME("Texture creation failed.\n"); + goto err; + } + + TRACE("Texture created correctly. Now loading the texture data into it.\n"); + dst_fmt_desc = get_format_info(format); + src_fmt_desc = get_format_info(img_info.Format); + loaded_miplevels = min(img_info.MipLevels, IDirect3DCubeTexture9_GetLevelCount(tex)); + for (i = 0; i < loaded_miplevels; ++i) + { + struct d3dx_pixels src_pixels, dst_pixels; + D3DSURFACE_DESC dst_surface_desc; + D3DLOCKED_RECT dst_locked_rect; + RECT dst_rect; + uint32_t face; + + IDirect3DCubeTexture9_GetLevelDesc(tex, i, &dst_surface_desc); + SetRect(&dst_rect, 0, 0, dst_surface_desc.Width, dst_surface_desc.Height); + for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; ++face) + { + hr = d3dx_image_get_pixels(&image, face, i, &src_pixels); + if (FAILED(hr)) + break; + + hr = IDirect3DCubeTexture9_LockRect(tex, face, i, &dst_locked_rect, NULL, 0); + if (FAILED(hr)) + break; + + 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, color_key); + IDirect3DCubeTexture9_UnlockRect(tex, face, i); + if (FAILED(hr)) + break; + } + + if (FAILED(hr)) + break; + }
- hr = load_cube_texture_from_dds(tex, src_data, palette, filter, color_key, &img_info); if (FAILED(hr)) { - IDirect3DCubeTexture9_Release(tex); - return hr; + FIXME("Texture loading failed.\n"); + goto err; }
- loaded_miplevels = min(IDirect3DCubeTexture9_GetLevelCount(tex), img_info.MipLevels); hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, palette, loaded_miplevels - 1, mip_filter); if (FAILED(hr)) { - IDirect3DCubeTexture9_Release(tex); - return hr; + FIXME("Texture filtering failed.\n"); + goto err; }
- if (buftex) + if (staging_tex) { - hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, &tex); + hr = D3DXCreateCubeTexture(device, size, mip_levels, usage, format, pool, cube_texture); if (FAILED(hr)) - { - IDirect3DCubeTexture9_Release(buftex); - return hr; - } + goto err;
- IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)buftex, (IDirect3DBaseTexture9 *)tex); - IDirect3DCubeTexture9_Release(buftex); + IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)staging_tex, (IDirect3DBaseTexture9 *)(*cube_texture)); + IDirect3DCubeTexture9_Release(staging_tex); + } + else + { + *cube_texture = tex; }
+ d3dx_image_cleanup(&image); if (src_info) *src_info = img_info;
- *cube_texture = tex; - return D3D_OK; + return hr; + +err: + d3dx_image_cleanup(&image); + if (tex) + IDirect3DCubeTexture9_Release(tex); + + return hr; }
===================================== dlls/d3dx9_36/volume.c ===================================== @@ -202,7 +202,7 @@ HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, cons set_d3dbox(&box, 0, 0, image_info.Width, image_info.Height, 0, image_info.Depth); }
- hr = d3dx_image_get_pixels(&image, 0, &pixels); + hr = d3dx_image_get_pixels(&image, 0, 0, &pixels); if (FAILED(hr)) goto exit;
View it on GitLab: https://gitlab.winehq.org/wine/wine/-/compare/b3aac0e5562c8e29c30b2e2a5c7f2f...