From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2 (Matteo): Rename a couple of "size" arguments to "count" (trivial)
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..276319719f8 --- /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 count) +{ + FIXME("iface %p, table %p, count %u stub!\n", iface, table, count); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3dx10_mesh_GetAttributeTable(ID3DX10Mesh *iface, + D3DX10_ATTRIBUTE_RANGE *table, UINT *count) +{ + FIXME("iface %p, table %p, count %p stub!\n", iface, table, count); + + 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; +}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2 (Matteo): Split out from the test patch. I dislike when a supposedly "tests" patch also touches the implementation. This one seemed innocuous enough but might as well split it up anyway.
dlls/d3dx10_43/sprite.c | 3 +++ 1 file changed, 3 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);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2 (Matteo): Minimal formatting changes, check device refcount at the end.
dlls/d3dx10_43/tests/d3dx10.c | 195 ++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+)
diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index b7834fb6f8a..1b875e4fc09 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -2973,6 +2973,200 @@ todo_wine ID3DX10Font_Release(font); }
+static void test_sprite(void) +{ + ID3D10ShaderResourceView *srv1, *srv2; + ID3D10Texture2D *texture1, *texture2; + D3D10_TEXTURE2D_DESC texture_desc; + ID3D10Device *device, *device2; + D3DX10_SPRITE sprite_desc; + ID3DX10Sprite *sprite; + D3DXMATRIX mat, mat2; + ULONG refcount; + HRESULT hr; + + 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); + + refcount = ID3D10Device_Release(device); + ok(!refcount, "Unexpected refcount.\n"); +} + START_TEST(d3dx10) { test_D3DX10UnsetAllDeviceObjects(); @@ -2982,4 +3176,5 @@ START_TEST(d3dx10) test_get_image_info(); test_create_texture(); test_font(); + test_sprite(); }