2 * Copyright 2020 Ziqing Hui for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "wine/debug.h"
26 #include "dxhelpers.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
30 HRESULT WINAPI
WICCreateImagingFactory_Proxy(UINT sdk_version
, IWICImagingFactory
**imaging_factory
);
34 const GUID
*wic_container_guid
;
35 D3DX10_IMAGE_FILE_FORMAT d3dx_file_format
;
39 { &GUID_ContainerFormatBmp
, D3DX10_IFF_BMP
},
40 { &GUID_ContainerFormatJpeg
, D3DX10_IFF_JPG
},
41 { &GUID_ContainerFormatPng
, D3DX10_IFF_PNG
},
42 { &GUID_ContainerFormatDds
, D3DX10_IFF_DDS
},
43 { &GUID_ContainerFormatTiff
, D3DX10_IFF_TIFF
},
44 { &GUID_ContainerFormatGif
, D3DX10_IFF_GIF
},
45 { &GUID_ContainerFormatWmp
, D3DX10_IFF_WMP
},
51 DXGI_FORMAT dxgi_format
;
55 { &GUID_WICPixelFormatBlackWhite
, DXGI_FORMAT_R1_UNORM
},
56 { &GUID_WICPixelFormat8bppAlpha
, DXGI_FORMAT_A8_UNORM
},
57 { &GUID_WICPixelFormat8bppGray
, DXGI_FORMAT_R8_UNORM
},
58 { &GUID_WICPixelFormat16bppGray
, DXGI_FORMAT_R16_UNORM
},
59 { &GUID_WICPixelFormat16bppGrayHalf
, DXGI_FORMAT_R16_FLOAT
},
60 { &GUID_WICPixelFormat32bppGrayFloat
, DXGI_FORMAT_R32_FLOAT
},
61 { &GUID_WICPixelFormat16bppBGR565
, DXGI_FORMAT_B5G6R5_UNORM
},
62 { &GUID_WICPixelFormat16bppBGRA5551
, DXGI_FORMAT_B5G5R5A1_UNORM
},
63 { &GUID_WICPixelFormat32bppBGR
, DXGI_FORMAT_B8G8R8X8_UNORM
},
64 { &GUID_WICPixelFormat32bppBGRA
, DXGI_FORMAT_B8G8R8A8_UNORM
},
65 { &GUID_WICPixelFormat32bppRGBA
, DXGI_FORMAT_R8G8B8A8_UNORM
},
66 { &GUID_WICPixelFormat32bppRGBA1010102
, DXGI_FORMAT_R10G10B10A2_UNORM
},
67 { &GUID_WICPixelFormat32bppRGBA1010102XR
, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
},
68 { &GUID_WICPixelFormat64bppRGBA
, DXGI_FORMAT_R16G16B16A16_UNORM
},
69 { &GUID_WICPixelFormat64bppRGBAHalf
, DXGI_FORMAT_R16G16B16A16_FLOAT
},
70 { &GUID_WICPixelFormat96bppRGBFloat
, DXGI_FORMAT_R32G32B32_FLOAT
},
71 { &GUID_WICPixelFormat128bppRGBAFloat
, DXGI_FORMAT_R32G32B32A32_FLOAT
}
74 static D3DX10_IMAGE_FILE_FORMAT
wic_container_guid_to_file_format(GUID
*container_format
)
78 for (i
= 0; i
< ARRAY_SIZE(file_formats
); ++i
)
80 if (IsEqualGUID(file_formats
[i
].wic_container_guid
, container_format
))
81 return file_formats
[i
].d3dx_file_format
;
83 return D3DX10_IFF_FORCE_DWORD
;
86 static const GUID
*dxgi_format_to_wic_guid(DXGI_FORMAT format
)
90 for (i
= 0; i
< ARRAY_SIZE(wic_pixel_formats
); ++i
)
92 if (wic_pixel_formats
[i
].dxgi_format
== format
)
93 return wic_pixel_formats
[i
].wic_guid
;
99 static D3D10_RESOURCE_DIMENSION
wic_dimension_to_d3dx10_dimension(WICDdsDimension wic_dimension
)
101 switch (wic_dimension
)
103 case WICDdsTexture1D
:
104 return D3D10_RESOURCE_DIMENSION_TEXTURE1D
;
105 case WICDdsTexture2D
:
106 case WICDdsTextureCube
:
107 return D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
108 case WICDdsTexture3D
:
109 return D3D10_RESOURCE_DIMENSION_TEXTURE3D
;
111 return D3D10_RESOURCE_DIMENSION_UNKNOWN
;
115 static unsigned int get_bpp_from_format(DXGI_FORMAT format
)
119 case DXGI_FORMAT_R32G32B32A32_TYPELESS
:
120 case DXGI_FORMAT_R32G32B32A32_FLOAT
:
121 case DXGI_FORMAT_R32G32B32A32_UINT
:
122 case DXGI_FORMAT_R32G32B32A32_SINT
:
124 case DXGI_FORMAT_R32G32B32_TYPELESS
:
125 case DXGI_FORMAT_R32G32B32_FLOAT
:
126 case DXGI_FORMAT_R32G32B32_UINT
:
127 case DXGI_FORMAT_R32G32B32_SINT
:
129 case DXGI_FORMAT_R16G16B16A16_TYPELESS
:
130 case DXGI_FORMAT_R16G16B16A16_FLOAT
:
131 case DXGI_FORMAT_R16G16B16A16_UNORM
:
132 case DXGI_FORMAT_R16G16B16A16_UINT
:
133 case DXGI_FORMAT_R16G16B16A16_SNORM
:
134 case DXGI_FORMAT_R16G16B16A16_SINT
:
135 case DXGI_FORMAT_R32G32_TYPELESS
:
136 case DXGI_FORMAT_R32G32_FLOAT
:
137 case DXGI_FORMAT_R32G32_UINT
:
138 case DXGI_FORMAT_R32G32_SINT
:
139 case DXGI_FORMAT_R32G8X24_TYPELESS
:
140 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT
:
141 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS
:
142 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT
:
143 case DXGI_FORMAT_Y416
:
144 case DXGI_FORMAT_Y210
:
145 case DXGI_FORMAT_Y216
:
147 case DXGI_FORMAT_R10G10B10A2_TYPELESS
:
148 case DXGI_FORMAT_R10G10B10A2_UNORM
:
149 case DXGI_FORMAT_R10G10B10A2_UINT
:
150 case DXGI_FORMAT_R11G11B10_FLOAT
:
151 case DXGI_FORMAT_R8G8B8A8_TYPELESS
:
152 case DXGI_FORMAT_R8G8B8A8_UNORM
:
153 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
:
154 case DXGI_FORMAT_R8G8B8A8_UINT
:
155 case DXGI_FORMAT_R8G8B8A8_SNORM
:
156 case DXGI_FORMAT_R8G8B8A8_SINT
:
157 case DXGI_FORMAT_R16G16_TYPELESS
:
158 case DXGI_FORMAT_R16G16_FLOAT
:
159 case DXGI_FORMAT_R16G16_UNORM
:
160 case DXGI_FORMAT_R16G16_UINT
:
161 case DXGI_FORMAT_R16G16_SNORM
:
162 case DXGI_FORMAT_R16G16_SINT
:
163 case DXGI_FORMAT_R32_TYPELESS
:
164 case DXGI_FORMAT_D32_FLOAT
:
165 case DXGI_FORMAT_R32_FLOAT
:
166 case DXGI_FORMAT_R32_UINT
:
167 case DXGI_FORMAT_R32_SINT
:
168 case DXGI_FORMAT_R24G8_TYPELESS
:
169 case DXGI_FORMAT_D24_UNORM_S8_UINT
:
170 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS
:
171 case DXGI_FORMAT_X24_TYPELESS_G8_UINT
:
172 case DXGI_FORMAT_R9G9B9E5_SHAREDEXP
:
173 case DXGI_FORMAT_R8G8_B8G8_UNORM
:
174 case DXGI_FORMAT_G8R8_G8B8_UNORM
:
175 case DXGI_FORMAT_B8G8R8A8_UNORM
:
176 case DXGI_FORMAT_B8G8R8X8_UNORM
:
177 case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM
:
178 case DXGI_FORMAT_B8G8R8A8_TYPELESS
:
179 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
:
180 case DXGI_FORMAT_B8G8R8X8_TYPELESS
:
181 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB
:
182 case DXGI_FORMAT_AYUV
:
183 case DXGI_FORMAT_Y410
:
184 case DXGI_FORMAT_YUY2
:
186 case DXGI_FORMAT_P010
:
187 case DXGI_FORMAT_P016
:
189 case DXGI_FORMAT_R8G8_TYPELESS
:
190 case DXGI_FORMAT_R8G8_UNORM
:
191 case DXGI_FORMAT_R8G8_UINT
:
192 case DXGI_FORMAT_R8G8_SNORM
:
193 case DXGI_FORMAT_R8G8_SINT
:
194 case DXGI_FORMAT_R16_TYPELESS
:
195 case DXGI_FORMAT_R16_FLOAT
:
196 case DXGI_FORMAT_D16_UNORM
:
197 case DXGI_FORMAT_R16_UNORM
:
198 case DXGI_FORMAT_R16_UINT
:
199 case DXGI_FORMAT_R16_SNORM
:
200 case DXGI_FORMAT_R16_SINT
:
201 case DXGI_FORMAT_B5G6R5_UNORM
:
202 case DXGI_FORMAT_B5G5R5A1_UNORM
:
203 case DXGI_FORMAT_A8P8
:
204 case DXGI_FORMAT_B4G4R4A4_UNORM
:
206 case DXGI_FORMAT_NV12
:
207 case DXGI_FORMAT_420_OPAQUE
:
208 case DXGI_FORMAT_NV11
:
210 case DXGI_FORMAT_R8_TYPELESS
:
211 case DXGI_FORMAT_R8_UNORM
:
212 case DXGI_FORMAT_R8_UINT
:
213 case DXGI_FORMAT_R8_SNORM
:
214 case DXGI_FORMAT_R8_SINT
:
215 case DXGI_FORMAT_A8_UNORM
:
216 case DXGI_FORMAT_AI44
:
217 case DXGI_FORMAT_IA44
:
219 case DXGI_FORMAT_BC2_TYPELESS
:
220 case DXGI_FORMAT_BC2_UNORM
:
221 case DXGI_FORMAT_BC2_UNORM_SRGB
:
222 case DXGI_FORMAT_BC3_TYPELESS
:
223 case DXGI_FORMAT_BC3_UNORM
:
224 case DXGI_FORMAT_BC3_UNORM_SRGB
:
225 case DXGI_FORMAT_BC5_TYPELESS
:
226 case DXGI_FORMAT_BC5_UNORM
:
227 case DXGI_FORMAT_BC5_SNORM
:
228 case DXGI_FORMAT_BC6H_TYPELESS
:
229 case DXGI_FORMAT_BC6H_UF16
:
230 case DXGI_FORMAT_BC6H_SF16
:
231 case DXGI_FORMAT_BC7_TYPELESS
:
232 case DXGI_FORMAT_BC7_UNORM
:
233 case DXGI_FORMAT_BC7_UNORM_SRGB
:
235 case DXGI_FORMAT_BC1_TYPELESS
:
236 case DXGI_FORMAT_BC1_UNORM
:
237 case DXGI_FORMAT_BC1_UNORM_SRGB
:
238 case DXGI_FORMAT_BC4_TYPELESS
:
239 case DXGI_FORMAT_BC4_UNORM
:
240 case DXGI_FORMAT_BC4_SNORM
:
242 case DXGI_FORMAT_R1_UNORM
:
249 static DXGI_FORMAT
get_d3dx10_dds_format(DXGI_FORMAT format
)
258 {DXGI_FORMAT_UNKNOWN
, DXGI_FORMAT_R8G8B8A8_UNORM
},
259 {DXGI_FORMAT_R8_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
260 {DXGI_FORMAT_R8G8_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
261 {DXGI_FORMAT_B5G6R5_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
262 {DXGI_FORMAT_B4G4R4A4_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
263 {DXGI_FORMAT_B5G5R5A1_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
264 {DXGI_FORMAT_B8G8R8X8_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
265 {DXGI_FORMAT_B8G8R8A8_UNORM
, DXGI_FORMAT_R8G8B8A8_UNORM
},
266 {DXGI_FORMAT_R16_UNORM
, DXGI_FORMAT_R16G16B16A16_UNORM
},
271 for (i
= 0; i
< ARRAY_SIZE(format_map
); ++i
)
273 if (format
== format_map
[i
].src
)
274 return format_map
[i
].dst
;
279 HRESULT WINAPI
D3DX10GetImageInfoFromFileA(const char *src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
286 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_a(src_file
), pump
, info
, result
);
291 str_len
= MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, NULL
, 0);
293 return HRESULT_FROM_WIN32(GetLastError());
295 buffer
= malloc(str_len
* sizeof(*buffer
));
297 return E_OUTOFMEMORY
;
299 MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, buffer
, str_len
);
300 hr
= D3DX10GetImageInfoFromFileW(buffer
, pump
, info
, result
);
307 HRESULT WINAPI
D3DX10GetImageInfoFromFileW(const WCHAR
*src_file
, ID3DX10ThreadPump
*pump
, D3DX10_IMAGE_INFO
*info
,
314 TRACE("src_file %s, pump %p, info %p, result %p.\n", debugstr_w(src_file
), pump
, info
, result
);
321 ID3DX10DataProcessor
*processor
;
322 ID3DX10DataLoader
*loader
;
324 if (FAILED((hr
= D3DX10CreateAsyncFileLoaderW(src_file
, &loader
))))
326 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
328 ID3DX10DataLoader_Destroy(loader
);
331 hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
);
334 ID3DX10DataLoader_Destroy(loader
);
335 ID3DX10DataProcessor_Destroy(processor
);
340 if (SUCCEEDED((hr
= load_file(src_file
, &buffer
, &size
))))
342 hr
= get_image_info(buffer
, size
, info
);
350 HRESULT WINAPI
D3DX10GetImageInfoFromResourceA(HMODULE module
, const char *resource
, ID3DX10ThreadPump
*pump
,
351 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
357 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
358 module
, debugstr_a(resource
), pump
, info
, result
);
362 ID3DX10DataProcessor
*processor
;
363 ID3DX10DataLoader
*loader
;
365 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderA(module
, resource
, &loader
))))
367 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
369 ID3DX10DataLoader_Destroy(loader
);
372 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
374 ID3DX10DataLoader_Destroy(loader
);
375 ID3DX10DataProcessor_Destroy(processor
);
380 if (FAILED((hr
= load_resourceA(module
, resource
, &buffer
, &size
))))
382 hr
= get_image_info(buffer
, size
, info
);
388 HRESULT WINAPI
D3DX10GetImageInfoFromResourceW(HMODULE module
, const WCHAR
*resource
, ID3DX10ThreadPump
*pump
,
389 D3DX10_IMAGE_INFO
*info
, HRESULT
*result
)
395 TRACE("module %p, resource %s, pump %p, info %p, result %p.\n",
396 module
, debugstr_w(resource
), pump
, info
, result
);
400 ID3DX10DataProcessor
*processor
;
401 ID3DX10DataLoader
*loader
;
403 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderW(module
, resource
, &loader
))))
405 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(info
, &processor
))))
407 ID3DX10DataLoader_Destroy(loader
);
410 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
412 ID3DX10DataLoader_Destroy(loader
);
413 ID3DX10DataProcessor_Destroy(processor
);
418 if (FAILED((hr
= load_resourceW(module
, resource
, &buffer
, &size
))))
420 hr
= get_image_info(buffer
, size
, info
);
426 HRESULT
get_image_info(const void *data
, SIZE_T size
, D3DX10_IMAGE_INFO
*img_info
)
428 IWICBitmapFrameDecode
*frame
= NULL
;
429 IWICImagingFactory
*factory
= NULL
;
430 IWICDdsDecoder
*dds_decoder
= NULL
;
431 IWICBitmapDecoder
*decoder
= NULL
;
432 WICDdsParameters dds_params
;
433 IWICStream
*stream
= NULL
;
434 unsigned int frame_count
;
435 GUID container_format
;
438 WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION
, &factory
);
439 IWICImagingFactory_CreateStream(factory
, &stream
);
440 hr
= IWICStream_InitializeFromMemory(stream
, (BYTE
*)data
, size
);
443 WARN("Failed to initialize stream.\n");
446 hr
= IWICImagingFactory_CreateDecoderFromStream(factory
, (IStream
*)stream
, NULL
, 0, &decoder
);
450 hr
= IWICBitmapDecoder_GetContainerFormat(decoder
, &container_format
);
453 img_info
->ImageFileFormat
= wic_container_guid_to_file_format(&container_format
);
454 if (img_info
->ImageFileFormat
== D3DX10_IFF_FORCE_DWORD
)
457 WARN("Unsupported image file format %s.\n", debugstr_guid(&container_format
));
461 hr
= IWICBitmapDecoder_GetFrameCount(decoder
, &frame_count
);
462 if (FAILED(hr
) || !frame_count
)
464 hr
= IWICBitmapDecoder_GetFrame(decoder
, 0, &frame
);
467 hr
= IWICBitmapFrameDecode_GetSize(frame
, &img_info
->Width
, &img_info
->Height
);
471 if (img_info
->ImageFileFormat
== D3DX10_IFF_DDS
)
473 hr
= IWICBitmapDecoder_QueryInterface(decoder
, &IID_IWICDdsDecoder
, (void **)&dds_decoder
);
476 hr
= IWICDdsDecoder_GetParameters(dds_decoder
, &dds_params
);
479 img_info
->ArraySize
= dds_params
.ArraySize
;
480 img_info
->Depth
= dds_params
.Depth
;
481 img_info
->MipLevels
= dds_params
.MipLevels
;
482 img_info
->ResourceDimension
= wic_dimension_to_d3dx10_dimension(dds_params
.Dimension
);
483 img_info
->Format
= get_d3dx10_dds_format(dds_params
.DxgiFormat
);
484 img_info
->MiscFlags
= 0;
485 if (dds_params
.Dimension
== WICDdsTextureCube
)
487 img_info
->MiscFlags
= D3D10_RESOURCE_MISC_TEXTURECUBE
;
488 img_info
->ArraySize
*= 6;
493 img_info
->ArraySize
= 1;
495 img_info
->MipLevels
= 1;
496 img_info
->ResourceDimension
= D3D10_RESOURCE_DIMENSION_TEXTURE2D
;
497 img_info
->Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
498 img_info
->MiscFlags
= 0;
503 IWICDdsDecoder_Release(dds_decoder
);
505 IWICBitmapFrameDecode_Release(frame
);
507 IWICBitmapDecoder_Release(decoder
);
509 IWICStream_Release(stream
);
511 IWICImagingFactory_Release(factory
);
515 WARN("Invalid or unsupported image file.\n");
521 HRESULT WINAPI
D3DX10GetImageInfoFromMemory(const void *src_data
, SIZE_T src_data_size
, ID3DX10ThreadPump
*pump
,
522 D3DX10_IMAGE_INFO
*img_info
, HRESULT
*result
)
526 TRACE("src_data %p, src_data_size %Iu, pump %p, img_info %p, hresult %p.\n",
527 src_data
, src_data_size
, pump
, img_info
, result
);
534 ID3DX10DataProcessor
*processor
;
535 ID3DX10DataLoader
*loader
;
537 if (FAILED((hr
= D3DX10CreateAsyncMemoryLoader(src_data
, src_data_size
, &loader
))))
539 if (FAILED((hr
= D3DX10CreateAsyncTextureInfoProcessor(img_info
, &processor
))))
541 ID3DX10DataLoader_Destroy(loader
);
544 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, result
, NULL
))))
546 ID3DX10DataLoader_Destroy(loader
);
547 ID3DX10DataProcessor_Destroy(processor
);
552 hr
= get_image_info(src_data
, src_data_size
, img_info
);
558 static HRESULT
create_texture(ID3D10Device
*device
, const void *data
, SIZE_T size
,
559 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3D10Resource
**texture
)
561 D3D10_SUBRESOURCE_DATA
*resource_data
;
562 D3DX10_IMAGE_LOAD_INFO load_info_copy
;
565 init_load_info(load_info
, &load_info_copy
);
567 if (FAILED((hr
= load_texture_data(data
, size
, &load_info_copy
, &resource_data
))))
569 hr
= create_d3d_texture(device
, &load_info_copy
, resource_data
, texture
);
574 HRESULT WINAPI
D3DX10CreateTextureFromFileA(ID3D10Device
*device
, const char *src_file
,
575 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
581 TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n",
582 device
, debugstr_a(src_file
), load_info
, pump
, texture
, hresult
);
589 if (!(str_len
= MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, NULL
, 0)))
590 return HRESULT_FROM_WIN32(GetLastError());
592 if (!(buffer
= malloc(str_len
* sizeof(*buffer
))))
593 return E_OUTOFMEMORY
;
595 MultiByteToWideChar(CP_ACP
, 0, src_file
, -1, buffer
, str_len
);
596 hr
= D3DX10CreateTextureFromFileW(device
, buffer
, load_info
, pump
, texture
, hresult
);
603 HRESULT WINAPI
D3DX10CreateTextureFromFileW(ID3D10Device
*device
, const WCHAR
*src_file
,
604 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
610 TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n",
611 device
, debugstr_w(src_file
), load_info
, pump
, texture
, hresult
);
620 ID3DX10DataProcessor
*processor
;
621 ID3DX10DataLoader
*loader
;
623 if (FAILED((hr
= D3DX10CreateAsyncFileLoaderW(src_file
, &loader
))))
625 if (FAILED((hr
= D3DX10CreateAsyncTextureProcessor(device
, load_info
, &processor
))))
627 ID3DX10DataLoader_Destroy(loader
);
630 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, hresult
, (void **)texture
))))
632 ID3DX10DataLoader_Destroy(loader
);
633 ID3DX10DataProcessor_Destroy(processor
);
638 if (SUCCEEDED((hr
= load_file(src_file
, &buffer
, &size
))))
640 hr
= create_texture(device
, buffer
, size
, load_info
, texture
);
648 HRESULT WINAPI
D3DX10CreateTextureFromResourceA(ID3D10Device
*device
, HMODULE module
, const char *resource
,
649 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
655 TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n",
656 device
, module
, debugstr_a(resource
), load_info
, pump
, texture
, hresult
);
663 ID3DX10DataProcessor
*processor
;
664 ID3DX10DataLoader
*loader
;
666 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderA(module
, resource
, &loader
))))
668 if (FAILED((hr
= D3DX10CreateAsyncTextureProcessor(device
, load_info
, &processor
))))
670 ID3DX10DataLoader_Destroy(loader
);
673 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, hresult
, (void **)texture
))))
675 ID3DX10DataLoader_Destroy(loader
);
676 ID3DX10DataProcessor_Destroy(processor
);
681 if (FAILED((hr
= load_resourceA(module
, resource
, &buffer
, &size
))))
683 hr
= create_texture(device
, buffer
, size
, load_info
, texture
);
689 HRESULT WINAPI
D3DX10CreateTextureFromResourceW(ID3D10Device
*device
, HMODULE module
, const WCHAR
*resource
,
690 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
696 TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n",
697 device
, module
, debugstr_w(resource
), load_info
, pump
, texture
, hresult
);
704 ID3DX10DataProcessor
*processor
;
705 ID3DX10DataLoader
*loader
;
707 if (FAILED((hr
= D3DX10CreateAsyncResourceLoaderW(module
, resource
, &loader
))))
709 if (FAILED((hr
= D3DX10CreateAsyncTextureProcessor(device
, load_info
, &processor
))))
711 ID3DX10DataLoader_Destroy(loader
);
714 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, hresult
, (void **)texture
))))
716 ID3DX10DataLoader_Destroy(loader
);
717 ID3DX10DataProcessor_Destroy(processor
);
722 if (FAILED((hr
= load_resourceW(module
, resource
, &buffer
, &size
))))
724 hr
= create_texture(device
, buffer
, size
, load_info
, texture
);
730 void init_load_info(const D3DX10_IMAGE_LOAD_INFO
*load_info
, D3DX10_IMAGE_LOAD_INFO
*out
)
738 out
->Width
= D3DX10_DEFAULT
;
739 out
->Height
= D3DX10_DEFAULT
;
740 out
->Depth
= D3DX10_DEFAULT
;
741 out
->FirstMipLevel
= D3DX10_DEFAULT
;
742 out
->MipLevels
= D3DX10_DEFAULT
;
743 out
->Usage
= D3DX10_DEFAULT
;
744 out
->BindFlags
= D3DX10_DEFAULT
;
745 out
->CpuAccessFlags
= D3DX10_DEFAULT
;
746 out
->MiscFlags
= D3DX10_DEFAULT
;
747 out
->Format
= D3DX10_DEFAULT
;
748 out
->Filter
= D3DX10_DEFAULT
;
749 out
->MipFilter
= D3DX10_DEFAULT
;
750 out
->pSrcInfo
= NULL
;
753 static HRESULT
dds_get_frame_info(IWICDdsFrameDecode
*frame
, const D3DX10_IMAGE_INFO
*img_info
,
754 WICDdsFormatInfo
*format_info
, unsigned int *stride
, unsigned int *frame_size
)
756 unsigned int width
, height
;
759 if (FAILED(hr
= IWICDdsFrameDecode_GetFormatInfo(frame
, format_info
)))
761 if (FAILED(hr
= IWICDdsFrameDecode_GetSizeInBlocks(frame
, &width
, &height
)))
764 if (img_info
->Format
== format_info
->DxgiFormat
)
766 *stride
= width
* format_info
->BytesPerBlock
;
767 *frame_size
= *stride
* height
;
771 width
*= format_info
->BlockWidth
;
772 height
*= format_info
->BlockHeight
;
773 *stride
= (width
* get_bpp_from_format(img_info
->Format
) + 7) / 8;
774 *frame_size
= *stride
* height
;
779 static HRESULT
convert_image(IWICImagingFactory
*factory
, IWICBitmapFrameDecode
*frame
,
780 const GUID
*dst_format
, unsigned int stride
, unsigned int frame_size
, BYTE
*buffer
)
782 IWICFormatConverter
*converter
;
787 if (FAILED(hr
= IWICBitmapFrameDecode_GetPixelFormat(frame
, &src_format
)))
790 if (IsEqualGUID(&src_format
, dst_format
))
792 if (FAILED(hr
= IWICBitmapFrameDecode_CopyPixels(frame
, NULL
, stride
, frame_size
, buffer
)))
797 if (FAILED(hr
= IWICImagingFactory_CreateFormatConverter(factory
, &converter
)))
799 if (FAILED(hr
= IWICFormatConverter_CanConvert(converter
, &src_format
, dst_format
, &can_convert
)))
801 IWICFormatConverter_Release(converter
);
806 WARN("Format converting %s to %s is not supported by WIC.\n",
807 debugstr_guid(&src_format
), debugstr_guid(dst_format
));
808 IWICFormatConverter_Release(converter
);
811 if (FAILED(hr
= IWICFormatConverter_Initialize(converter
, (IWICBitmapSource
*)frame
, dst_format
,
812 WICBitmapDitherTypeErrorDiffusion
, 0, 0, WICBitmapPaletteTypeCustom
)))
814 IWICFormatConverter_Release(converter
);
817 hr
= IWICFormatConverter_CopyPixels(converter
, NULL
, stride
, frame_size
, buffer
);
818 IWICFormatConverter_Release(converter
);
822 HRESULT
load_texture_data(const void *data
, SIZE_T size
, D3DX10_IMAGE_LOAD_INFO
*load_info
,
823 D3D10_SUBRESOURCE_DATA
**resource_data
)
825 unsigned int stride
, frame_size
, i
, j
;
826 IWICDdsFrameDecode
*dds_frame
= NULL
;
827 IWICBitmapFrameDecode
*frame
= NULL
;
828 IWICImagingFactory
*factory
= NULL
;
829 IWICDdsDecoder
*dds_decoder
= NULL
;
830 IWICBitmapDecoder
*decoder
= NULL
;
831 BYTE
*res_data
= NULL
, *buffer
;
832 D3DX10_IMAGE_INFO img_info
;
833 IWICStream
*stream
= NULL
;
834 const GUID
*dst_format
;
837 if (load_info
->Width
!= D3DX10_DEFAULT
)
838 FIXME("load_info->Width is ignored.\n");
839 if (load_info
->Height
!= D3DX10_DEFAULT
)
840 FIXME("load_info->Height is ignored.\n");
841 if (load_info
->Depth
!= D3DX10_DEFAULT
)
842 FIXME("load_info->Depth is ignored.\n");
843 if (load_info
->FirstMipLevel
!= D3DX10_DEFAULT
)
844 FIXME("load_info->FirstMipLevel is ignored.\n");
845 if (load_info
->MipLevels
!= D3DX10_DEFAULT
)
846 FIXME("load_info->MipLevels is ignored.\n");
847 if (load_info
->Usage
!= D3DX10_DEFAULT
)
848 FIXME("load_info->Usage is ignored.\n");
849 if (load_info
->BindFlags
!= D3DX10_DEFAULT
)
850 FIXME("load_info->BindFlags is ignored.\n");
851 if (load_info
->CpuAccessFlags
!= D3DX10_DEFAULT
)
852 FIXME("load_info->CpuAccessFlags is ignored.\n");
853 if (load_info
->MiscFlags
!= D3DX10_DEFAULT
)
854 FIXME("load_info->MiscFlags is ignored.\n");
855 if (load_info
->Format
!= D3DX10_DEFAULT
)
856 FIXME("load_info->Format is ignored.\n");
857 if (load_info
->Filter
!= D3DX10_DEFAULT
)
858 FIXME("load_info->Filter is ignored.\n");
859 if (load_info
->MipFilter
!= D3DX10_DEFAULT
)
860 FIXME("load_info->MipFilter is ignored.\n");
861 if (load_info
->pSrcInfo
)
862 FIXME("load_info->pSrcInfo is ignored.\n");
864 if (FAILED(D3DX10GetImageInfoFromMemory(data
, size
, NULL
, &img_info
, NULL
)))
866 if ((!(img_info
.MiscFlags
& D3D10_RESOURCE_MISC_TEXTURECUBE
) || img_info
.ArraySize
!= 6)
867 && img_info
.ArraySize
!= 1)
869 FIXME("img_info.ArraySize = %u not supported.\n", img_info
.ArraySize
);
874 if (FAILED(hr
= WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION
, &factory
)))
876 if (FAILED(hr
= IWICImagingFactory_CreateStream(factory
, &stream
)))
878 if (FAILED(hr
= IWICStream_InitializeFromMemory(stream
, (BYTE
*)data
, size
)))
880 if (FAILED(hr
= IWICImagingFactory_CreateDecoderFromStream(factory
, (IStream
*)stream
, NULL
, 0, &decoder
)))
883 if (img_info
.ImageFileFormat
== D3DX10_IFF_DDS
)
885 WICDdsFormatInfo format_info
;
888 if (FAILED(hr
= IWICBitmapDecoder_QueryInterface(decoder
, &IID_IWICDdsDecoder
, (void **)&dds_decoder
)))
891 for (i
= 0; i
< img_info
.ArraySize
; ++i
)
893 for (j
= 0; j
< img_info
.MipLevels
; ++j
)
895 if (FAILED(hr
= IWICDdsDecoder_GetFrame(dds_decoder
, i
, j
, 0, &frame
)))
897 if (FAILED(hr
= IWICBitmapFrameDecode_QueryInterface(frame
,
898 &IID_IWICDdsFrameDecode
, (void **)&dds_frame
)))
900 if (FAILED(hr
= dds_get_frame_info(dds_frame
, &img_info
, &format_info
, &stride
, &frame_size
)))
905 img_info
.Width
= (img_info
.Width
+ format_info
.BlockWidth
- 1) & ~(format_info
.BlockWidth
- 1);
906 img_info
.Height
= (img_info
.Height
+ format_info
.BlockHeight
- 1) & ~(format_info
.BlockHeight
- 1);
909 size
+= sizeof(**resource_data
) + frame_size
;
911 IWICDdsFrameDecode_Release(dds_frame
);
913 IWICBitmapFrameDecode_Release(frame
);
918 if (!(res_data
= malloc(size
)))
923 *resource_data
= (D3D10_SUBRESOURCE_DATA
*)res_data
;
926 for (i
= 0; i
< img_info
.ArraySize
; ++i
)
928 for (j
= 0; j
< img_info
.MipLevels
; ++j
)
930 if (FAILED(hr
= IWICDdsDecoder_GetFrame(dds_decoder
, i
, j
, 0, &frame
)))
932 if (FAILED(hr
= IWICBitmapFrameDecode_QueryInterface(frame
,
933 &IID_IWICDdsFrameDecode
, (void **)&dds_frame
)))
935 if (FAILED(hr
= dds_get_frame_info(dds_frame
, &img_info
, &format_info
, &stride
, &frame_size
)))
938 buffer
= res_data
+ sizeof(**resource_data
) * img_info
.ArraySize
* img_info
.MipLevels
+ size
;
941 if (img_info
.Format
== format_info
.DxgiFormat
)
943 if (FAILED(hr
= IWICDdsFrameDecode_CopyBlocks(dds_frame
, NULL
, stride
, frame_size
, buffer
)))
948 if (!(dst_format
= dxgi_format_to_wic_guid(img_info
.Format
)))
951 FIXME("Unsupported DXGI format %#x.\n", img_info
.Format
);
954 if (FAILED(hr
= convert_image(factory
, frame
, dst_format
, stride
, frame_size
, buffer
)))
958 IWICDdsFrameDecode_Release(dds_frame
);
960 IWICBitmapFrameDecode_Release(frame
);
963 (*resource_data
)[i
* img_info
.MipLevels
+ j
].pSysMem
= buffer
;
964 (*resource_data
)[i
* img_info
.MipLevels
+ j
].SysMemPitch
= stride
;
965 (*resource_data
)[i
* img_info
.MipLevels
+ j
].SysMemSlicePitch
= frame_size
;
971 if (FAILED(hr
= IWICBitmapDecoder_GetFrame(decoder
, 0, &frame
)))
974 stride
= (img_info
.Width
* get_bpp_from_format(img_info
.Format
) + 7) / 8;
975 frame_size
= stride
* img_info
.Height
;
977 if (!(res_data
= malloc(sizeof(**resource_data
) + frame_size
)))
982 buffer
= res_data
+ sizeof(**resource_data
);
984 if (!(dst_format
= dxgi_format_to_wic_guid(img_info
.Format
)))
987 FIXME("Unsupported DXGI format %#x.\n", img_info
.Format
);
990 if (FAILED(hr
= convert_image(factory
, frame
, dst_format
, stride
, frame_size
, buffer
)))
993 *resource_data
= (D3D10_SUBRESOURCE_DATA
*)res_data
;
994 (*resource_data
)->pSysMem
= buffer
;
995 (*resource_data
)->SysMemPitch
= stride
;
996 (*resource_data
)->SysMemSlicePitch
= frame_size
;
999 load_info
->Width
= img_info
.Width
;
1000 load_info
->Height
= img_info
.Height
;
1001 load_info
->MipLevels
= img_info
.MipLevels
;
1002 load_info
->Format
= img_info
.Format
;
1003 load_info
->Usage
= D3D10_USAGE_DEFAULT
;
1004 load_info
->BindFlags
= D3D10_BIND_SHADER_RESOURCE
;
1005 load_info
->MiscFlags
= img_info
.MiscFlags
;
1012 IWICDdsDecoder_Release(dds_decoder
);
1014 IWICDdsFrameDecode_Release(dds_frame
);
1017 IWICBitmapFrameDecode_Release(frame
);
1019 IWICBitmapDecoder_Release(decoder
);
1021 IWICStream_Release(stream
);
1023 IWICImagingFactory_Release(factory
);
1027 HRESULT
create_d3d_texture(ID3D10Device
*device
, D3DX10_IMAGE_LOAD_INFO
*load_info
,
1028 D3D10_SUBRESOURCE_DATA
*resource_data
, ID3D10Resource
**texture
)
1030 D3D10_TEXTURE2D_DESC texture_2d_desc
;
1031 ID3D10Texture2D
*texture_2d
;
1034 memset(&texture_2d_desc
, 0, sizeof(texture_2d_desc
));
1035 texture_2d_desc
.Width
= load_info
->Width
;
1036 texture_2d_desc
.Height
= load_info
->Height
;
1037 texture_2d_desc
.MipLevels
= load_info
->MipLevels
;
1038 texture_2d_desc
.ArraySize
= load_info
->MiscFlags
& D3D10_RESOURCE_MISC_TEXTURECUBE
? 6 : 1;
1039 texture_2d_desc
.Format
= load_info
->Format
;
1040 texture_2d_desc
.SampleDesc
.Count
= 1;
1041 texture_2d_desc
.Usage
= load_info
->Usage
;
1042 texture_2d_desc
.BindFlags
= load_info
->BindFlags
;
1043 texture_2d_desc
.MiscFlags
= load_info
->MiscFlags
;
1045 if (FAILED(hr
= ID3D10Device_CreateTexture2D(device
, &texture_2d_desc
, resource_data
, &texture_2d
)))
1048 *texture
= (ID3D10Resource
*)texture_2d
;
1052 HRESULT WINAPI
D3DX10CreateTextureFromMemory(ID3D10Device
*device
, const void *src_data
, SIZE_T src_data_size
,
1053 D3DX10_IMAGE_LOAD_INFO
*load_info
, ID3DX10ThreadPump
*pump
, ID3D10Resource
**texture
, HRESULT
*hresult
)
1057 TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n",
1058 device
, src_data
, src_data_size
, load_info
, pump
, texture
, hresult
);
1061 return E_INVALIDARG
;
1067 ID3DX10DataProcessor
*processor
;
1068 ID3DX10DataLoader
*loader
;
1070 if (FAILED((hr
= D3DX10CreateAsyncMemoryLoader(src_data
, src_data_size
, &loader
))))
1072 if (FAILED((hr
= D3DX10CreateAsyncTextureProcessor(device
, load_info
, &processor
))))
1074 ID3DX10DataLoader_Destroy(loader
);
1077 if (FAILED((hr
= ID3DX10ThreadPump_AddWorkItem(pump
, loader
, processor
, hresult
, (void **)texture
))))
1079 ID3DX10DataLoader_Destroy(loader
);
1080 ID3DX10DataProcessor_Destroy(processor
);
1085 hr
= create_texture(device
, src_data
, src_data_size
, load_info
, texture
);