From: Connor McAdams <cmcadams@codeweavers.com> Signed-off-by: Connor McAdams <cmcadams@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 693 ++++++++++++++++++++++++++++++++++ 1 file changed, 693 insertions(+) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 78278da0a60..0816cc073d7 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -882,6 +882,75 @@ static const uint8_t dds_2d_array_4_4_data[] = 0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff, }; +/* A 4x4x4 3D texture with 2 mips. */ +static const uint8_t dds_dxt10_3d_texture_4_4[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x01,0x10,0x80,0x00,0x04,0x00,0x00,0x00, + 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x04,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, + 0x04,0x00,0x00,0x00,0x44,0x58,0x31,0x30,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, + 0x1c,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,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,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,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,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,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff, + 0xff,0x00,0x00,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,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff, + 0xff,0x00,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0x80,0x80,0x80,0xff, +}; + +/* 8x8 DXT10 DDS file with a format of DXGI_FORMAT_R8G8B8A8_UNORM and 4 mips. */ +static const uint8_t dds_dxt10_8_8[] = +{ + 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x01,0x10,0x00,0x00,0x08,0x00,0x00,0x00, + 0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,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, + 0x04,0x00,0x00,0x00,0x44,0x58,0x31,0x30,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, + 0x1c,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff, + 0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff, + 0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff, + 0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff,0x40,0x40,0x40,0xff, + 0x40,0x40,0x40,0xff,0x20,0x20,0x20,0xff,0x20,0x20,0x20,0xff,0x20,0x20,0x20,0xff, + 0x20,0x20,0x20,0xff,0x10,0x10,0x10,0xff, +}; + /* 1x1 wmp image */ static const uint8_t test_wmp[] = { @@ -3102,6 +3171,73 @@ static void check_resource_data(ID3D10Resource *resource, const struct test_imag } } +#define check_test_resource_data(resource, data) check_test_resource_data_(__LINE__, resource, data) +static void check_test_resource_data_(unsigned int line, ID3D10Resource *resource, const void *expected_data) +{ + D3D10_RESOURCE_DIMENSION resource_dimension; + const uint8_t *cur_data = expected_data; + uint32_t levels, layers, i, j, fmt_bpp; + struct resource_readback rb = { 0 }; + DXGI_FORMAT format; + HRESULT hr; + + ID3D10Resource_GetType(resource, &resource_dimension); + switch (resource_dimension) + { + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + { + D3D10_TEXTURE2D_DESC desc_2d; + ID3D10Texture2D *tex_2d; + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture2D, (void **)&tex_2d); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID3D10Texture2D_GetDesc(tex_2d, &desc_2d); + ID3D10Texture2D_Release(tex_2d); + + levels = desc_2d.MipLevels; + layers = desc_2d.ArraySize; + format = desc_2d.Format; + break; + } + + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + { + D3D10_TEXTURE3D_DESC desc_3d; + ID3D10Texture3D *tex_3d; + + hr = ID3D10Resource_QueryInterface(resource, &IID_ID3D10Texture3D, (void **)&tex_3d); + ok_(__FILE__, line)(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ID3D10Texture3D_GetDesc(tex_3d, &desc_3d); + ID3D10Texture3D_Release(tex_3d); + + levels = desc_3d.MipLevels; + layers = 1; + format = desc_3d.Format; + break; + } + + default: + assert(0 && "Unsupported resource type."); + break; + } + + fmt_bpp = (get_bpp_from_format(format) + 7) / 8; + for (i = 0; i < layers; ++i) + { + for (j = 0; j < levels; ++j) + { + winetest_push_context("Layer %u, level %u", i, j); + get_resource_readback(resource, (i * levels) + j, &rb); + + _check_test_readback(__FILE__, line, &rb, cur_data, rb.width, rb.height, rb.depth, format, 0); + cur_data += (rb.width * fmt_bpp * rb.height * rb.depth); + + release_resource_readback(&rb); + winetest_pop_context(); + } + } +} + static void test_D3DX10UnsetAllDeviceObjects(void) { static const D3D10_INPUT_ELEMENT_DESC layout_desc[] = @@ -6009,6 +6145,562 @@ static void test_srgb_filter_flags(void) ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); } +struct test_resource +{ + D3D10_RESOURCE_DIMENSION type; + union + { + D3D10_TEXTURE2D_DESC desc_2d; + D3D10_TEXTURE3D_DESC desc_3d; + } desc; +}; + +static void init_subresource_data(D3D10_SUBRESOURCE_DATA *subresources, const void *data, uint32_t width, uint32_t height, + uint32_t depth, uint32_t mip_levels, uint32_t array_size, DXGI_FORMAT format) +{ + const uint8_t *pixel_ptr = data; + uint32_t i, j; + + for (i = 0; i < array_size; ++i) + { + uint32_t tmp_width, tmp_height, tmp_depth; + + tmp_width = width; + tmp_height = height; + tmp_depth = depth; + for (j = 0; j < mip_levels; ++j) + { + D3D10_SUBRESOURCE_DATA *subresource = &subresources[(i * mip_levels) + j]; + + subresource->pSysMem = pixel_ptr; + subresource->SysMemPitch = (tmp_width * get_bpp_from_format(format) + 7) / 8; + subresource->SysMemSlicePitch = subresource->SysMemPitch * tmp_height; + if (is_block_compressed(format)) + subresource->SysMemPitch *= 4; + pixel_ptr += (subresource->SysMemSlicePitch * tmp_depth); + + tmp_width = max(tmp_width / 2, 1); + tmp_height = max(tmp_height / 2, 1); + tmp_depth = max(tmp_depth / 2, 1); + } + } +} + +static ID3D10Resource *create_texture_resource(ID3D10Device *device, const struct test_resource *test_rsrc) +{ + D3D10_SUBRESOURCE_DATA subresources[16] = { 0 }; + uint8_t buffer[8192] = { 0 }; + ID3D10Resource *ret = NULL; + HRESULT hr = S_OK; + + switch (test_rsrc->type) + { + case D3D10_RESOURCE_DIMENSION_TEXTURE2D: + { + const D3D10_TEXTURE2D_DESC *desc_2d = &test_rsrc->desc.desc_2d; + + assert((desc_2d->MipLevels * desc_2d->ArraySize) <= ARRAY_SIZE(subresources)); + init_subresource_data(subresources, buffer, desc_2d->Width, desc_2d->Height, 1, desc_2d->MipLevels, + desc_2d->ArraySize, desc_2d->Format); + hr = ID3D10Device_CreateTexture2D(device, desc_2d, subresources, (ID3D10Texture2D **)&ret); + break; + } + + case D3D10_RESOURCE_DIMENSION_TEXTURE3D: + { + const D3D10_TEXTURE3D_DESC *desc_3d = &test_rsrc->desc.desc_3d; + + assert(desc_3d->MipLevels <= ARRAY_SIZE(subresources)); + init_subresource_data(subresources, buffer, desc_3d->Width, desc_3d->Height, desc_3d->Depth, + desc_3d->MipLevels, 1, desc_3d->Format); + hr = ID3D10Device_CreateTexture3D(device, desc_3d, subresources, (ID3D10Texture3D **)&ret); + break; + } + + default: + assert(0 && "Invalid resource type."); + } + + if (FAILED(hr)) + trace("Failed to create texture, hr %#lx.\n", hr); + return ret; +} + +static void test_load_texture_from_texture(void) +{ + static const uint8_t test_10_expected[] = + { + 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,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,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,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, + }; + static const uint8_t test_15_expected[] = + { + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0xff, + 0x80,0x80,0x80,0xff, + }; + static const uint8_t test_16_expected[] = + { + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff,0x10,0x10,0x10,0xff, + 0x10,0x10,0x10,0xff, + }; + static const uint8_t test_18_expected[] = + { + 0x00,0x00,0xff,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,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, + }; + static const D3DX10_IMAGE_LOAD_INFO d3dx10_from_file_load_info = + { + D3DX10_FROM_FILE, D3DX10_FROM_FILE, D3DX10_FROM_FILE, D3DX10_DEFAULT, D3DX10_FROM_FILE, D3DX10_DEFAULT, + D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, DXGI_FORMAT_FROM_FILE, D3DX10_FILTER_NONE, + D3DX10_FILTER_NONE, NULL + }; + static const struct + { + D3DX10_TEXTURE_LOAD_INFO load_info; + const uint8_t *src_data; + unsigned int src_data_size; + D3D10_BOX src_box; + BOOL use_src_box; + + struct test_resource dst_rsrc; + D3D10_BOX dst_box; + BOOL use_dst_box; + HRESULT expected_hr; + const uint8_t *expected_dst; + unsigned int broken_below_version; + BOOL todo_hr; + } tests[] = + { + /* + * Source and destination are the same texture. If the elements and + * levels match, the function will fail. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { D3D10_RESOURCE_DIMENSION_UNKNOWN }, { 0 }, FALSE, D3DERR_INVALIDCALL, .todo_hr = TRUE + }, + /* Invalid pSrcBox dimensions. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 1, 0, 0, 0, 0, 0 }, TRUE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, D3DERR_INVALIDCALL, .broken_below_version = 40, .todo_hr = TRUE + }, + /* Invalid pDstBox dimensions. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0, 1, 0, 0, 0, 0 }, TRUE, D3DERR_INVALIDCALL, .broken_below_version = 40, .todo_hr = TRUE + }, + /* + * Invalid filter flags. Still validated even if SrcFirstMip is higher + * than number of levels in the source texture. + */ + { + { NULL, NULL, 3, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, 9, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, D3DERR_INVALIDCALL, .todo_hr = TRUE + }, + /* + * Filter flags aren't validated if DstFirstMip is higher than the + * number of levels. + */ + { + { NULL, NULL, 0, 1, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, 9, D3DX10_FILTER_NONE }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, .todo_hr = TRUE + }, + /* + * 5. + * Filter flags aren't validated if SrcFirstElement is higher than the + * number of source elements. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 2, 0, D3DX10_DEFAULT, 9, D3DX10_FILTER_NONE }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, .todo_hr = TRUE + }, + /* + * Filter flags aren't validated if DstFirstElement is higher than the + * number of destination elements. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 1, D3DX10_DEFAULT, 9, D3DX10_FILTER_NONE }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, .todo_hr = TRUE + }, + /* Invalid mip filter flags. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_DEFAULT, 9 }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 3, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, D3DERR_INVALIDCALL, .todo_hr = TRUE + }, + /* + * Invalid mip filter flags. If no mips are generated, no validation is + * done. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, 9 }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_2d_array_4_4[0x94], .todo_hr = TRUE + }, + /* Destination texture is immutable. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_IMMUTABLE, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, D3DERR_INVALIDCALL, .todo_hr = TRUE + }, + /* + * 10. + * Source and destination are the same texture. + * Source is level 0 of element 0. + * Destination is level 0 of element 1. + * Load levels 0-1 from element 0 into levels 0-1 of element 1. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 1, D3DX10_DEFAULT, D3DX10_FILTER_NONE, D3DX10_DEFAULT }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { D3D10_RESOURCE_DIMENSION_UNKNOWN }, { 0 }, FALSE, S_OK, test_10_expected, .todo_hr = TRUE + }, + /* Load a 3D texture into a 2D texture. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, D3DX10_DEFAULT }, + dds_dxt10_3d_texture_4_4, sizeof(dds_dxt10_3d_texture_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_dxt10_3d_texture_4_4[0x94], .todo_hr = TRUE + }, + /* Load a 3D texture into a 2D texture with a source box offset. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, D3DX10_DEFAULT }, + dds_dxt10_3d_texture_4_4, sizeof(dds_dxt10_3d_texture_4_4), { 0, 0, 1, 4, 4, 2 }, TRUE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_dxt10_3d_texture_4_4[0xd4], .todo_hr = TRUE + }, + /* Load a 3D texture into a 3D texture with identical dimensions. */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, D3DX10_DEFAULT }, + dds_dxt10_3d_texture_4_4, sizeof(dds_dxt10_3d_texture_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE3D, + .desc.desc_3d = + { + 4, 4, 4, 2, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_dxt10_3d_texture_4_4[0x94], .todo_hr = TRUE + }, + /* Load a 3D texture into a 3D texture with a first mip offset. */ + { + { NULL, NULL, 1, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, D3DX10_DEFAULT }, + dds_dxt10_3d_texture_4_4, sizeof(dds_dxt10_3d_texture_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE3D, + .desc.desc_3d = + { + 2, 2, 2, 1, DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_dxt10_3d_texture_4_4[0x194], .todo_hr = TRUE + }, + /* + * 15. + * Source and destination are the same texture. + * Source is level 0 of element 0. + * Destination is level 1 of element 0. + * Load level n into level n+1. + */ + { + { NULL, NULL, 0, 1, 3, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, 9 }, + dds_dxt10_8_8, sizeof(dds_dxt10_8_8), { 0 }, FALSE, + { D3D10_RESOURCE_DIMENSION_UNKNOWN }, { 0 }, FALSE, S_OK, test_15_expected, .todo_hr = TRUE + }, + /* + * Source and destination are the same texture. + * Source is level 3 of element 0. + * Destination is level 0 of element 0. + * Load level 3 into level 0, generate levels 1-3 from level 0. + */ + { + { NULL, NULL, 3, 0, 4, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_POINT, D3DX10_FILTER_POINT }, + dds_dxt10_8_8, sizeof(dds_dxt10_8_8), { 0 }, FALSE, + { D3D10_RESOURCE_DIMENSION_UNKNOWN }, { 0 }, FALSE, S_OK, test_16_expected, .todo_hr = TRUE + }, + /* + * Argument of 0 for NumElements/NumMips matches behavior of + * D3DX10_DEFAULT. + */ + { + { NULL, NULL, 0, 0, 0, 0, 0, 0, D3DX10_FILTER_NONE, 9 }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 2, 2, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, &dds_2d_array_4_4[0x94], .todo_hr = TRUE + }, + /* + * Empty source box results in a 1x1x1 box. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, 9 }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, TRUE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, FALSE, S_OK, test_18_expected, .todo_hr = TRUE + }, + /* + * Empty destination box results in a 1x1x1 box. + */ + { + { NULL, NULL, 0, 0, D3DX10_DEFAULT, 0, 0, D3DX10_DEFAULT, D3DX10_FILTER_NONE, 9 }, + dds_2d_array_4_4, sizeof(dds_2d_array_4_4), { 0 }, FALSE, + { + D3D10_RESOURCE_DIMENSION_TEXTURE2D, + .desc.desc_2d = + { + 4, 4, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM, { 1, 0 }, D3D10_USAGE_DEFAULT, D3D10_BIND_SHADER_RESOURCE, + 0, 0, + } + }, { 0 }, TRUE, S_OK, test_18_expected, .todo_hr = TRUE + }, + }; + const uint8_t empty_buffer[8192] = { 0 }; + ID3D10Resource *src_rsrc, *dst_rsrc; + const uint8_t *expected_dst; + ID3D10Device *device; + unsigned int i; + HRESULT hr; + + if (D3DX10_SDK_VERSION <= 34) + { + skip("D3DX10LoadTextureFromTexture() behavior is broken in version 34 and below.\n"); + return; + } + + device = create_device(); + if (!device) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + D3DX10_IMAGE_LOAD_INFO img_load_info = d3dx10_from_file_load_info; + D3DX10_TEXTURE_LOAD_INFO load_info = tests[i].load_info; + D3D10_BOX src_box = tests[i].src_box; + D3D10_BOX dst_box = tests[i].dst_box; + + if (D3DX10_SDK_VERSION < tests[i].broken_below_version) + { + skip("Test %u broken on version %u, skipping test.\n", i, D3DX10_SDK_VERSION); + continue; + } + + winetest_push_context("Test %u", i); + + hr = D3DX10CreateTextureFromMemory(device, tests[i].src_data, tests[i].src_data_size, &img_load_info, NULL, + &src_rsrc, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + load_info.pSrcBox = (tests[i].use_src_box) ? &src_box : NULL; + load_info.pDstBox = (tests[i].use_dst_box) ? &dst_box : NULL; + expected_dst = (tests[i].expected_dst) ? tests[i].expected_dst : empty_buffer; + + dst_rsrc = (tests[i].dst_rsrc.type) ? create_texture_resource(device, &tests[i].dst_rsrc) : src_rsrc; + ok(!!dst_rsrc, "Got unexpected dst_rsrc %p.\n", dst_rsrc); + + hr = D3DX10LoadTextureFromTexture(src_rsrc, &load_info, dst_rsrc); + todo_wine_if(tests[i].todo_hr) ok(hr == tests[i].expected_hr, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_test_resource_data(dst_rsrc, expected_dst); + + ID3D10Resource_Release(src_rsrc); + if (dst_rsrc != src_rsrc) + ID3D10Resource_Release(dst_rsrc); + + winetest_pop_context(); + } + + /* NULL load_info argument, gets default load_info values. */ + hr = D3DX10CreateTextureFromMemory(device, dds_2d_array_4_4, sizeof(dds_2d_array_4_4), + (D3DX10_IMAGE_LOAD_INFO *)&d3dx10_from_file_load_info, NULL, &src_rsrc, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + dst_rsrc = create_texture_resource(device, &tests[8].dst_rsrc); + ok(!!dst_rsrc, "Got unexpected dst_rsrc %p.\n", dst_rsrc); + + /* Test NULL arguments for source/dest resource. */ + hr = D3DX10LoadTextureFromTexture(src_rsrc, NULL, NULL); + todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); + + hr = D3DX10LoadTextureFromTexture(NULL, NULL, dst_rsrc); + todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); + + hr = D3DX10LoadTextureFromTexture(NULL, NULL, NULL); + todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr); + + /* NULL load_info argument, gets default load_info values. */ + hr = D3DX10LoadTextureFromTexture(src_rsrc, NULL, dst_rsrc); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_test_resource_data(dst_rsrc, &dds_2d_array_4_4[0x94]); + + ID3D10Resource_Release(src_rsrc); + ID3D10Resource_Release(dst_rsrc); + + /* NULL load_info argument on 3D texture. */ + hr = D3DX10CreateTextureFromMemory(device, dds_dxt10_3d_texture_4_4, sizeof(dds_dxt10_3d_texture_4_4), + (D3DX10_IMAGE_LOAD_INFO *)&d3dx10_from_file_load_info, NULL, &src_rsrc, NULL); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + dst_rsrc = create_texture_resource(device, &tests[13].dst_rsrc); + ok(!!dst_rsrc, "Got unexpected dst_rsrc %p.\n", dst_rsrc); + + hr = D3DX10LoadTextureFromTexture(src_rsrc, NULL, dst_rsrc); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + check_test_resource_data(dst_rsrc, &dds_dxt10_3d_texture_4_4[0x94]); + + ID3D10Resource_Release(src_rsrc); + ID3D10Resource_Release(dst_rsrc); + + ok(!ID3D10Device_Release(device), "Unexpected refcount.\n"); +} + #define check_rect(rect, left, top, right, bottom) _check_rect(__LINE__, rect, left, top, right, bottom) static inline void _check_rect(unsigned int line, const RECT *rect, int left, int top, int right, int bottom) { @@ -7500,4 +8192,5 @@ START_TEST(d3dx10) test_image_filters(); test_dxt_formats(); test_srgb_filter_flags(); + test_load_texture_from_texture(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10887