Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx10_43/Makefile.in | 1 + dlls/d3dx10_43/d3dx10_43.spec | 2 +- dlls/d3dx10_43/mesh.c | 378 ++++++++++++++++++++++++++++++++++ 3 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 dlls/d3dx10_43/mesh.c
diff --git a/dlls/d3dx10_43/Makefile.in b/dlls/d3dx10_43/Makefile.in index a763f588996..b6baed2b619 100644 --- a/dlls/d3dx10_43/Makefile.in +++ b/dlls/d3dx10_43/Makefile.in @@ -10,6 +10,7 @@ C_SRCS = \ compiler.c \ d3dx10_43_main.c \ font.c \ + mesh.c \ sprite.c \ texture.c
diff --git a/dlls/d3dx10_43/d3dx10_43.spec b/dlls/d3dx10_43/d3dx10_43.spec index aaa056acdd2..da6629ad1a0 100644 --- a/dlls/d3dx10_43/d3dx10_43.spec +++ b/dlls/d3dx10_43/d3dx10_43.spec @@ -34,7 +34,7 @@ @ stdcall D3DX10CreateFontIndirectA(ptr ptr ptr) @ stdcall D3DX10CreateFontIndirectW(ptr ptr ptr) @ stdcall D3DX10CreateFontW(ptr long long long long long long long long long wstr ptr) -@ stub D3DX10CreateMesh(ptr ptr long str long long long ptr) +@ stdcall D3DX10CreateMesh(ptr ptr long str long long long ptr) @ stub D3DX10CreateShaderResourceViewFromFileA(ptr str ptr ptr ptr ptr) @ stub D3DX10CreateShaderResourceViewFromFileW(ptr wstr ptr ptr ptr ptr) @ stub D3DX10CreateShaderResourceViewFromMemory(ptr ptr long ptr ptr ptr ptr) diff --git a/dlls/d3dx10_43/mesh.c b/dlls/d3dx10_43/mesh.c new file mode 100644 index 00000000000..8507df82884 --- /dev/null +++ b/dlls/d3dx10_43/mesh.c @@ -0,0 +1,378 @@ +/* + * Copyright 2021 Nikolay Sivov for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define COBJMACROS +#include "d3dx10.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + +struct d3dx10_mesh +{ + ID3DX10Mesh ID3DX10Mesh_iface; + LONG refcount; +}; + +static inline struct d3dx10_mesh *impl_from_ID3DX10Mesh(ID3DX10Mesh *iface) +{ + return CONTAINING_RECORD(iface, struct d3dx10_mesh, ID3DX10Mesh_iface); +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_QueryInterface(ID3DX10Mesh *iface, REFIID riid, void **out) +{ + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_ID3DX10Mesh) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3dx10_mesh_AddRef(ID3DX10Mesh *iface) +{ + struct d3dx10_mesh *mesh = impl_from_ID3DX10Mesh(iface); + ULONG refcount = InterlockedIncrement(&mesh->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3dx10_mesh_Release(ID3DX10Mesh *iface) +{ + struct d3dx10_mesh *mesh = impl_from_ID3DX10Mesh(iface); + ULONG refcount = InterlockedDecrement(&mesh->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + heap_free(mesh); + + return refcount; +} + +static UINT STDMETHODCALLTYPE d3dx10_mesh_GetFaceCount(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3dx10_mesh_GetVertexCount(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3dx10_mesh_GetVertexBufferCount(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3dx10_mesh_GetFlags(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetVertexDescription(ID3DX10Mesh *iface, + const D3D10_INPUT_ELEMENT_DESC **desc, UINT *count) +{ + FIXME("iface %p, desc %p, count %p stub!\n", iface, desc, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetVertexData(ID3DX10Mesh *iface, UINT index, + const void *data) +{ + FIXME("iface %p, index %u, data %p stub!\n", iface, index, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetVertexBuffer(ID3DX10Mesh *iface, UINT index, + ID3DX10MeshBuffer **buffer) +{ + FIXME("iface %p, index %u, buffer %p stub!\n", iface, index, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetIndexData(ID3DX10Mesh *iface, const void *data, + UINT count) +{ + FIXME("iface %p, data %p, count %u stub!\n", iface, data, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetIndexBuffer(ID3DX10Mesh *iface, + ID3DX10MeshBuffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetAttributeData(ID3DX10Mesh *iface, + const UINT *data) +{ + FIXME("iface %p, data %p stub!\n", iface, data); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetAttributeBuffer(ID3DX10Mesh *iface, + ID3DX10MeshBuffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetAttributeTable(ID3DX10Mesh *iface, + const D3DX10_ATTRIBUTE_RANGE *table, UINT size) +{ + FIXME("iface %p, table %p, size %u stub!\n", iface, table, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetAttributeTable(ID3DX10Mesh *iface, + D3DX10_ATTRIBUTE_RANGE *table, UINT *size) +{ + FIXME("iface %p, table %p, size %p stub!\n", iface, table, size); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GenerateAdjacencyAndPointReps(ID3DX10Mesh *iface, + float epsilon) +{ + FIXME("iface %p, epsilon %.8e stub!\n", iface, epsilon); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GenerateGSAdjacency(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetAdjacencyData(ID3DX10Mesh *iface, + const UINT *adjacency) +{ + FIXME("iface %p, adjacency %p stub!\n", iface, adjacency); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetAdjacencyBuffer(ID3DX10Mesh *iface, + ID3DX10MeshBuffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_SetPointRepData(ID3DX10Mesh *iface, + const UINT *pointreps) +{ + FIXME("iface %p, pointreps %p stub!\n", iface, pointreps); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetPointRepBuffer(ID3DX10Mesh *iface, + ID3DX10MeshBuffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_Discard(ID3DX10Mesh *iface, + D3DX10_MESH_DISCARD_FLAGS flags) +{ + FIXME("iface %p, flags %#x stub!\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_CloneMesh(ID3DX10Mesh *iface, UINT flags, + const char *pos_semantic, const D3D10_INPUT_ELEMENT_DESC *desc, UINT decl_count, + ID3DX10Mesh **cloned_mesh) +{ + FIXME("iface %p, flags %#x, pos_semantic %s, desc %p, decl_count %u, cloned_mesh %p stub!\n", + iface, flags, debugstr_a(pos_semantic), desc, decl_count, cloned_mesh); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_Optimize(ID3DX10Mesh *iface, UINT flags, + UINT *face_remap, ID3D10Blob **vertex_remap) +{ + FIXME("iface %p, flags %#x, face_remap %p, vertex_remap %p stub!\n", iface, flags, + face_remap, vertex_remap); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GenerateAttributeBufferFromTable(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_Intersect(ID3DX10Mesh *iface, D3DXVECTOR3 *ray_pos, + D3DXVECTOR3 *ray_dir, UINT *hit_count, UINT *face_index, float *u, float *v, float *dist, + ID3D10Blob **all_hits) +{ + FIXME("iface %p, ray_pos %p, ray_dir %p, hit_count %p, u %p, v %p, dist %p, all_hits %p stub!\n", + iface, ray_pos, ray_dir, hit_count, u, v, dist, all_hits); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_IntersectSubset(ID3DX10Mesh *iface, UINT attr_id, + D3DXVECTOR3 *ray_pos, D3DXVECTOR3 *ray_dir, UINT *hit_count, float *u, float *v, + float *dist, ID3D10Blob **all_hits) +{ + FIXME("iface %p, attr_id %u, ray_pos %p, ray_dir %p, hit_count %p, u %p, v %p, dist %p, all_hits %p stub!\n", + iface, attr_id, ray_pos, ray_dir, hit_count, u, v, dist, all_hits); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_CommitToDevice(ID3DX10Mesh *iface) +{ + FIXME("iface %p stub!\n", iface); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_DrawSubset(ID3DX10Mesh *iface, UINT attr_id) +{ + FIXME("iface %p, attr_id %u stub!\n", iface, attr_id); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_DrawSubsetInstanced(ID3DX10Mesh *iface, UINT attr_id, + UINT instance_count, UINT start_instance) +{ + FIXME("iface %p, attr_id %u, instance_count %u, start_instance %u stub!\n", iface, attr_id, + instance_count, start_instance); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetDeviceVertexBuffer(ID3DX10Mesh *iface, UINT index, + ID3D10Buffer **buffer) +{ + FIXME("iface %p, index %u, buffer %p stub!\n", iface, index, buffer); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetDeviceIndexBuffer(ID3DX10Mesh *iface, + ID3D10Buffer **buffer) +{ + FIXME("iface %p, buffer %p stub!\n", iface, buffer); + + return E_NOTIMPL; +} + +static const ID3DX10MeshVtbl d3dx10_mesh_vtbl = +{ + d3dx10_mesh_QueryInterface, + d3dx10_mesh_AddRef, + d3dx10_mesh_Release, + d3dx10_mesh_GetFaceCount, + d3dx10_mesh_GetVertexCount, + d3dx10_mesh_GetVertexBufferCount, + d3dx10_mesh_GetFlags, + d3dx10_mesh_GetVertexDescription, + d3dx10_mesh_SetVertexData, + d3dx10_mesh_GetVertexBuffer, + d3dx10_mesh_SetIndexData, + d3dx10_mesh_GetIndexBuffer, + d3dx10_mesh_SetAttributeData, + d3dx10_mesh_GetAttributeBuffer, + d3dx10_mesh_SetAttributeTable, + d3dx10_mesh_GetAttributeTable, + d3dx10_mesh_GenerateAdjacencyAndPointReps, + d3dx10_mesh_GenerateGSAdjacency, + d3dx10_mesh_SetAdjacencyData, + d3dx10_mesh_GetAdjacencyBuffer, + d3dx10_mesh_SetPointRepData, + d3dx10_mesh_GetPointRepBuffer, + d3dx10_mesh_Discard, + d3dx10_mesh_CloneMesh, + d3dx10_mesh_Optimize, + d3dx10_mesh_GenerateAttributeBufferFromTable, + d3dx10_mesh_Intersect, + d3dx10_mesh_IntersectSubset, + d3dx10_mesh_CommitToDevice, + d3dx10_mesh_DrawSubset, + d3dx10_mesh_DrawSubsetInstanced, + d3dx10_mesh_GetDeviceVertexBuffer, + d3dx10_mesh_GetDeviceIndexBuffer, +}; + +HRESULT WINAPI D3DX10CreateMesh(ID3D10Device *device, const D3D10_INPUT_ELEMENT_DESC *decl, + UINT decl_count, const char *position_semantic, UINT vertex_count, UINT face_count, + UINT options, ID3DX10Mesh **mesh) +{ + struct d3dx10_mesh *object; + + FIXME("device %p, decl %p, decl_count %u, position_semantic %s, vertex_count %u, face_count %u, " + "options %#x, mesh %p semi-stub.\n", device, decl, decl_count, debugstr_a(position_semantic), vertex_count, + face_count, options, mesh); + + *mesh = NULL; + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ID3DX10Mesh_iface.lpVtbl = &d3dx10_mesh_vtbl; + object->refcount = 1; + + *mesh = &object->ID3DX10Mesh_iface; + + return S_OK; +}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d3dx10_43/sprite.c | 3 + dlls/d3dx10_43/tests/d3dx10.c | 194 ++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+)
diff --git a/dlls/d3dx10_43/sprite.c b/dlls/d3dx10_43/sprite.c index c90185e0c0a..5fc9b9edaa2 100644 --- a/dlls/d3dx10_43/sprite.c +++ b/dlls/d3dx10_43/sprite.c @@ -157,6 +157,9 @@ static HRESULT WINAPI d3dx10_sprite_GetDevice(ID3DX10Sprite *iface, ID3D10Device
TRACE("iface %p, device %p.\n", iface, device);
+ if (!device) + return E_FAIL; + *device = sprite->device; ID3D10Device_AddRef(*device);
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index b7834fb6f8a..7ed77a6406c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2973,6 +2973,199 @@ todo_wine ID3DX10Font_Release(font); }
+static void test_sprite(void) +{ + ID3D10Device *device, *device2; + ID3DX10Sprite *sprite; + D3DXMATRIX mat, mat2; + HRESULT hr; + D3DX10_SPRITE sprite_desc; + D3D10_TEXTURE2D_DESC texture_desc; + ID3D10Texture2D *texture1, *texture2; + ID3D10ShaderResourceView *srv1, *srv2; + ULONG refcount; + + if (!(device = create_device())) + { + skip("Failed to create device, skipping tests.\n"); + return; + } + + texture_desc.Width = 64; + texture_desc.Height = 64; + texture_desc.MipLevels = 1; + texture_desc.ArraySize = 1; + texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texture_desc.SampleDesc.Count = 1; + texture_desc.SampleDesc.Quality = 0; + texture_desc.Usage = D3D10_USAGE_DEFAULT; + texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; + texture_desc.CPUAccessFlags = 0; + texture_desc.MiscFlags = 0; + + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture1); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture2); + ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); + + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv1); + ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr); + + hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv2); + ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr); + + hr = D3DX10CreateSprite(device, 0, NULL); + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr); + + hr = D3DX10CreateSprite(NULL, 0, &sprite); + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr); + + hr = D3DX10CreateSprite(device, 0, &sprite); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* GetDevice */ + hr = ID3DX10Sprite_GetDevice(sprite, NULL); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_GetDevice(sprite, &device2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(device == device2, "Unexpected device.\n"); + + ID3D10Device_Release(device2); + + /* Projection transform */ + hr = ID3DX10Sprite_GetProjectionTransform(sprite, NULL); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + hr = ID3DX10Sprite_GetProjectionTransform(sprite, &mat); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Set a transform and test if it gets returned correctly */ + mat.m[0][0] = 2.1f; mat.m[0][1] = 6.5f; mat.m[0][2] =-9.6f; mat.m[0][3] = 1.7f; + mat.m[1][0] = 4.2f; mat.m[1][1] =-2.5f; mat.m[1][2] = 2.1f; mat.m[1][3] = 5.5f; + mat.m[2][0] =-2.6f; mat.m[2][1] = 0.3f; mat.m[2][2] = 8.6f; mat.m[2][3] = 8.4f; + mat.m[3][0] = 6.7f; mat.m[3][1] =-5.1f; mat.m[3][2] = 6.1f; mat.m[3][3] = 2.2f; + + hr = ID3DX10Sprite_SetProjectionTransform(sprite, NULL); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_SetProjectionTransform(sprite, &mat); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_GetProjectionTransform(sprite, &mat2); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!memcmp(&mat, &mat2, sizeof(mat)), "Unexpected matrix.\n"); +} + + /* View transform */ + hr = ID3DX10Sprite_SetViewTransform(sprite, NULL); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_SetViewTransform(sprite, &mat); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Begin */ + hr = ID3DX10Sprite_Begin(sprite, 0); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Flush/End */ + hr = ID3DX10Sprite_Flush(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_End(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* May not be called before next Begin */ + hr = ID3DX10Sprite_Flush(sprite); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + hr = ID3DX10Sprite_End(sprite); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + /* Draw */ + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, NULL, 0); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + memset(&sprite_desc, 0, sizeof(sprite_desc)); + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 0); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1); +todo_wine + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_Begin(sprite, 0); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + memset(&sprite_desc, 0, sizeof(sprite_desc)); + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + sprite_desc.pTexture = srv1; + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_Flush(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_Flush(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ID3DX10Sprite_End(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* D3DX10_SPRITE_ADDREF_TEXTURES */ + hr = ID3DX10Sprite_Begin(sprite, D3DX10_SPRITE_ADDREF_TEXTURES); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + memset(&sprite_desc, 0, sizeof(sprite_desc)); + sprite_desc.pTexture = srv1; + + refcount = get_refcount(srv1); + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(get_refcount(srv1) > refcount, "Unexpected refcount.\n"); +} + + hr = ID3DX10Sprite_Flush(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(get_refcount(srv1) == refcount, "Unexpected refcount.\n"); + + hr = ID3DX10Sprite_End(sprite); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + ID3DX10Sprite_Release(sprite); + ID3D10Texture2D_Release(texture1); + ID3D10Texture2D_Release(texture2); + ID3D10ShaderResourceView_Release(srv1); + ID3D10ShaderResourceView_Release(srv2); + + ID3D10Device_Release(device); +} + START_TEST(d3dx10) { test_D3DX10UnsetAllDeviceObjects(); @@ -2982,4 +3175,5 @@ START_TEST(d3dx10) test_get_image_info(); test_create_texture(); test_font(); + test_sprite(); }
On Mon, Aug 23, 2021 at 10:22 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3dx10_43/sprite.c | 3 + dlls/d3dx10_43/tests/d3dx10.c | 194 ++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index b7834fb6f8a..7ed77a6406c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2973,6 +2973,199 @@ todo_wine ID3DX10Font_Release(font); }
+static void test_sprite(void) +{
- ID3D10Device *device, *device2;
- ID3DX10Sprite *sprite;
- D3DXMATRIX mat, mat2;
- HRESULT hr;
- D3DX10_SPRITE sprite_desc;
- D3D10_TEXTURE2D_DESC texture_desc;
- ID3D10Texture2D *texture1, *texture2;
- ID3D10ShaderResourceView *srv1, *srv2;
- ULONG refcount;
- if (!(device = create_device()))
- {
skip("Failed to create device, skipping tests.\n");
return;
- }
- texture_desc.Width = 64;
- texture_desc.Height = 64;
- texture_desc.MipLevels = 1;
- texture_desc.ArraySize = 1;
- texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- texture_desc.SampleDesc.Count = 1;
- texture_desc.SampleDesc.Quality = 0;
- texture_desc.Usage = D3D10_USAGE_DEFAULT;
- texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
- texture_desc.CPUAccessFlags = 0;
- texture_desc.MiscFlags = 0;
- hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture1);
- ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
- hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture2);
- ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv1);
- ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr);
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv2);
- ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr);
- hr = D3DX10CreateSprite(device, 0, NULL);
- ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
- hr = D3DX10CreateSprite(NULL, 0, &sprite);
- ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
- hr = D3DX10CreateSprite(device, 0, &sprite);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- /* GetDevice */
- hr = ID3DX10Sprite_GetDevice(sprite, NULL);
- ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_GetDevice(sprite, &device2);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(device == device2, "Unexpected device.\n");
- ID3D10Device_Release(device2);
- /* Projection transform */
- hr = ID3DX10Sprite_GetProjectionTransform(sprite, NULL);
+todo_wine
- ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_GetProjectionTransform(sprite, &mat);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
We could test what the initial projection transform matrix looks like. I expect it to be just the identity matrix of course, but... Same for the view matrix.
- hr = ID3DX10Sprite_Begin(sprite, 0);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- memset(&sprite_desc, 0, sizeof(sprite_desc));
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- sprite_desc.pTexture = srv1;
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_End(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- /* D3DX10_SPRITE_ADDREF_TEXTURES */
- hr = ID3DX10Sprite_Begin(sprite, D3DX10_SPRITE_ADDREF_TEXTURES);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- memset(&sprite_desc, 0, sizeof(sprite_desc));
- sprite_desc.pTexture = srv1;
- refcount = get_refcount(srv1);
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine {
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(get_refcount(srv1) > refcount, "Unexpected refcount.\n");
+}
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(get_refcount(srv1) == refcount, "Unexpected refcount.\n");
- hr = ID3DX10Sprite_End(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
The docs suggest that you must call Flush() before End() to make sure that the sprites are actually drawn on the screen. Some testing around that would be nice. FWIW it would be pretty surprising to me if End() doesn't flush on its own anyway.
On 8/25/21 8:40 PM, Matteo Bruni wrote:
On Mon, Aug 23, 2021 at 10:22 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/d3dx10_43/sprite.c | 3 + dlls/d3dx10_43/tests/d3dx10.c | 194 ++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index b7834fb6f8a..7ed77a6406c 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2973,6 +2973,199 @@ todo_wine ID3DX10Font_Release(font); }
+static void test_sprite(void) +{
- ID3D10Device *device, *device2;
- ID3DX10Sprite *sprite;
- D3DXMATRIX mat, mat2;
- HRESULT hr;
- D3DX10_SPRITE sprite_desc;
- D3D10_TEXTURE2D_DESC texture_desc;
- ID3D10Texture2D *texture1, *texture2;
- ID3D10ShaderResourceView *srv1, *srv2;
- ULONG refcount;
- if (!(device = create_device()))
- {
skip("Failed to create device, skipping tests.\n");
return;
- }
- texture_desc.Width = 64;
- texture_desc.Height = 64;
- texture_desc.MipLevels = 1;
- texture_desc.ArraySize = 1;
- texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- texture_desc.SampleDesc.Count = 1;
- texture_desc.SampleDesc.Quality = 0;
- texture_desc.Usage = D3D10_USAGE_DEFAULT;
- texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
- texture_desc.CPUAccessFlags = 0;
- texture_desc.MiscFlags = 0;
- hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture1);
- ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
- hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture2);
- ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv1);
- ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr);
- hr = ID3D10Device_CreateShaderResourceView(device, (ID3D10Resource *)texture1, NULL, &srv2);
- ok(SUCCEEDED(hr), "Failed to create srv, hr %#x.\n", hr);
- hr = D3DX10CreateSprite(device, 0, NULL);
- ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
- hr = D3DX10CreateSprite(NULL, 0, &sprite);
- ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
- hr = D3DX10CreateSprite(device, 0, &sprite);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- /* GetDevice */
- hr = ID3DX10Sprite_GetDevice(sprite, NULL);
- ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_GetDevice(sprite, &device2);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(device == device2, "Unexpected device.\n");
- ID3D10Device_Release(device2);
- /* Projection transform */
- hr = ID3DX10Sprite_GetProjectionTransform(sprite, NULL);
+todo_wine
- ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_GetProjectionTransform(sprite, &mat);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
We could test what the initial projection transform matrix looks like. I expect it to be just the identity matrix of course, but... Same for the view matrix.
Right, I have a patch for this part, as projection matrix was actually set by the demo application.
- hr = ID3DX10Sprite_Begin(sprite, 0);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- memset(&sprite_desc, 0, sizeof(sprite_desc));
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- sprite_desc.pTexture = srv1;
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- hr = ID3DX10Sprite_End(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- /* D3DX10_SPRITE_ADDREF_TEXTURES */
- hr = ID3DX10Sprite_Begin(sprite, D3DX10_SPRITE_ADDREF_TEXTURES);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- memset(&sprite_desc, 0, sizeof(sprite_desc));
- sprite_desc.pTexture = srv1;
- refcount = get_refcount(srv1);
- hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1);
+todo_wine {
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(get_refcount(srv1) > refcount, "Unexpected refcount.\n");
+}
- hr = ID3DX10Sprite_Flush(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- ok(get_refcount(srv1) == refcount, "Unexpected refcount.\n");
- hr = ID3DX10Sprite_End(sprite);
+todo_wine
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
The docs suggest that you must call Flush() before End() to make sure that the sprites are actually drawn on the screen. Some testing around that would be nice. FWIW it would be pretty surprising to me if End() doesn't flush on its own anyway.
I had a failed naive attempt to draw solid color sprite on top of solid color cleared target, where I wanted to see how flushing happens. I'll revisit when I have more time for this.