[PATCH 0/3] MR11721: d3dx10: Partially implement sprite rendering.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11721
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/d3dx10_43/sprite.c | 369 +++++++++++++++++++++++++++++++--- dlls/d3dx10_43/tests/d3dx10.c | 9 - 2 files changed, 344 insertions(+), 34 deletions(-) diff --git a/dlls/d3dx10_43/sprite.c b/dlls/d3dx10_43/sprite.c index 422d0a4922d..133b33d381f 100644 --- a/dlls/d3dx10_43/sprite.c +++ b/dlls/d3dx10_43/sprite.c @@ -19,6 +19,7 @@ #define COBJMACROS #include "d3dx10.h" +#include "d3dcompiler.h" #include <stdbool.h> #include "wine/debug.h" @@ -28,6 +29,51 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); #define D3DERR_INVALIDCALL 0x8876086c #define D3DX10_SPRITE_READY 0x10000000 +static D3DXVECTOR4 * d3dx_vec4_transform(D3DXVECTOR4 *out, const D3DXVECTOR4 *v, const D3DXMATRIX *m) +{ + out->x = m->m[0][0] * v->x + m->m[1][0] * v->y + m->m[2][0] * v->z + m->m[3][0] * v->w; + out->y = m->m[0][1] * v->x + m->m[1][1] * v->y + m->m[2][1] * v->z + m->m[3][1] * v->w; + out->z = m->m[0][2] * v->x + m->m[1][2] * v->y + m->m[2][2] * v->z + m->m[3][2] * v->w; + out->w = m->m[0][3] * v->x + m->m[1][3] * v->y + m->m[2][3] * v->z + m->m[3][3] * v->w; + + return out; +} + +static D3DXVECTOR4 * d3dx_vec4_transform_array(D3DXVECTOR4 *out, UINT out_stride, + const D3DXVECTOR4 *v, UINT in_stride, const D3DXMATRIX *m, UINT count) +{ + for (unsigned int i = 0; i < count; ++i) + { + d3dx_vec4_transform((D3DXVECTOR4 *)((char *)out + out_stride * i), + (const D3DXVECTOR4 *)((const char *)v + in_stride * i), m); + } + + return out; +} + +static D3DXMATRIX * d3dx_matrix_multiply(D3DXMATRIX *out, const D3DXMATRIX *m1, const D3DXMATRIX *m2) +{ + int i, j; + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + out->m[i][j] = m1->m[i][0] * m2->m[0][j] + m1->m[i][1] * m2->m[1][j] + + m1->m[i][2] * m2->m[2][j] + m1->m[i][3] * m2->m[3][j]; + } + } + + return out; +} + +struct vertex +{ + D3DXVECTOR4 pos; + D3DXVECTOR4 texcoord; + D3DXVECTOR4 color; +}; + struct d3dx10_sprite { ID3DX10Sprite ID3DX10Sprite_iface; @@ -40,8 +86,17 @@ struct d3dx10_sprite size_t capacity; } buffer; D3DXMATRIX projection; + D3DXMATRIX view; ID3D10Device *device; ID3D10StateBlock *state_block; + struct vertex *vertex_data; + unsigned int batch_size; + ID3D10InputLayout *input_layout; + ID3D10PixelShader *pixel_shader; + ID3D10VertexShader *vertex_shader; + ID3D10SamplerState *sampler; + ID3D10Buffer *vb; + ID3D10Buffer *vs_cb; unsigned int flags; }; @@ -85,9 +140,123 @@ static void d3dx10_sprite_clear_batch(struct d3dx10_sprite *sprite) sprite->buffer.count = 0; } +static void d3dx10_sprite_cleanup(struct d3dx10_sprite *sprite) +{ + if (sprite->input_layout) + ID3D10InputLayout_Release(sprite->input_layout); + if (sprite->pixel_shader) + ID3D10PixelShader_Release(sprite->pixel_shader); + if (sprite->vertex_shader) + ID3D10VertexShader_Release(sprite->vertex_shader); + if (sprite->sampler) + ID3D10SamplerState_Release(sprite->sampler); + if (sprite->device) + ID3D10Device_Release(sprite->device); + if (sprite->state_block) + IUnknown_Release(sprite->state_block); + if (sprite->vb) + ID3D10Buffer_Release(sprite->vb); + if (sprite->vs_cb) + ID3D10Buffer_Release(sprite->vs_cb); + d3dx10_sprite_clear_batch(sprite); + free(sprite->buffer.sprites); + free(sprite->vertex_data); +} + +static D3DX10_SPRITE * d3dx10_get_next_sprite(D3DX10_SPRITE *ptr, unsigned int stride) +{ + return (D3DX10_SPRITE *)((char *)ptr + stride); +} + +static void d3dx10_sprite_draw_batch(struct d3dx10_sprite *sprite, D3DX10_SPRITE **sprites, + unsigned int count, unsigned int stride) +{ + struct vertex *v = sprite->vertex_data; + static const D3DXVECTOR4 quad[] = + { + {-0.5f, -0.5f, 0.0f, 1.0f}, + {-0.5f, 0.5f, 0.0f, 1.0f}, + { 0.5f, -0.5f, 0.0f, 1.0f}, + { 0.5f, 0.5f, 0.0f, 1.0f}, + }; + D3DX10_SPRITE *ptr = *sprites, *start_sprite; + unsigned int i, start; + + for (i = 0; i < count; ++i, v += 4) + { + memcpy(&v->color, &ptr->ColorModulate, sizeof(v->color)); + v[0].texcoord.z = ptr->TextureIndex; + v[1] = v[2] = v[3] = *v; + d3dx_vec4_transform_array(&v->pos, sizeof(*v), quad, sizeof(*quad), &ptr->matWorld, 4); + v[0].texcoord.x = ptr->TexCoord.x; + v[0].texcoord.y = ptr->TexCoord.y + ptr->TexSize.y; + v[1].texcoord.x = ptr->TexCoord.x; + v[1].texcoord.y = ptr->TexCoord.y; + v[2].texcoord.x = ptr->TexCoord.x + ptr->TexSize.x; + v[2].texcoord.y = ptr->TexCoord.y + ptr->TexSize.y; + v[3].texcoord.x = ptr->TexCoord.x + ptr->TexSize.x; + v[3].texcoord.y = ptr->TexCoord.y; + + ptr = d3dx10_get_next_sprite(ptr, stride); + } + + ID3D10Device_UpdateSubresource(sprite->device, (ID3D10Resource *)sprite->vb, 0, NULL, + sprite->vertex_data, 0, 0); + + start_sprite = ptr = *sprites; + start = 0; + + for (i = 0; i < count; ++i) + { + if (ptr->pTexture != start_sprite->pTexture || i == count - 1) + { + ID3D10Device_PSSetShaderResources(sprite->device, 0, 1, &start_sprite->pTexture); + ID3D10Device_Draw(sprite->device, (i - start + 1) * 4, start * 4); + start_sprite = ptr; + start = i; + } + + ptr = d3dx10_get_next_sprite(ptr, stride); + } + + *sprites = (D3DX10_SPRITE *)((char *)*sprites + count * stride); +} + +static void d3dx10_sprite_draw(struct d3dx10_sprite *sprite, D3DX10_SPRITE *sprites, + size_t count, unsigned int stride) +{ + unsigned int i, vb_stride, offset; + D3DX10_SPRITE *ptr = sprites; + D3DXMATRIX m; + + if (!count) return; + + if (!stride) stride = sizeof(*sprites); + + ID3D10Device_IASetInputLayout(sprite->device, sprite->input_layout); + ID3D10Device_IASetPrimitiveTopology(sprite->device, D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + vb_stride = sizeof(*sprite->vertex_data); + offset = 0; + ID3D10Device_IASetVertexBuffers(sprite->device, 0, 1, &sprite->vb, &vb_stride, &offset); + ID3D10Device_VSSetShader(sprite->device, sprite->vertex_shader); + ID3D10Device_VSSetConstantBuffers(sprite->device, 0, 1, &sprite->vs_cb); + ID3D10Device_PSSetShader(sprite->device, sprite->pixel_shader); + ID3D10Device_PSSetConstantBuffers(sprite->device, 0, 0, NULL); + ID3D10Device_PSSetSamplers(sprite->device, 0, 1, &sprite->sampler); + + d3dx_matrix_multiply(&m, &sprite->projection, &sprite->view); + ID3D10Device_UpdateSubresource(sprite->device, (ID3D10Resource *)sprite->vs_cb, 0, NULL, + &m, 0, 0); + + for (i = 0; i < count / sprite->batch_size; ++i) + d3dx10_sprite_draw_batch(sprite, &ptr, sprite->batch_size, stride); + + d3dx10_sprite_draw_batch(sprite, &ptr, count % sprite->batch_size, stride); +} + static void d3dx10_sprite_flush(struct d3dx10_sprite *sprite) { - /* TODO: draw batched sprites */ + d3dx10_sprite_draw(sprite, sprite->buffer.sprites, sprite->buffer.count, 0); d3dx10_sprite_clear_batch(sprite); } @@ -133,11 +302,7 @@ static ULONG WINAPI d3dx10_sprite_Release(ID3DX10Sprite *iface) if (!refcount) { - ID3D10Device_Release(sprite->device); - if (sprite->state_block) - IUnknown_Release(sprite->state_block); - d3dx10_sprite_clear_batch(sprite); - free(sprite->buffer.sprites); + d3dx10_sprite_cleanup(sprite); free(sprite); } @@ -153,6 +318,14 @@ static HRESULT WINAPI d3dx10_sprite_Begin(ID3DX10Sprite *iface, UINT flags) if (sprite->flags & D3DX10_SPRITE_READY) return E_FAIL; + if (flags & + ( D3DX10_SPRITE_SORT_TEXTURE + | D3DX10_SPRITE_SORT_DEPTH_BACK_TO_FRONT + | D3DX10_SPRITE_SORT_DEPTH_FRONT_TO_BACK)) + { + FIXME("Sorting options are not implemented.\n"); + } + sprite->flags = flags | D3DX10_SPRITE_READY; if (sprite->flags & D3DX10_SPRITE_SAVE_STATE) sprite->state_block->lpVtbl->Capture(sprite->state_block); @@ -190,14 +363,14 @@ static HRESULT WINAPI d3dx10_sprite_Flush(ID3DX10Sprite *iface) { struct d3dx10_sprite *sprite = impl_from_ID3DX10Sprite(iface); - FIXME("iface %p stub!\n", iface); + TRACE("iface %p.\n", iface); if (!(sprite->flags & D3DX10_SPRITE_READY)) return E_FAIL; d3dx10_sprite_flush(sprite); - return E_NOTIMPL; + return S_OK; } static HRESULT WINAPI d3dx10_sprite_DrawSpritesImmediate(ID3DX10Sprite *iface, @@ -205,20 +378,22 @@ static HRESULT WINAPI d3dx10_sprite_DrawSpritesImmediate(ID3DX10Sprite *iface, { struct d3dx10_sprite *sprite = impl_from_ID3DX10Sprite(iface); - FIXME("iface %p, sprites %p, count %u, size %u, flags %#x stub!\n", + TRACE("iface %p, sprites %p, count %u, size %u, flags %#x.\n", iface, sprites, count, size, flags); if (!(sprite->flags & D3DX10_SPRITE_READY)) return E_FAIL; - return E_NOTIMPL; + d3dx10_sprite_draw(sprite, sprites, count, size); + + return S_OK; } static HRESULT WINAPI d3dx10_sprite_End(ID3DX10Sprite *iface) { struct d3dx10_sprite *sprite = impl_from_ID3DX10Sprite(iface); - FIXME("iface %p stub!\n", iface); + TRACE("iface %p.\n", iface); if (!(sprite->flags & D3DX10_SPRITE_READY)) return E_FAIL; @@ -307,10 +482,165 @@ static const ID3DX10SpriteVtbl d3dx10_sprite_vtbl = d3dx10_sprite_GetDevice, }; +static HRESULT d3dx10_sprite_init(struct d3dx10_sprite *sprite, ID3D10Device *device, UINT size) +{ + static const D3D10_INPUT_ELEMENT_DESC il_desc[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D10_INPUT_PER_VERTEX_DATA, 0 }, + }; + + static const char vs_code[] = + "float4x4 transform;\n" + "\n" + "struct vertex\n" + "{\n" + " float4 p : SV_POSITION;\n" + " float4 t : TEXCOORD;\n" + " float4 color : COLOR;\n" + "};\n" + "\n" + "void main(float4 p : POSITION, float4 t : TEXCOORD, float4 c : COLOR, out struct vertex o)\n" + "{\n" + " o.p = mul(transform, p);\n" + " o.t = t;\n" + " o.color = c;\n" + "}"; + + static const char ps_code[] = + "Texture2D t;\n" + "SamplerState s;\n" + "\n" + "struct vertex\n" + "{\n" + " float4 p : SV_POSITION;\n" + " float4 t : TEXCOORD;\n" + " float4 color : COLOR;\n" + "};\n" + "\n" + "float4 main(struct vertex v) : SV_Target\n" + "{\n" + " return t.Sample(s, float2(v.t.x, v.t.y)) * v.color;\n" + "}"; + + D3D10_SAMPLER_DESC sampler_desc = { 0 }; + const unsigned int max_size = 4096; + ID3D10Blob *vs = NULL, *ps = NULL; + D3D10_BUFFER_DESC buffer_desc; + D3D10_STATE_BLOCK_MASK mask; + unsigned int vb_size; + HRESULT hr; + + sprite->ID3DX10Sprite_iface.lpVtbl = &d3dx10_sprite_vtbl; + sprite->refcount = 1; + sprite->device = device; + ID3D10Device_AddRef(device); + sprite->projection._11 = 1.0f; + sprite->projection._22 = 1.0f; + sprite->projection._33 = 1.0f; + sprite->projection._44 = 1.0f; + sprite->view = sprite->projection; + + /* TODO: we shouldn't be capturing entire state */ + D3D10StateBlockMaskEnableAll(&mask); + if (FAILED(hr = D3D10CreateStateBlock(device, &mask, &sprite->state_block))) + goto err; + + if (FAILED(hr = D3DCompile(vs_code, sizeof(vs_code) - 1, "vs_sprite", NULL, NULL, + "main", "vs_4_0", 0, 0, &vs, NULL))) + { + WARN("Failed to compile the vertex shader, hr %#lx.\n", hr); + goto err; + } + + if (FAILED(hr = D3DCompile(ps_code, sizeof(ps_code) - 1, "ps_sprite", NULL, NULL, + "main", "ps_4_0", 0, 0, &ps, NULL))) + { + WARN("Failed to compile the pixel shader, hr %#lx.\n", hr); + goto err; + } + + if (FAILED(hr = ID3D10Device_CreateInputLayout(device, il_desc, ARRAY_SIZE(il_desc), + ID3D10Blob_GetBufferPointer(vs), ID3D10Blob_GetBufferSize(vs), &sprite->input_layout))) + { + WARN("Failed to create input layout, hr %#lx.\n", hr); + goto err; + } + + if (FAILED(hr = ID3D10Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs), + ID3D10Blob_GetBufferSize(vs), &sprite->vertex_shader))) + { + WARN("Failed to create vertex shader, hr %#lx.\n", hr); + goto err; + } + + if (FAILED(hr = ID3D10Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps), + ID3D10Blob_GetBufferSize(ps), &sprite->pixel_shader))) + { + WARN("Failed to create pixel shader, hr %#lx.\n", hr); + goto err; + } + + ID3D10Blob_Release(vs); + ID3D10Blob_Release(ps); + + sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT; + sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP; + sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP; + if (FAILED(hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sprite->sampler))) + { + WARN("Failed to create a sampler state, hr %#lx.\n", hr); + goto err; + } + + sprite->batch_size = size ? min(size, max_size) : max_size; + + buffer_desc.ByteWidth = vb_size = sprite->batch_size * 4 * sizeof(*sprite->vertex_data); + buffer_desc.Usage = D3D10_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; + buffer_desc.CPUAccessFlags = 0; + buffer_desc.MiscFlags = 0; + + if (FAILED(hr = ID3D10Device_CreateBuffer(device, &buffer_desc, NULL, &sprite->vb))) + { + WARN("Failed to create vertex buffer, hr %#lx.\n", hr); + goto err; + } + + buffer_desc.ByteWidth = sizeof(D3DXMATRIX); + buffer_desc.Usage = D3D10_USAGE_DYNAMIC; + buffer_desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER; + buffer_desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; + + if (FAILED(hr = ID3D10Device_CreateBuffer(device, &buffer_desc, NULL, &sprite->vs_cb))) + { + WARN("Failed to create a constant buffer, hr %#lx.\n", hr); + goto err; + } + + if (!(sprite->vertex_data = malloc(vb_size))) + { + hr = E_OUTOFMEMORY; + goto err; + } + + return S_OK; + +err: + d3dx10_sprite_cleanup(sprite); + if (vs) + ID3D10Blob_Release(vs); + if (ps) + ID3D10Blob_Release(ps); + + return hr; +} + HRESULT WINAPI D3DX10CreateSprite(ID3D10Device *device, UINT size, ID3DX10Sprite **sprite) { struct d3dx10_sprite *object; - D3D10_STATE_BLOCK_MASK mask; HRESULT hr; TRACE("device %p, size %u, sprite %p.\n", device, size, sprite); @@ -323,20 +653,9 @@ HRESULT WINAPI D3DX10CreateSprite(ID3D10Device *device, UINT size, ID3DX10Sprite if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; - object->ID3DX10Sprite_iface.lpVtbl = &d3dx10_sprite_vtbl; - object->refcount = 1; - object->device = device; - ID3D10Device_AddRef(device); - object->projection._11 = 1.0f; - object->projection._22 = 1.0f; - object->projection._33 = 1.0f; - object->projection._44 = 1.0f; - - /* TODO: we shouldn't be capturing entire state */ - D3D10StateBlockMaskEnableAll(&mask); - if (FAILED(hr = D3D10CreateStateBlock(device, &mask, &object->state_block))) + if (FAILED(hr = d3dx10_sprite_init(object, device, size))) { - ID3DX10Sprite_Release(&object->ID3DX10Sprite_iface); + free(object); return hr; } diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index c759a5fb35b..5a3b64da69a 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -7933,7 +7933,6 @@ static void test_sprite(void) /* Flush/End */ hr = ID3DX10Sprite_Flush(sprite); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_End(sprite); @@ -7968,11 +7967,9 @@ static void test_sprite(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_Flush(sprite); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_Flush(sprite); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_End(sprite); @@ -7991,7 +7988,6 @@ static void test_sprite(void) ok(get_refcount(srv1) > refcount, "Unexpected refcount.\n"); hr = ID3DX10Sprite_Flush(sprite); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(get_refcount(srv1) == refcount, "Unexpected refcount.\n"); @@ -8172,22 +8168,17 @@ static void test_sprite_render(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_Flush(sprite); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_End(sprite); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); color = get_texture_color(test_context.backbuffer, 160, 120); - todo_wine ok(compare_color(color, 0xff0000ff, 0), "Got unexpected color 0x%08x.\n", color); color = get_texture_color(test_context.backbuffer, 480, 120); - todo_wine ok(compare_color(color, 0xffff00ff, 0), "Got unexpected color 0x%08x.\n", color); color = get_texture_color(test_context.backbuffer, 160, 360); - todo_wine ok(compare_color(color, 0xffff0000, 0), "Got unexpected color 0x%08x.\n", color); color = get_texture_color(test_context.backbuffer, 480, 360); - todo_wine ok(compare_color(color, 0xff00ffff, 0), "Got unexpected color 0x%08x.\n", color); ID3DX10Sprite_Release(sprite); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11721
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/d3dx10_43/tests/d3dx10.c | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index 5a3b64da69a..e3aa23b07d8 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -8181,6 +8181,58 @@ static void test_sprite_render(void) color = get_texture_color(test_context.backbuffer, 480, 360); ok(compare_color(color, 0xff00ffff, 0), "Got unexpected color 0x%08x.\n", color); + /* Immediate draws with sprites in the batch */ + ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, clear); + + hr = ID3DX10Sprite_Begin(sprite, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + color = get_texture_color(test_context.backbuffer, 160, 120); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 120); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 160, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + + D3DXMatrixTranslation(&sprite_desc.matWorld, -0.5f, 0.5f, 0.0f); + sprite_desc.TexCoord.x = 0.0f; + sprite_desc.TexCoord.y = 0.0f; + sprite_desc.TexSize.x = 0.25f; + sprite_desc.TexSize.y = 0.25f; + hr = ID3DX10Sprite_DrawSpritesBuffered(sprite, &sprite_desc, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + color = get_texture_color(test_context.backbuffer, 160, 120); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 120); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 160, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + + D3DXMatrixTranslation(&sprite_desc.matWorld, 0.5f, 0.5f, 0.0f); + sprite_desc.TexCoord.x = 0.7f; + sprite_desc.TexCoord.y = 0.0f; + sprite_desc.TexSize.x = 0.25f; + sprite_desc.TexSize.y = 0.25f; + hr = ID3DX10Sprite_DrawSpritesImmediate(sprite, &sprite_desc, 1, sizeof(sprite_desc), 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + color = get_texture_color(test_context.backbuffer, 160, 120); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 120); + ok(compare_color(color, 0xffff00ff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 160, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + color = get_texture_color(test_context.backbuffer, 480, 360); + ok(compare_color(color, 0xffffffff, 0), "Got unexpected color 0x%08x.\n", color); + + hr = ID3DX10Sprite_End(sprite); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ID3DX10Sprite_Release(sprite); ID3D10Texture2D_Release(texture); ID3D10ShaderResourceView_Release(srv); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11721
From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/d3dx10_43/sprite.c | 22 ++++++++++++++++++---- dlls/d3dx10_43/tests/d3dx10.c | 10 ++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/dlls/d3dx10_43/sprite.c b/dlls/d3dx10_43/sprite.c index 133b33d381f..49c1eeae76e 100644 --- a/dlls/d3dx10_43/sprite.c +++ b/dlls/d3dx10_43/sprite.c @@ -409,16 +409,30 @@ static HRESULT WINAPI d3dx10_sprite_End(ID3DX10Sprite *iface) static HRESULT WINAPI d3dx10_sprite_GetViewTransform(ID3DX10Sprite *iface, D3DXMATRIX *transform) { - FIXME("iface %p, transform %p stub!\n", iface, transform); + struct d3dx10_sprite *sprite = impl_from_ID3DX10Sprite(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + if (!transform) + return E_FAIL; - return E_NOTIMPL; + *transform = sprite->view; + + return S_OK; } static HRESULT WINAPI d3dx10_sprite_SetViewTransform(ID3DX10Sprite *iface, D3DXMATRIX *transform) { - FIXME("iface %p, transform %p stub!\n", iface, transform); + struct d3dx10_sprite *sprite = impl_from_ID3DX10Sprite(iface); + + TRACE("iface %p, transform %p.\n", iface, transform); + + if (!transform) + return E_FAIL; - return E_NOTIMPL; + sprite->view = *transform; + + return S_OK; } static HRESULT WINAPI d3dx10_sprite_GetProjectionTransform(ID3DX10Sprite *iface, diff --git a/dlls/d3dx10_43/tests/d3dx10.c b/dlls/d3dx10_43/tests/d3dx10.c index e3aa23b07d8..0fc06144406 100644 --- a/dlls/d3dx10_43/tests/d3dx10.c +++ b/dlls/d3dx10_43/tests/d3dx10.c @@ -7916,12 +7916,18 @@ static void test_sprite(void) ok(!memcmp(&mat, &mat2, sizeof(mat)), "Unexpected matrix.\n"); /* View transform */ + hr = ID3DX10Sprite_GetViewTransform(sprite, NULL); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + + memset(&mat, 0, sizeof(mat)); + hr = ID3DX10Sprite_GetViewTransform(sprite, &mat); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!memcmp(&mat, &identity, sizeof(mat)), "Unexpected view transform.\n"); + hr = ID3DX10Sprite_SetViewTransform(sprite, NULL); - todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); hr = ID3DX10Sprite_SetViewTransform(sprite, &mat); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); /* Begin */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11721
participants (2)
-
Nikolay Sivov -
Nikolay Sivov (@nsivov)