This finishes up the handling of `D3DX10_IMAGE_LOAD_INFO` fields. :)
The default filter values were confirmed using a test locally that I've pushed to a branch here: https://gitlab.winehq.org/cmcadams/wine/-/commits/d3dx10-filter-test
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 12 +++++++++--- dlls/d3dx9_36/d3dx9_private.h | 10 +--------- dlls/d3dx9_36/d3dx_helpers.c | 9 +++++++++ dlls/d3dx9_36/d3dx_helpers.h | 2 ++ dlls/d3dx9_36/texture.c | 2 +- 6 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 88bcb4784d3..49292c8982a 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1096,7 +1096,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, (D3D10_USAGE)D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7, D3DX10_DEFAULT }, - D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE + D3DERR_INVALIDCALL, D3DERR_INVALIDCALL }, /* Invalid mipfilter value, only validated if mips are generated. */ { diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 10c939f5e4f..db33bd20a1f 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -660,12 +660,18 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO FIXME("load_info->CpuAccessFlags is ignored.\n"); if (load_info->MiscFlags != D3DX10_DEFAULT) FIXME("load_info->MiscFlags is ignored.\n"); - if (load_info->Filter != D3DX10_DEFAULT) - FIXME("load_info->Filter is ignored.\n"); if (load_info->MipFilter != D3DX10_DEFAULT) FIXME("load_info->MipFilter is ignored.\n");
*resource_data = NULL; + if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT) + load_info->Filter = D3DX10_FILTER_LINEAR; + if (FAILED(hr = d3dx_validate_filter(load_info->Filter))) + { + ERR("Invalid filter argument %#x.\n", load_info->Filter); + return hr; + } + hr = d3dx_image_init(data, size, &image, 0, D3DX_IMAGE_SUPPORT_DXT10); if (FAILED(hr)) return E_FAIL; @@ -748,7 +754,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO set_d3dx_pixels(&dst_pixels, pixels_buffer, dst_row_pitch, dst_slice_pitch, NULL, dst_size.width, dst_size.height, dst_size.depth, &unaligned_rect);
- hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, D3DX10_FILTER_POINT, 0); + hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, load_info->Filter, 0); if (FAILED(hr)) break;
diff --git a/dlls/d3dx9_36/d3dx9_private.h b/dlls/d3dx9_36/d3dx9_private.h index a52636298be..d47c3e8cb70 100644 --- a/dlls/d3dx9_36/d3dx9_private.h +++ b/dlls/d3dx9_36/d3dx9_private.h @@ -35,20 +35,12 @@ #define FOURCC_TX_1 0x54580100
#define D3DX9_FILTER_INVALID_BITS 0xff80fff8 -static inline HRESULT d3dx9_validate_filter(uint32_t filter) -{ - if ((filter & D3DX9_FILTER_INVALID_BITS) || !(filter & 0x7) || ((filter & 0x7) > D3DX_FILTER_BOX)) - return D3DERR_INVALIDCALL; - - return D3D_OK; -} - static inline HRESULT d3dx9_handle_load_filter(DWORD *filter) { if (*filter == D3DX_DEFAULT) *filter = D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER;
- return d3dx9_validate_filter(*filter); + return d3dx_validate_filter(*filter); }
BOOL d3dximage_info_from_d3dx_image(D3DXIMAGE_INFO *info, struct d3dx_image *image); diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 83c9befb08b..3e1bda400d7 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -53,6 +53,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); #define D3DX_FILTER_SRGB_OUT 0x00400000 #define D3DX_FILTER_SRGB 0x00600000
+#define D3DX_FILTER_INVALID_BITS 0xff80fff8 +HRESULT d3dx_validate_filter(uint32_t filter) +{ + if ((filter & D3DX_FILTER_INVALID_BITS) || !(filter & 0x7) || ((filter & 0x7) > D3DX_FILTER_BOX)) + return D3DERR_INVALIDCALL; + + return D3D_OK; +} + HRESULT WINAPI WICCreateImagingFactory_Proxy(UINT, IWICImagingFactory**);
/************************************************************ diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 42b40c1c279..83c213db311 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -394,6 +394,8 @@ static inline BOOL is_conversion_to_supported(const struct pixel_format_desc *fo && !is_unknown_format(format); }
+HRESULT d3dx_validate_filter(uint32_t filter); + const struct pixel_format_desc *get_d3dx_pixel_format_info(enum d3dx_pixel_format_id format);
void format_to_d3dx_color(const struct pixel_format_desc *format, const BYTE *src, const PALETTEENTRY *palette, diff --git a/dlls/d3dx9_36/texture.c b/dlls/d3dx9_36/texture.c index 2896bd1f2b6..0873b686497 100644 --- a/dlls/d3dx9_36/texture.c +++ b/dlls/d3dx9_36/texture.c @@ -59,7 +59,7 @@ HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9 *texture, if (!texture) return D3DERR_INVALIDCALL;
- if (filter != D3DX_DEFAULT && FAILED(hr = d3dx9_validate_filter(filter))) + if (filter != D3DX_DEFAULT && FAILED(hr = d3dx_validate_filter(filter))) return hr;
if (srclevel == D3DX_DEFAULT)
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 3 +- dlls/d3dx10_43/texture.c | 97 +++++++++++++++++++++-------------- dlls/d3dx9_36/d3dx_helpers.c | 69 +++++++++++++++++++++++++ dlls/d3dx9_36/d3dx_helpers.h | 17 ++++++ 4 files changed, 146 insertions(+), 40 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 49292c8982a..486e77ca549 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1114,7 +1114,7 @@ static const struct test_invalid_image_load_info 2, 2, D3DX10_DEFAULT, D3DX10_DEFAULT, 2, (D3D10_USAGE)D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, 7 }, - D3DERR_INVALIDCALL, D3DERR_INVALIDCALL, .todo_hr = TRUE, .todo_process_hr = TRUE + D3DERR_INVALIDCALL, D3DERR_INVALIDCALL }, /* * Usage/BindFlags/CpuAccessFlags are validated in the call to @@ -1978,7 +1978,6 @@ static void check_resource_info(ID3D10Resource *resource, const struct test_imag ok_(__FILE__, line)(desc_2d.Height == expected_height, "Got unexpected Height %u, expected %u.\n", desc_2d.Height, expected_height); - todo_wine_if(expected_mip_levels != image->expected_info.MipLevels) ok_(__FILE__, line)(desc_2d.MipLevels == expected_mip_levels, "Got unexpected MipLevels %u, expected %u.\n", desc_2d.MipLevels, expected_mip_levels); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index db33bd20a1f..1c9f303929a 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -638,8 +638,8 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO D3D10_SUBRESOURCE_DATA **resource_data) { const struct pixel_format_desc *fmt_desc, *src_desc; - BYTE *res_data = NULL, *pixels_buffer; - uint32_t pixels_size, pixels_offset; + struct d3dx_subresource_data *sub_rsrcs = NULL; + uint32_t loaded_mip_levels, max_mip_levels; D3DX10_IMAGE_INFO img_info; struct d3dx_image image; unsigned int i, j; @@ -650,8 +650,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO
if (load_info->FirstMipLevel != D3DX10_DEFAULT) FIXME("load_info->FirstMipLevel is ignored.\n"); - if (load_info->MipLevels != D3DX10_DEFAULT) - FIXME("load_info->MipLevels is ignored.\n"); if (load_info->Usage != D3DX10_DEFAULT) FIXME("load_info->Usage is ignored.\n"); if (load_info->BindFlags != D3DX10_DEFAULT) @@ -660,8 +658,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO FIXME("load_info->CpuAccessFlags is ignored.\n"); if (load_info->MiscFlags != D3DX10_DEFAULT) FIXME("load_info->MiscFlags is ignored.\n"); - if (load_info->MipFilter != D3DX10_DEFAULT) - FIXME("load_info->MipFilter is ignored.\n");
*resource_data = NULL; if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT) @@ -717,62 +713,89 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end; }
- load_info->MipLevels = img_info.MipLevels; + max_mip_levels = d3dx_get_max_mip_levels_for_size(load_info->Width, load_info->Height, load_info->Depth); + if (!load_info->MipLevels || load_info->MipLevels == D3DX10_DEFAULT || load_info->MipLevels == D3DX10_FROM_FILE) + load_info->MipLevels = (load_info->MipLevels == D3DX10_FROM_FILE) ? img_info.MipLevels : max_mip_levels; + load_info->MipLevels = min(max_mip_levels, load_info->MipLevels);
- pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, load_info->Width, load_info->Height, - load_info->Depth, load_info->MipLevels) * img_info.ArraySize; - pixels_offset = (sizeof(**resource_data) * load_info->MipLevels * img_info.ArraySize); - if (!(res_data = malloc(pixels_size + pixels_offset))) - { - hr = E_OUTOFMEMORY; + hr = d3dx_create_subresource_data_for_texture(load_info->Width, load_info->Height, load_info->Depth, + load_info->MipLevels, img_info.ArraySize, fmt_desc, &sub_rsrcs); + if (FAILED(hr)) goto end; - } - - pixels_buffer = res_data + pixels_offset; - *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data;
src_desc = get_d3dx_pixel_format_info(image.format); + loaded_mip_levels = min(img_info.MipLevels, load_info->MipLevels); for (i = 0; i < img_info.ArraySize; ++i) { struct volume dst_size = { load_info->Width, load_info->Height, load_info->Depth };
- for (j = 0; j < load_info->MipLevels; ++j) + for (j = 0; j < loaded_mip_levels; ++j) { + struct d3dx_subresource_data *sub_rsrc = &sub_rsrcs[i * load_info->MipLevels + j]; const RECT unaligned_rect = { 0, 0, dst_size.width, dst_size.height }; struct d3dx_pixels src_pixels, dst_pixels; - uint32_t dst_row_pitch, dst_slice_pitch;
hr = d3dx_image_get_pixels(&image, i, j, &src_pixels); if (FAILED(hr)) - break; + goto end;
- hr = d3dx_calculate_pixels_size(fmt_desc->format, dst_size.width, dst_size.height, &dst_row_pitch, - &dst_slice_pitch); - if (FAILED(hr)) - break; - - set_d3dx_pixels(&dst_pixels, pixels_buffer, dst_row_pitch, dst_slice_pitch, NULL, dst_size.width, + set_d3dx_pixels(&dst_pixels, sub_rsrc->data, sub_rsrc->row_pitch, sub_rsrc->slice_pitch, NULL, dst_size.width, dst_size.height, dst_size.depth, &unaligned_rect);
hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, src_desc, load_info->Filter, 0); if (FAILED(hr)) - break; - - (*resource_data)[i * load_info->MipLevels + j].pSysMem = pixels_buffer; - (*resource_data)[i * load_info->MipLevels + j].SysMemPitch = dst_row_pitch; - (*resource_data)[i * load_info->MipLevels + j].SysMemSlicePitch = dst_slice_pitch; + goto end;
- pixels_buffer += dst_slice_pitch * dst_size.depth; d3dx_get_next_mip_level_size(&dst_size); } }
- if (FAILED(hr)) + if (loaded_mip_levels < load_info->MipLevels) { - *resource_data = NULL; - goto end; + struct volume base_level_size = { load_info->Width, load_info->Height, load_info->Depth }; + const uint32_t base_level = loaded_mip_levels - 1; + + if (!load_info->MipFilter || load_info->MipFilter == D3DX10_DEFAULT) + load_info->MipFilter = D3DX10_FILTER_LINEAR; + if (FAILED(hr = d3dx_validate_filter(load_info->MipFilter))) + { + ERR("Invalid mip filter argument %#x.\n", load_info->MipFilter); + goto end; + } + + d3dx_get_mip_level_size(&base_level_size, base_level); + for (i = 0; i < img_info.ArraySize; ++i) + { + struct volume src_size, dst_size; + + src_size = dst_size = base_level_size; + for (j = base_level; j < (load_info->MipLevels - 1); ++j) + { + struct d3dx_subresource_data *dst_data = &sub_rsrcs[i * load_info->MipLevels + j + 1]; + struct d3dx_subresource_data *src_data = &sub_rsrcs[i * load_info->MipLevels + j]; + const RECT src_unaligned_rect = { 0, 0, src_size.width, src_size.height }; + struct d3dx_pixels src_pixels, dst_pixels; + RECT dst_unaligned_rect; + + d3dx_get_next_mip_level_size(&dst_size); + SetRect(&dst_unaligned_rect, 0, 0, dst_size.width, dst_size.height); + set_d3dx_pixels(&dst_pixels, dst_data->data, dst_data->row_pitch, dst_data->slice_pitch, NULL, + dst_size.width, dst_size.height, dst_size.depth, &dst_unaligned_rect); + set_d3dx_pixels(&src_pixels, src_data->data, src_data->row_pitch, src_data->slice_pitch, NULL, + src_size.width, src_size.height, src_size.depth, &src_unaligned_rect); + + hr = d3dx_load_pixels_from_pixels(&dst_pixels, fmt_desc, &src_pixels, fmt_desc, load_info->MipFilter, 0); + if (FAILED(hr)) + goto end; + + src_size = dst_size; + } + } }
+ *resource_data = (D3D10_SUBRESOURCE_DATA *)sub_rsrcs; + sub_rsrcs = NULL; + load_info->Usage = D3D10_USAGE_DEFAULT; load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; load_info->MiscFlags = img_info.MiscFlags; @@ -783,11 +806,9 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO assert(load_info->pSrcInfo); *load_info->pSrcInfo = img_info;
- res_data = NULL; - end: d3dx_image_cleanup(&image); - free(res_data); + free(sub_rsrcs); return hr; }
diff --git a/dlls/d3dx9_36/d3dx_helpers.c b/dlls/d3dx9_36/d3dx_helpers.c index 3e1bda400d7..69a54ed4188 100644 --- a/dlls/d3dx9_36/d3dx_helpers.c +++ b/dlls/d3dx9_36/d3dx_helpers.c @@ -445,6 +445,28 @@ void d3dx_get_next_mip_level_size(struct volume *size) size->depth = max(size->depth / 2, 1); }
+void d3dx_get_mip_level_size(struct volume *size, uint32_t level) +{ + uint32_t i; + + for (i = 0; i < level; ++i) + d3dx_get_next_mip_level_size(size); +} + +uint32_t d3dx_get_max_mip_levels_for_size(uint32_t width, uint32_t height, uint32_t depth) +{ + struct volume tmp = { width, height, depth }; + uint32_t mip_levels = 1; + + while (!(tmp.width == 1 && tmp.height == 1 && tmp.depth == 1)) + { + d3dx_get_next_mip_level_size(&tmp); + mip_levels++; + } + + return mip_levels; +} + static const char *debug_volume(const struct volume *volume) { if (!volume) @@ -3158,3 +3180,50 @@ void get_aligned_rect(uint32_t left, uint32_t top, uint32_t right, uint32_t bott aligned_rect->bottom = min((aligned_rect->bottom + fmt_desc->block_height - 1) & ~(fmt_desc->block_height - 1), height); } + +HRESULT d3dx_create_subresource_data_for_texture(uint32_t width, uint32_t height, uint32_t depth, + uint32_t mip_levels, uint32_t layer_count, const struct pixel_format_desc *fmt_desc, + struct d3dx_subresource_data **out_sub_rsrc_data) +{ + struct d3dx_subresource_data *sub_rsrcs = NULL; + uint8_t *sub_rsrc_data = NULL, *pixels_ptr; + uint32_t pixels_size, pixels_offset; + unsigned int i, j; + HRESULT hr = S_OK; + + *out_sub_rsrc_data = NULL; + pixels_offset = sizeof(*sub_rsrcs) * mip_levels * layer_count; + pixels_size = d3dx_calculate_layer_pixels_size(fmt_desc->format, width, height, depth, mip_levels) * layer_count; + if (!(sub_rsrc_data = malloc(pixels_size + pixels_offset))) + return E_OUTOFMEMORY; + + sub_rsrcs = (struct d3dx_subresource_data *)sub_rsrc_data; + pixels_ptr = sub_rsrc_data + pixels_offset; + for (i = 0; i < layer_count; ++i) + { + struct volume size = { width, height, depth }; + + for (j = 0; j < mip_levels; ++j) + { + uint32_t row_pitch, slice_pitch; + + hr = d3dx_calculate_pixels_size(fmt_desc->format, size.width, size.height, &row_pitch, &slice_pitch); + if (FAILED(hr)) + goto exit; + + sub_rsrcs[i * mip_levels + j].data = pixels_ptr; + sub_rsrcs[i * mip_levels + j].row_pitch = row_pitch; + sub_rsrcs[i * mip_levels + j].slice_pitch = slice_pitch; + + pixels_ptr += slice_pitch * size.depth; + d3dx_get_next_mip_level_size(&size); + } + } + + *out_sub_rsrc_data = sub_rsrcs; + sub_rsrc_data = NULL; + +exit: + free(sub_rsrc_data); + return hr; +} diff --git a/dlls/d3dx9_36/d3dx_helpers.h b/dlls/d3dx9_36/d3dx_helpers.h index 83c213db311..aadbb2a9ea6 100644 --- a/dlls/d3dx9_36/d3dx_helpers.h +++ b/dlls/d3dx9_36/d3dx_helpers.h @@ -404,6 +404,8 @@ void format_from_d3dx_color(const struct pixel_format_desc *format, const struct
enum d3dx_pixel_format_id d3dx_pixel_format_id_from_dxgi_format(uint32_t format); void d3dx_get_next_mip_level_size(struct volume *size); +void d3dx_get_mip_level_size(struct volume *size, uint32_t level); +uint32_t d3dx_get_max_mip_levels_for_size(uint32_t width, uint32_t height, uint32_t depth); HRESULT d3dx_calculate_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, uint32_t *pitch, uint32_t *size); uint32_t d3dx_calculate_layer_pixels_size(enum d3dx_pixel_format_id format, uint32_t width, uint32_t height, @@ -438,6 +440,21 @@ struct d3dx_buffer_wrapper HRESULT d3dx_save_pixels_to_memory(struct d3dx_pixels *src_pixels, const struct pixel_format_desc *src_fmt_desc, enum d3dx_image_file_format file_format, const struct d3dx_buffer_wrapper *wrapper, struct d3dx_buffer *dst_buffer);
+/* + * Structure that is able to be cast to D3D10_SUBRESOURCE_DATA and + * D3D11_SUBRESOURCE_DATA. + */ +struct d3dx_subresource_data +{ + const void *data; + UINT row_pitch; + UINT slice_pitch; +}; + +HRESULT d3dx_create_subresource_data_for_texture(uint32_t width, uint32_t height, uint32_t depth, + uint32_t mip_levels, uint32_t layer_count, const struct pixel_format_desc *fmt_desc, + struct d3dx_subresource_data **out_sub_rsrc_data); + /* debug helpers */ const char *debug_d3dx_image_file_format(enum d3dx_image_file_format format); #endif /* __WINE_D3DX_HELPERS_H */
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 2 +- dlls/d3dx10_43/texture.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 486e77ca549..56897730f6c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -4289,7 +4289,7 @@ static void test_create_texture(void) for (mip_level = 0; mip_level < 4; ++mip_level) { winetest_push_context("MipLevel %u", mip_level); - todo_wine_if(i && mip_level != 3) check_texture_sub_resource_u32(tex_2d, mip_level, NULL, + check_texture_sub_resource_u32(tex_2d, mip_level, NULL, dds_24bit_8_8_mip_level_expected[min(3, mip_level + i)]); winetest_pop_context(); } diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 1c9f303929a..0b71556f870 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -648,8 +648,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO if (!data || !size) return E_FAIL;
- if (load_info->FirstMipLevel != D3DX10_DEFAULT) - FIXME("load_info->FirstMipLevel is ignored.\n"); if (load_info->Usage != D3DX10_DEFAULT) FIXME("load_info->Usage is ignored.\n"); if (load_info->BindFlags != D3DX10_DEFAULT) @@ -688,6 +686,9 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end; }
+ if (load_info->FirstMipLevel == D3DX10_DEFAULT || (load_info->FirstMipLevel >= img_info.MipLevels)) + load_info->FirstMipLevel = 0; + if (load_info->Format == D3DX10_DEFAULT || load_info->Format == DXGI_FORMAT_FROM_FILE) load_info->Format = img_info.Format; fmt_desc = get_d3dx_pixel_format_info(d3dx_pixel_format_id_from_dxgi_format(load_info->Format)); @@ -724,7 +725,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO goto end;
src_desc = get_d3dx_pixel_format_info(image.format); - loaded_mip_levels = min(img_info.MipLevels, load_info->MipLevels); + loaded_mip_levels = min((img_info.MipLevels - load_info->FirstMipLevel), load_info->MipLevels); for (i = 0; i < img_info.ArraySize; ++i) { struct volume dst_size = { load_info->Width, load_info->Height, load_info->Depth }; @@ -735,7 +736,7 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO const RECT unaligned_rect = { 0, 0, dst_size.width, dst_size.height }; struct d3dx_pixels src_pixels, dst_pixels;
- hr = d3dx_image_get_pixels(&image, i, j, &src_pixels); + hr = d3dx_image_get_pixels(&image, i, j + load_info->FirstMipLevel, &src_pixels); if (FAILED(hr)) goto end;
From: Connor McAdams cmcadams@codeweavers.com
Signed-off-by: Connor McAdams cmcadams@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 10 +++++----- dlls/d3dx10_43/texture.c | 21 ++++++++------------- 2 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 56897730f6c..238aebc060e 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -1042,7 +1042,7 @@ static const struct test_image_load_info (D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET), 0, (D3D10_RESOURCE_MISC_GENERATE_MIPS | D3D10_RESOURCE_MISC_TEXTURECUBE) } - }, .todo_resource_desc = TRUE, + } }, /* * Pass in different dimensions and texture format than the source image. @@ -1126,7 +1126,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_CPU_ACCESS_READ, D3D10_USAGE_DYNAMIC, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, - E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + E_INVALIDARG, S_OK, E_INVALIDARG }, /* 5. */ { @@ -1135,7 +1135,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, D3D10_BIND_DEPTH_STENCIL, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, - E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + E_INVALIDARG, S_OK, E_INVALIDARG }, /* * D3D10_RESOURCE_MISC_GENERATE_MIPS requires binding as a shader resource @@ -1147,7 +1147,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_GENERATE_MIPS, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, - E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + E_INVALIDARG, S_OK, E_INVALIDARG }, /* Can't set the cube texture flag if the image isn't a cube texture. */ { @@ -1156,7 +1156,7 @@ static const struct test_invalid_image_load_info D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_USAGE_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT, D3D10_RESOURCE_MISC_TEXTURECUBE, D3DX10_DEFAULT, D3DX10_DEFAULT, D3DX10_DEFAULT }, - E_INVALIDARG, S_OK, E_INVALIDARG, .todo_hr = TRUE, .todo_create_device_object_hr = TRUE, + E_INVALIDARG, S_OK, E_INVALIDARG }, };
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 0b71556f870..e63dcb92c5d 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -648,15 +648,6 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO if (!data || !size) return E_FAIL;
- if (load_info->Usage != D3DX10_DEFAULT) - FIXME("load_info->Usage is ignored.\n"); - if (load_info->BindFlags != D3DX10_DEFAULT) - FIXME("load_info->BindFlags is ignored.\n"); - if (load_info->CpuAccessFlags != D3DX10_DEFAULT) - FIXME("load_info->CpuAccessFlags is ignored.\n"); - if (load_info->MiscFlags != D3DX10_DEFAULT) - FIXME("load_info->MiscFlags is ignored.\n"); - *resource_data = NULL; if (!load_info->Filter || load_info->Filter == D3DX10_DEFAULT) load_info->Filter = D3DX10_FILTER_LINEAR; @@ -797,9 +788,11 @@ HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *resource_data = (D3D10_SUBRESOURCE_DATA *)sub_rsrcs; sub_rsrcs = NULL;
- load_info->Usage = D3D10_USAGE_DEFAULT; - load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; - load_info->MiscFlags = img_info.MiscFlags; + load_info->Usage = (load_info->Usage == D3DX10_DEFAULT) ? D3D10_USAGE_DEFAULT : load_info->Usage; + load_info->BindFlags = (load_info->BindFlags == D3DX10_DEFAULT) ? D3D10_BIND_SHADER_RESOURCE : load_info->BindFlags; + load_info->CpuAccessFlags = (load_info->CpuAccessFlags == D3DX10_DEFAULT) ? 0 : load_info->CpuAccessFlags; + load_info->MiscFlags = (load_info->MiscFlags == D3DX10_DEFAULT) ? 0 : load_info->MiscFlags; + load_info->MiscFlags |= img_info.MiscFlags; /* * Must be present in order to get resource dimension for texture * creation. @@ -829,11 +822,12 @@ HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_in texture_2d_desc.Width = load_info->Width; texture_2d_desc.Height = load_info->Height; texture_2d_desc.MipLevels = load_info->MipLevels; - texture_2d_desc.ArraySize = load_info->MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE ? 6 : 1; + texture_2d_desc.ArraySize = load_info->pSrcInfo->ArraySize; texture_2d_desc.Format = load_info->Format; texture_2d_desc.SampleDesc.Count = 1; texture_2d_desc.Usage = load_info->Usage; texture_2d_desc.BindFlags = load_info->BindFlags; + texture_2d_desc.CPUAccessFlags = load_info->CpuAccessFlags; texture_2d_desc.MiscFlags = load_info->MiscFlags;
if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, resource_data, &texture_2d))) @@ -854,6 +848,7 @@ HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_in texture_3d_desc.Format = load_info->Format; texture_3d_desc.Usage = load_info->Usage; texture_3d_desc.BindFlags = load_info->BindFlags; + texture_3d_desc.CPUAccessFlags = load_info->CpuAccessFlags; texture_3d_desc.MiscFlags = load_info->MiscFlags;
if (FAILED(hr = ID3D10Device_CreateTexture3D(device, &texture_3d_desc, resource_data, &texture_3d)))