- support HRESULT parameter in D3DX10CreateTextureFrom* - implement D3DX10CreateAsyncTextureProcessor
-- v3: d3dx10/tests: Add D3DX10CreateAsyncTextureProcessor tests. d3dx10: Add D3DX10CreateAsyncTextureProcessor implementation. d3dx10: Add D3DX10CreateAsyncTextureProcessor stub. d3dx10: Exit early on volume textures in D3DX10CreateTextureFromMemory. d3dx10/tests: Add D3DX10CreateTextureFromMemory HRESULT argument tests. d3dx10: Don't ignore HRESULT parameter in D3DX10CreateTextureFromMemory.
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 5 +++++ dlls/d3dx10_43/texture.c | 32 +++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 0c6c4e5c8ce..560bc7a8f17 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2172,6 +2172,11 @@ static void test_create_texture(void)
/* D3DX10CreateTextureFromMemory tests */
+ resource = (ID3D10Resource *)0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(NULL, test_bmp_1bpp, sizeof(test_bmp_1bpp), NULL, NULL, &resource, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource); + resource = (ID3D10Resource *)0xdeadbeef; hr = D3DX10CreateTextureFromMemory(device, NULL, 0, NULL, NULL, &resource, NULL); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index 9c7762bc617..d5066b9793b 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -581,7 +581,9 @@ HRESULT WINAPI D3DX10CreateTextureFromFileA(ID3D10Device *device, const char *sr TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n", device, debugstr_a(src_file), load_info, pump, texture, hresult);
- if (!src_file || !texture) + if (!device) + return E_INVALIDARG; + if (!src_file) return E_FAIL;
if (!(str_len = MultiByteToWideChar(CP_ACP, 0, src_file, -1, NULL, 0))) @@ -608,11 +610,17 @@ HRESULT WINAPI D3DX10CreateTextureFromFileW(ID3D10Device *device, const WCHAR *s TRACE("device %p, src_file %s, load_info %p, pump %p, texture %p, hresult %p.\n", device, debugstr_w(src_file), load_info, pump, texture, hresult);
- if (!src_file || !texture) + if (!device) + return E_INVALIDARG; + if (!src_file) return E_FAIL;
if (FAILED((hr = load_file(src_file, &buffer, &size)))) + { + if (hresult) + *hresult = hr; return hr; + }
hr = D3DX10CreateTextureFromMemory(device, buffer, size, load_info, pump, texture, hresult);
@@ -631,8 +639,8 @@ HRESULT WINAPI D3DX10CreateTextureFromResourceA(ID3D10Device *device, HMODULE mo TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n", device, module, debugstr_a(resource), load_info, pump, texture, hresult);
- if (!resource || !texture) - return D3DX10_ERR_INVALID_DATA; + if (!device) + return E_INVALIDARG;
hr = load_resourceA(module, resource, &buffer, &size); if (FAILED(hr)) @@ -651,8 +659,8 @@ HRESULT WINAPI D3DX10CreateTextureFromResourceW(ID3D10Device *device, HMODULE mo TRACE("device %p, module %p, resource %s, load_info %p, pump %p, texture %p, hresult %p.\n", device, module, debugstr_w(resource), load_info, pump, texture, hresult);
- if (!resource || !texture) - return D3DX10_ERR_INVALID_DATA; + if (!device) + return E_INVALIDARG;
hr = load_resourceW(module, resource, &buffer, &size); if (FAILED(hr)) @@ -684,7 +692,9 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n", device, src_data, src_data_size, load_info, pump, texture, hresult);
- if (!src_data || !src_data_size || !texture) + if (!device) + return E_INVALIDARG; + if (!src_data) return E_FAIL; if (load_info) FIXME("load_info is ignored.\n"); @@ -692,10 +702,16 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s FIXME("Thread pump is not supported yet.\n");
if (FAILED(D3DX10GetImageInfoFromMemory(src_data, src_data_size, NULL, &img_info, NULL))) + { + if (hresult) + *hresult = E_FAIL; return E_FAIL; + } if (img_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) { FIXME("Cube map is not supported.\n"); + if (hresult) + *hresult = E_FAIL; return E_FAIL; }
@@ -807,5 +823,7 @@ end: if (factory) IWICImagingFactory_Release(factory);
+ if (hresult) + *hresult = hr; return hr; }
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 79 ++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 560bc7a8f17..026eaf0dbb6 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2158,8 +2158,8 @@ static void test_create_texture(void) HMODULE resource_module; ID3D10Device *device; WCHAR path[MAX_PATH]; + HRESULT hr, hr2; unsigned int i; - HRESULT hr;
device = create_device(); if (!device) @@ -2173,35 +2173,47 @@ static void test_create_texture(void) /* D3DX10CreateTextureFromMemory tests */
resource = (ID3D10Resource *)0xdeadbeef; - hr = D3DX10CreateTextureFromMemory(NULL, test_bmp_1bpp, sizeof(test_bmp_1bpp), NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(NULL, test_bmp_1bpp, sizeof(test_bmp_1bpp), NULL, NULL, &resource, &hr2); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef; - hr = D3DX10CreateTextureFromMemory(device, NULL, 0, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, NULL, 0, NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef; - hr = D3DX10CreateTextureFromMemory(device, NULL, sizeof(test_bmp_1bpp), NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, NULL, sizeof(test_bmp_1bpp), NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef; - hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, 0, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, 0, NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
resource = (ID3D10Resource *)0xdeadbeef; - hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, sizeof(test_bmp_1bpp) - 1, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test_bmp_1bpp, sizeof(test_bmp_1bpp) - 1, NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); ok(resource == (ID3D10Resource *)0xdeadbeef, "Got unexpected resource %p.\n", resource);
for (i = 0; i < ARRAY_SIZE(test_image); ++i) { winetest_push_context("Test %u", i);
- hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromMemory(device, test_image[i].data, test_image[i].size, NULL, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#x.\n", hr); @@ -2217,21 +2229,31 @@ static void test_create_texture(void)
/* D3DX10CreateTextureFromFile tests */
- hr = D3DX10CreateTextureFromFileW(device, NULL, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, NULL, NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromFileW(device, L"deadbeef", NULL, NULL, &resource, NULL); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, L"deadbeef", NULL, NULL, &resource, &hr2); ok(hr == D3D10_ERROR_FILE_NOT_FOUND, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromFileA(device, NULL, NULL, NULL, &resource, NULL); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileA(device, NULL, NULL, NULL, &resource, &hr2); ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromFileA(device, "deadbeef", NULL, NULL, &resource, NULL); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileA(device, "deadbeef", NULL, NULL, &resource, &hr2); ok(hr == D3D10_ERROR_FILE_NOT_FOUND, "Got unexpected hr %#x.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2);
for (i = 0; i < ARRAY_SIZE(test_image); ++i) { winetest_push_context("Test %u", i); create_file(test_filename, test_image[i].data, test_image[i].size, path);
- hr = D3DX10CreateTextureFromFileW(device, path, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileW(device, path, NULL, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#x.\n", hr); @@ -2242,7 +2264,9 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); }
- hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromFileA(device, get_str_a(path), NULL, NULL, &resource, &hr2); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#x.\n", hr); @@ -2259,25 +2283,40 @@ static void test_create_texture(void)
/* D3DX10CreateTextureFromResource tests */
- hr = D3DX10CreateTextureFromResourceW(device, NULL, NULL, NULL, NULL, &resource, NULL); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, NULL, NULL, NULL, NULL, &resource, &hr2); ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromResourceW(device, NULL, L"deadbeef", NULL, NULL, &resource, NULL); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, NULL, L"deadbeef", NULL, NULL, &resource, &hr2); ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromResourceA(device, NULL, NULL, NULL, NULL, &resource, NULL); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceA(device, NULL, NULL, NULL, NULL, &resource, &hr2); ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); - hr = D3DX10CreateTextureFromResourceA(device, NULL, "deadbeef", NULL, NULL, &resource, NULL); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceA(device, NULL, "deadbeef", NULL, NULL, &resource, &hr2); ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2);
for (i = 0; i < ARRAY_SIZE(test_image); ++i) { winetest_push_context("Test %u", i); resource_module = create_resource_module(test_resource_name, test_image[i].data, test_image[i].size);
+ hr2 = 0xdeadbeef; + hr = D3DX10CreateTextureFromResourceW(device, resource_module, L"deadbeef", NULL, NULL, &resource, &hr2); + ok(hr == D3DX10_ERR_INVALID_DATA, "Got unexpected hr %#x.\n", hr); + ok(hr2 == 0xdeadbeef, "Got unexpected hr2 %#x.\n", hr2); + + hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromResourceW(device, resource_module, - test_resource_name, NULL, NULL, &resource, NULL); + test_resource_name, NULL, NULL, &resource, &hr2); todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#x.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); if (hr == S_OK) { check_resource_info(resource, test_image + i, __LINE__); @@ -2285,11 +2324,13 @@ static void test_create_texture(void) ID3D10Resource_Release(resource); }
+ hr2 = 0xdeadbeef; hr = D3DX10CreateTextureFromResourceA(device, resource_module, - get_str_a(test_resource_name), NULL, NULL, &resource, NULL); + get_str_a(test_resource_name), NULL, NULL, &resource, &hr2); todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), "Got unexpected hr %#x.\n", hr); + ok(hr == hr2, "Got unexpected hr2 %#x.\n", hr2); if (hr == S_OK) { check_resource_info(resource, test_image + i, __LINE__);
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/texture.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index d5066b9793b..d3a4d9450b6 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -714,6 +714,13 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s *hresult = E_FAIL; return E_FAIL; } + if (img_info.ArraySize != 1) + { + FIXME("img_info.ArraySize = %d not supported.\n", img_info.ArraySize); + if (hresult) + *hresult = E_NOTIMPL; + return E_NOTIMPL; + }
if (FAILED(hr = WICCreateImagingFactory_Proxy(WINCODEC_SDK_VERSION, &factory))) goto end;
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/async.c | 7 +++++++ dlls/d3dx10_43/d3dx10_43.spec | 2 +- include/d3dx10async.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c index 0d75a64ff9e..cd41e405210 100644 --- a/dlls/d3dx10_43/async.c +++ b/dlls/d3dx10_43/async.c @@ -514,6 +514,13 @@ HRESULT WINAPI D3DX10CreateAsyncTextureInfoProcessor(D3DX10_IMAGE_INFO *info, ID return S_OK; }
+HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *device, + D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10DataProcessor **processor) +{ + FIXME("device %p, load_info %p, processor %p stub!\n", device, load_info, processor); + return E_NOTIMPL; +} + HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_size, const char *filename, const D3D10_SHADER_MACRO *defines, ID3DInclude *include, ID3DX10ThreadPump *pump, ID3D10Blob **shader_text, ID3D10Blob **errors, HRESULT *hresult) diff --git a/dlls/d3dx10_43/d3dx10_43.spec b/dlls/d3dx10_43/d3dx10_43.spec index c0a2c9fa56c..95160a067c5 100644 --- a/dlls/d3dx10_43/d3dx10_43.spec +++ b/dlls/d3dx10_43/d3dx10_43.spec @@ -17,7 +17,7 @@ @ stub D3DX10CreateAsyncShaderPreprocessProcessor(str ptr ptr ptr ptr ptr) @ stub D3DX10CreateAsyncShaderResourceViewProcessor(ptr ptr ptr) @ stdcall D3DX10CreateAsyncTextureInfoProcessor(ptr ptr) -@ stub D3DX10CreateAsyncTextureProcessor(ptr ptr ptr) +@ stdcall D3DX10CreateAsyncTextureProcessor(ptr ptr ptr) @ stdcall D3DX10CreateDevice(ptr long long long ptr) @ stdcall D3DX10CreateDeviceAndSwapChain(ptr long long long ptr ptr ptr) @ stdcall D3DX10CreateEffectFromFileA(str ptr ptr str long long ptr ptr ptr ptr ptr ptr) diff --git a/include/d3dx10async.h b/include/d3dx10async.h index c932be91b01..931458f4813 100644 --- a/include/d3dx10async.h +++ b/include/d3dx10async.h @@ -76,6 +76,8 @@ HRESULT WINAPI D3DX10CreateAsyncMemoryLoader(const void *data, SIZE_T datasize, HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE module, const char *resource, ID3DX10DataLoader **loader); HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *resource, ID3DX10DataLoader **loader);
+HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *device, + D3DX10_IMAGE_LOAD_INFO *info, ID3DX10DataProcessor **processor); HRESULT WINAPI D3DX10CreateAsyncTextureInfoProcessor(D3DX10_IMAGE_INFO *info, ID3DX10DataProcessor **processor);
#endif
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/async.c | 81 ++++++++++++++++- dlls/d3dx10_43/dxhelpers.h | 8 ++ dlls/d3dx10_43/texture.c | 176 +++++++++++++++++++++++++++---------- 3 files changed, 216 insertions(+), 49 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c index cd41e405210..bb1cf30a217 100644 --- a/dlls/d3dx10_43/async.c +++ b/dlls/d3dx10_43/async.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define COBJMACROS #include "d3d10_1.h" #include "d3dx10.h" #include "d3dcompiler.h" @@ -315,6 +316,66 @@ static ID3DX10DataProcessorVtbl texture_info_processor_vtbl = texture_info_processor_Destroy };
+struct texture_processor +{ + ID3DX10DataProcessor ID3DX10DataProcessor_iface; + ID3D10Device *device; + D3DX10_IMAGE_LOAD_INFO load_info; + D3D10_SUBRESOURCE_DATA *resource_data; +}; + +static inline struct texture_processor *texture_processor_from_ID3DX10DataProcessor(ID3DX10DataProcessor *iface) +{ + return CONTAINING_RECORD(iface, struct texture_processor, ID3DX10DataProcessor_iface); +} + +static HRESULT WINAPI texture_processor_Process(ID3DX10DataProcessor *iface, void *data, SIZE_T size) +{ + struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface); + + TRACE("iface %p, data %p, size %Iu.\n", iface, data, size); + + if (processor->resource_data) + { + WARN("Called multiple times.\n"); + free(processor->resource_data); + processor->resource_data = NULL; + } + return load_texture_data(data, size, &processor->load_info, &processor->resource_data); +} + +static HRESULT WINAPI texture_processor_CreateDeviceObject(ID3DX10DataProcessor *iface, void **object) +{ + struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface); + + TRACE("iface %p, object %p.\n", iface, object); + + if (!processor->resource_data) + return E_FAIL; + + return create_d3d_texture(processor->device, &processor->load_info, + processor->resource_data, (ID3D10Resource **)object); +} + +static HRESULT WINAPI texture_processor_Destroy(ID3DX10DataProcessor *iface) +{ + struct texture_processor *processor = texture_processor_from_ID3DX10DataProcessor(iface); + + TRACE("iface %p.\n", iface); + + ID3D10Device_Release(processor->device); + free(processor->resource_data); + free(processor); + return S_OK; +} + +static ID3DX10DataProcessorVtbl texture_processor_vtbl = +{ + texture_processor_Process, + texture_processor_CreateDeviceObject, + texture_processor_Destroy +}; + HRESULT WINAPI D3DX10CompileFromMemory(const char *data, SIZE_T data_size, const char *filename, const D3D10_SHADER_MACRO *defines, ID3D10Include *include, const char *entry_point, const char *target, UINT sflags, UINT eflags, ID3DX10ThreadPump *pump, ID3D10Blob **shader, @@ -517,8 +578,24 @@ HRESULT WINAPI D3DX10CreateAsyncTextureInfoProcessor(D3DX10_IMAGE_INFO *info, ID HRESULT WINAPI D3DX10CreateAsyncTextureProcessor(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10DataProcessor **processor) { - FIXME("device %p, load_info %p, processor %p stub!\n", device, load_info, processor); - return E_NOTIMPL; + struct texture_processor *object; + + TRACE("device %p, load_info %p, processor %p.\n", device, load_info, processor); + + if (!device || !processor) + return E_INVALIDARG; + + object = calloc(1, sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->ID3DX10DataProcessor_iface.lpVtbl = &texture_processor_vtbl; + object->device = device; + ID3D10Device_AddRef(device); + init_load_info(load_info, &object->load_info); + + *processor = &object->ID3DX10DataProcessor_iface; + return S_OK; }
HRESULT WINAPI D3DX10PreprocessShaderFromMemory(const char *data, SIZE_T data_size, const char *filename, diff --git a/dlls/d3dx10_43/dxhelpers.h b/dlls/d3dx10_43/dxhelpers.h index 82fe639c2ea..5d0cdb54c59 100644 --- a/dlls/d3dx10_43/dxhelpers.h +++ b/dlls/d3dx10_43/dxhelpers.h @@ -23,3 +23,11 @@ extern HRESULT load_resourceW(HMODULE module, const WCHAR *resource, void **data, DWORD *size) DECLSPEC_HIDDEN;
extern HRESULT get_image_info(const void *data, SIZE_T size, D3DX10_IMAGE_INFO *img_info) DECLSPEC_HIDDEN; + +extern void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info, + D3DX10_IMAGE_LOAD_INFO *out) DECLSPEC_HIDDEN; +/* Returns array of D3D10_SUBRESOURCE_DATA structures followed by textures data. */ +extern HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, + D3D10_SUBRESOURCE_DATA **resource_data) DECLSPEC_HIDDEN; +extern HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info, + D3D10_SUBRESOURCE_DATA *resource_data, ID3D10Resource **texture) DECLSPEC_HIDDEN; diff --git a/dlls/d3dx10_43/texture.c b/dlls/d3dx10_43/texture.c index d3a4d9450b6..b07472e5c46 100644 --- a/dlls/d3dx10_43/texture.c +++ b/dlls/d3dx10_43/texture.c @@ -571,6 +571,22 @@ HRESULT WINAPI D3DX10GetImageInfoFromMemory(const void *src_data, SIZE_T src_dat return hr; }
+static HRESULT create_texture(ID3D10Device *device, const void *data, SIZE_T size, + D3DX10_IMAGE_LOAD_INFO *load_info, ID3D10Resource **texture) +{ + D3D10_SUBRESOURCE_DATA *resource_data; + D3DX10_IMAGE_LOAD_INFO load_info_copy; + HRESULT hr; + + init_load_info(load_info, &load_info_copy); + + if (FAILED((hr = load_texture_data(data, size, &load_info_copy, &resource_data)))) + return hr; + hr = create_d3d_texture(device, &load_info_copy, resource_data, texture); + free(resource_data); + return hr; +} + HRESULT WINAPI D3DX10CreateTextureFromFileA(ID3D10Device *device, const char *src_file, D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult) { @@ -669,56 +685,83 @@ HRESULT WINAPI D3DX10CreateTextureFromResourceW(ID3D10Device *device, HMODULE mo return D3DX10CreateTextureFromMemory(device, buffer, size, load_info, pump, texture, hresult); }
-HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *src_data, SIZE_T src_data_size, - D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult) +void init_load_info(const D3DX10_IMAGE_LOAD_INFO *load_info, D3DX10_IMAGE_LOAD_INFO *out) +{ + if (load_info) + { + *out = *load_info; + return; + } + + out->Width = D3DX10_DEFAULT; + out->Height = D3DX10_DEFAULT; + out->Depth = D3DX10_DEFAULT; + out->FirstMipLevel = D3DX10_DEFAULT; + out->MipLevels = D3DX10_DEFAULT; + out->Usage = D3DX10_DEFAULT; + out->BindFlags = D3DX10_DEFAULT; + out->CpuAccessFlags = D3DX10_DEFAULT; + out->MiscFlags = D3DX10_DEFAULT; + out->Format = D3DX10_DEFAULT; + out->Filter = D3DX10_DEFAULT; + out->MipFilter = D3DX10_DEFAULT; + out->pSrcInfo = NULL; +} + +HRESULT load_texture_data(const void *data, SIZE_T size, D3DX10_IMAGE_LOAD_INFO *load_info, + D3D10_SUBRESOURCE_DATA **resource_data) { unsigned int frame_count, width, height, stride, frame_size; IWICFormatConverter *converter = NULL; IWICDdsFrameDecode *dds_frame = NULL; - D3D10_TEXTURE2D_DESC texture_2d_desc; - D3D10_SUBRESOURCE_DATA resource_data; IWICBitmapFrameDecode *frame = NULL; IWICImagingFactory *factory = NULL; IWICBitmapDecoder *decoder = NULL; - ID3D10Texture2D *texture_2d; + BYTE *res_data = NULL, *buffer; D3DX10_IMAGE_INFO img_info; IWICStream *stream = NULL; const GUID *dst_format; - BYTE *buffer = NULL; BOOL can_convert; GUID src_format; HRESULT hr;
- TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n", - device, src_data, src_data_size, load_info, pump, texture, hresult); - - if (!device) - return E_INVALIDARG; - if (!src_data) - return E_FAIL; - if (load_info) - FIXME("load_info is ignored.\n"); - if (pump) - FIXME("Thread pump is not supported yet.\n"); - - if (FAILED(D3DX10GetImageInfoFromMemory(src_data, src_data_size, NULL, &img_info, NULL))) - { - if (hresult) - *hresult = E_FAIL; + if (load_info->Width != D3DX10_DEFAULT) + FIXME("load_info->Width is ignored.\n"); + if (load_info->Height != D3DX10_DEFAULT) + FIXME("load_info->Height is ignored.\n"); + if (load_info->Depth != D3DX10_DEFAULT) + FIXME("load_info->Depth is ignored.\n"); + 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) + 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"); + if (load_info->Format != D3DX10_DEFAULT) + FIXME("load_info->Format 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"); + if (load_info->pSrcInfo) + FIXME("load_info->pSrcInfo is ignored.\n"); + + if (FAILED(D3DX10GetImageInfoFromMemory(data, size, NULL, &img_info, NULL))) return E_FAIL; - } if (img_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) { FIXME("Cube map is not supported.\n"); - if (hresult) - *hresult = E_FAIL; return E_FAIL; } if (img_info.ArraySize != 1) { FIXME("img_info.ArraySize = %d not supported.\n", img_info.ArraySize); - if (hresult) - *hresult = E_NOTIMPL; return E_NOTIMPL; }
@@ -726,7 +769,7 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s goto end; if (FAILED(hr = IWICImagingFactory_CreateStream(factory, &stream))) goto end; - if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)src_data, src_data_size))) + if (FAILED(hr = IWICStream_InitializeFromMemory(stream, (BYTE *)data, size))) goto end; if (FAILED(hr = IWICImagingFactory_CreateDecoderFromStream(factory, (IStream *)stream, NULL, 0, &decoder))) goto end; @@ -747,11 +790,12 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s stride = (width * get_bpp_from_format(img_info.Format) + 7) / 8; frame_size = stride * height;
- if (!(buffer = malloc(frame_size))) + if (!(res_data = malloc(sizeof(**resource_data) + frame_size))) { hr = E_FAIL; goto end; } + buffer = res_data + sizeof(**resource_data);
if (is_block_compressed(img_info.Format)) { @@ -794,25 +838,20 @@ HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *s } }
- memset(&texture_2d_desc, 0, sizeof(texture_2d_desc)); - texture_2d_desc.Width = width; - texture_2d_desc.Height = height; - texture_2d_desc.MipLevels = 1; - texture_2d_desc.ArraySize = img_info.ArraySize; - texture_2d_desc.Format = img_info.Format; - texture_2d_desc.SampleDesc.Count = 1; - texture_2d_desc.Usage = D3D10_USAGE_DEFAULT; - texture_2d_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; - texture_2d_desc.MiscFlags = img_info.MiscFlags; - - resource_data.pSysMem = buffer; - resource_data.SysMemPitch = stride; - resource_data.SysMemSlicePitch = frame_size; + load_info->Width = width; + load_info->Height = height; + load_info->MipLevels = 1; + load_info->Format = img_info.Format; + load_info->Usage = D3D10_USAGE_DEFAULT; + load_info->BindFlags = D3D10_BIND_SHADER_RESOURCE; + load_info->MiscFlags = img_info.MiscFlags;
- if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, &resource_data, &texture_2d))) - goto end; + *resource_data = (D3D10_SUBRESOURCE_DATA *)res_data; + res_data = NULL; + (*resource_data)->pSysMem = buffer; + (*resource_data)->SysMemPitch = stride; + (*resource_data)->SysMemSlicePitch = frame_size;
- *texture = (ID3D10Resource *)texture_2d; hr = S_OK;
end: @@ -820,7 +859,7 @@ end: IWICFormatConverter_Release(converter); if (dds_frame) IWICDdsFrameDecode_Release(dds_frame); - free(buffer); + free(res_data); if (frame) IWICBitmapFrameDecode_Release(frame); if (decoder) @@ -829,7 +868,50 @@ end: IWICStream_Release(stream); if (factory) IWICImagingFactory_Release(factory); + return hr; +} + +HRESULT create_d3d_texture(ID3D10Device *device, D3DX10_IMAGE_LOAD_INFO *load_info, + D3D10_SUBRESOURCE_DATA *resource_data, ID3D10Resource **texture) +{ + D3D10_TEXTURE2D_DESC texture_2d_desc; + ID3D10Texture2D *texture_2d; + HRESULT hr; + + memset(&texture_2d_desc, 0, sizeof(texture_2d_desc)); + 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 = 1; + 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.MiscFlags = load_info->MiscFlags; + + if (FAILED(hr = ID3D10Device_CreateTexture2D(device, &texture_2d_desc, resource_data, &texture_2d))) + return hr; + + *texture = (ID3D10Resource *)texture_2d; + return S_OK; +} + +HRESULT WINAPI D3DX10CreateTextureFromMemory(ID3D10Device *device, const void *src_data, SIZE_T src_data_size, + D3DX10_IMAGE_LOAD_INFO *load_info, ID3DX10ThreadPump *pump, ID3D10Resource **texture, HRESULT *hresult) +{ + HRESULT hr; + + TRACE("device %p, src_data %p, src_data_size %Iu, load_info %p, pump %p, texture %p, hresult %p.\n", + device, src_data, src_data_size, load_info, pump, texture, hresult); + + if (!device) + return E_INVALIDARG; + if (!src_data) + return E_FAIL; + if (pump) + FIXME("Thread pump is not supported yet.\n");
+ hr = create_texture(device, src_data, src_data_size, load_info, texture); if (hresult) *hresult = hr; return hr;
From: Piotr Caban piotr@codeweavers.com
Signed-off-by: Piotr Caban piotr@codeweavers.com --- dlls/d3dx10_43/tests/d3dx10.c | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 026eaf0dbb6..d8839626c3b 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2003,6 +2003,69 @@ static void test_D3DX10CreateAsyncTextureInfoProcessor(void) CoUninitialize(); }
+static void test_D3DX10CreateAsyncTextureProcessor(void) +{ + ID3DX10DataProcessor *dp; + ID3D10Resource *resource; + ID3D10Device *device; + HRESULT hr; + int i; + + device = create_device(); + if (!device) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + CoInitialize(NULL); + + hr = D3DX10CreateAsyncTextureProcessor(device, NULL, NULL); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + hr = D3DX10CreateAsyncTextureProcessor(NULL, NULL, &dp); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + + hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &dp); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[0].data, 0); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + hr = ID3DX10DataProcessor_Process(dp, NULL, test_image[0].size); + ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr); + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(test_image); ++i) + { + winetest_push_context("Test %u", i); + + hr = D3DX10CreateAsyncTextureProcessor(device, NULL, &dp); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + hr = ID3DX10DataProcessor_Process(dp, (void *)test_image[i].data, test_image[i].size); + todo_wine_if(test_image[i].expected_info.MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE) + ok(hr == S_OK || broken(hr == E_FAIL && test_image[i].expected_info.ImageFileFormat == D3DX10_IFF_WMP), + "Got unexpected hr %#x.\n", hr); + if (hr == S_OK) + { + hr = ID3DX10DataProcessor_CreateDeviceObject(dp, (void **)&resource); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + check_resource_info(resource, test_image + i, __LINE__); + check_resource_data(resource, test_image + i, __LINE__); + ID3D10Resource_Release(resource); + } + + hr = ID3DX10DataProcessor_Destroy(dp); + ok(hr == S_OK, "Got unexpected hr %#x.\n", hr); + + winetest_pop_context(); + } + + CoUninitialize(); + + ID3D10Device_Release(device); +} + static void test_get_image_info(void) { static const WCHAR test_resource_name[] = L"resource.data"; @@ -3498,6 +3561,7 @@ START_TEST(d3dx10) test_D3DX10CreateAsyncFileLoader(); test_D3DX10CreateAsyncResourceLoader(); test_D3DX10CreateAsyncTextureInfoProcessor(); + test_D3DX10CreateAsyncTextureProcessor(); test_get_image_info(); test_create_texture(); test_font();
On Wed Jun 15 11:56:53 2022 +0000, Piotr Caban wrote:
The helper will return array of structures in future (it's needed to e.g. support MipLevels). That's why I would prefer to do it in one of following ways. Return array of D3D10_SUBRESOURCE_DATA structures with data following the structures:
- can be freed with single free
- it would be possible to sometimes pass loaded data directly without
creating a copy (I was not planning to do that)
- it's harder to create
Return array of D3D10_SUBRESOURCE_DATA structures with each pSysMem fields allocated separately. Do you have any preference?
If I understand correctly, basically either (pseudocode): ``` struct texture_data { unsigned int subresource_count; D3D10_SUBRESOURCE_DATA subresource_data[]; BYTE data[]; }; ``` or ``` struct texture_data { unsigned int subresource_count; struct { D3D10_SUBRESOURCE_DATA subresource_data; } subresources[]; BYTE *data[]; }; ``` I think I very slightly prefer the first option if it doesn't turn out unreasonably complicated. Both are fine for sure.
On Wed Jun 15 14:04:22 2022 +0000, Matteo Bruni wrote:
If I understand correctly, basically either (pseudocode):
struct texture_data { unsigned int subresource_count; D3D10_SUBRESOURCE_DATA subresource_data[]; BYTE data[]; };
or
struct texture_data { unsigned int subresource_count; struct { D3D10_SUBRESOURCE_DATA subresource_data; } subresources[]; BYTE *data[]; };
I think I very slightly prefer the first option if it doesn't turn out unreasonably complicated. Both are fine for sure.
I was planning to skip the subresource_count since it's encoded in D3DX10_IMAGE_LOAD_INFO.
I think that the patches are currently implementing "first option" (unless you prefer to store subresource_count explicitly or use custom structure). I have added a comment saying that returned data contains both `D3D10_SUBRESOURCE_DATA` structures and actual data.
On Wed Jun 15 14:58:31 2022 +0000, Piotr Caban wrote:
I was planning to skip the subresource_count since it's encoded in D3DX10_IMAGE_LOAD_INFO. I think that the patches are currently implementing "first option" (unless you prefer to store subresource_count explicitly or use custom structure). I have added a comment saying that returned data contains both `D3D10_SUBRESOURCE_DATA` structures and actual data.
Ah sure, subresource_count was there as an example. A custom structure would be nice but I understand that's awkward with "first option" so the comment will do.