d2d1/effect: Add a stub vertex buffer object.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2024-05-15 03:00:40 +02:00 committed by Alexandre Julliard
parent 26b89ce06d
commit 76eaa05c92
4 changed files with 169 additions and 32 deletions

View file

@ -159,6 +159,17 @@ enum d2d_device_context_target_type
D2D_TARGET_COMMAND_LIST,
};
struct d2d_indexed_objects
{
struct
{
GUID id;
IUnknown *object;
} *elements;
size_t size;
size_t count;
};
struct d2d_device_context
{
ID2D1DeviceContext6 ID2D1DeviceContext6_iface;
@ -208,6 +219,8 @@ struct d2d_device_context
D2D1_RENDER_TARGET_PROPERTIES desc;
D2D1_SIZE_U pixel_size;
struct d2d_clip_stack clip_stack;
struct d2d_indexed_objects vertex_buffers;
};
HRESULT d2d_d3d_create_render_target(struct d2d_device *device, IDXGISurface *surface, IUnknown *outer_unknown,
@ -594,17 +607,6 @@ HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *fac
D2D1_FILL_MODE fill_mode, ID2D1Geometry **src_geometries, unsigned int geometry_count);
struct d2d_geometry *unsafe_impl_from_ID2D1Geometry(ID2D1Geometry *iface);
struct d2d_indexed_objects
{
struct
{
GUID id;
IUnknown *object;
} *elements;
size_t size;
size_t count;
};
struct d2d_device
{
ID2D1Device6 ID2D1Device6_iface;
@ -618,7 +620,9 @@ struct d2d_device
struct d2d_device *unsafe_impl_from_ID2D1Device(ID2D1Device1 *iface);
HRESULT d2d_device_add_indexed_object(struct d2d_indexed_objects *objects, const GUID *id,
IUnknown *object);
BOOL d2d_device_is_object_indexed(struct d2d_indexed_objects *objects, const GUID *id);
BOOL d2d_device_get_indexed_object(struct d2d_indexed_objects *objects, const GUID *id,
IUnknown **object);
void d2d_device_indexed_objects_clear(struct d2d_indexed_objects *objects);
struct d2d_effect_context
{
@ -799,6 +803,12 @@ HRESULT d2d_factory_register_builtin_effect(struct d2d_factory *factory, REFCLSI
const WCHAR *property_xml, const D2D1_PROPERTY_BINDING *bindings, UINT32 binding_count,
PD2D1_EFFECT_FACTORY effect_factory);
struct d2d_vertex_buffer
{
ID2D1VertexBuffer ID2D1VertexBuffer_iface;
LONG refcount;
};
enum d2d_command_list_state
{
D2D_COMMAND_LIST_STATE_INITIAL = 0,

View file

@ -304,6 +304,7 @@ static ULONG STDMETHODCALLTYPE d2d_device_context_inner_Release(IUnknown *iface)
ID3D11Device1_Release(context->d3d_device);
ID2D1Factory_Release(context->factory);
ID2D1Device6_Release(&context->device->ID2D1Device6_iface);
d2d_device_indexed_objects_clear(&context->vertex_buffers);
free(context);
}
@ -4282,7 +4283,7 @@ static ULONG WINAPI d2d_device_AddRef(ID2D1Device6 *iface)
return refcount;
}
static void d2d_device_indexed_objects_clear(struct d2d_indexed_objects *objects)
void d2d_device_indexed_objects_clear(struct d2d_indexed_objects *objects)
{
size_t i;
@ -4546,15 +4547,24 @@ HRESULT d2d_device_add_indexed_object(struct d2d_indexed_objects *objects,
return S_OK;
}
BOOL d2d_device_is_object_indexed(struct d2d_indexed_objects *objects, const GUID *id)
BOOL d2d_device_get_indexed_object(struct d2d_indexed_objects *objects, const GUID *id,
IUnknown **object)
{
size_t i;
size_t i;
for (i = 0; i < objects->count; ++i)
{
if (IsEqualGUID(id, &objects->elements[i].id))
return TRUE;
}
for (i = 0; i < objects->count; ++i)
{
if (IsEqualGUID(id, &objects->elements[i].id))
{
if (object)
{
*object = objects->elements[i].object;
IUnknown_AddRef(*object);
}
return TRUE;
}
}
return FALSE;
if (object) *object = NULL;
return FALSE;
}

View file

@ -41,6 +41,90 @@ static inline struct d2d_transform *impl_from_ID2D1BoundsAdjustmentTransform(
return CONTAINING_RECORD(iface, struct d2d_transform, ID2D1TransformNode_iface);
}
static inline struct d2d_vertex_buffer *impl_from_ID2D1VertexBuffer(ID2D1VertexBuffer *iface)
{
return CONTAINING_RECORD(iface, struct d2d_vertex_buffer, ID2D1VertexBuffer_iface);
}
static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_QueryInterface(ID2D1VertexBuffer *iface,
REFIID iid, void **out)
{
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualGUID(iid, &IID_ID2D1VertexBuffer)
|| IsEqualGUID(iid, &IID_IUnknown))
{
*out = iface;
ID2D1VertexBuffer_AddRef(iface);
return S_OK;
}
WARN("Unsupported interface %s.\n", debugstr_guid(iid));
*out = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d2d_vertex_buffer_AddRef(ID2D1VertexBuffer *iface)
{
struct d2d_vertex_buffer *buffer = impl_from_ID2D1VertexBuffer(iface);
ULONG refcount = InterlockedIncrement(&buffer->refcount);
TRACE("%p increasing refcount to %lu.\n", iface, refcount);
return refcount;
}
static ULONG STDMETHODCALLTYPE d2d_vertex_buffer_Release(ID2D1VertexBuffer *iface)
{
struct d2d_vertex_buffer *buffer = impl_from_ID2D1VertexBuffer(iface);
ULONG refcount = InterlockedDecrement(&buffer->refcount);
TRACE("%p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount)
free(buffer);
return refcount;
}
static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_Map(ID2D1VertexBuffer *iface, BYTE **data, UINT32 size)
{
FIXME("iface %p, data %p, size %u.\n", iface, data, size);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d2d_vertex_buffer_Unmap(ID2D1VertexBuffer *iface)
{
FIXME("iface %p.\n", iface);
return E_NOTIMPL;
}
static const ID2D1VertexBufferVtbl d2d_vertex_buffer_vtbl =
{
d2d_vertex_buffer_QueryInterface,
d2d_vertex_buffer_AddRef,
d2d_vertex_buffer_Release,
d2d_vertex_buffer_Map,
d2d_vertex_buffer_Unmap,
};
static HRESULT d2d_vertex_buffer_create(ID2D1VertexBuffer **buffer)
{
struct d2d_vertex_buffer *object;
if (!(object = calloc(1, sizeof(*object))))
return E_OUTOFMEMORY;
object->ID2D1VertexBuffer_iface.lpVtbl = &d2d_vertex_buffer_vtbl;
object->refcount = 1;
*buffer = &object->ID2D1VertexBuffer_iface;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d2d_offset_transform_QueryInterface(ID2D1OffsetTransform *iface,
REFIID iid, void **out)
{
@ -1458,7 +1542,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadPixelShader(ID2D1EffectC
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
iface, debugstr_guid(shader_id), buffer, buffer_size);
if (d2d_device_is_object_indexed(&device->shaders, shader_id))
if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL))
return S_OK;
if (FAILED(hr = ID3D11Device1_CreatePixelShader(effect_context->device_context->d3d_device,
@ -1485,7 +1569,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadVertexShader(ID2D1Effect
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
iface, debugstr_guid(shader_id), buffer, buffer_size);
if (d2d_device_is_object_indexed(&device->shaders, shader_id))
if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL))
return S_OK;
if (FAILED(hr = ID3D11Device1_CreateVertexShader(effect_context->device_context->d3d_device,
@ -1512,7 +1596,7 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_LoadComputeShader(ID2D1Effec
TRACE("iface %p, shader_id %s, buffer %p, buffer_size %u.\n",
iface, debugstr_guid(shader_id), buffer, buffer_size);
if (d2d_device_is_object_indexed(&device->shaders, shader_id))
if (d2d_device_get_indexed_object(&device->shaders, shader_id, NULL))
return S_OK;
if (FAILED(hr = ID3D11Device1_CreateComputeShader(effect_context->device_context->d3d_device,
@ -1535,7 +1619,7 @@ static BOOL STDMETHODCALLTYPE d2d_effect_context_IsShaderLoaded(ID2D1EffectConte
TRACE("iface %p, shader_id %s.\n", iface, debugstr_guid(shader_id));
return d2d_device_is_object_indexed(&device->shaders, shader_id);
return d2d_device_get_indexed_object(&device->shaders, shader_id, NULL);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateResourceTexture(ID2D1EffectContext *iface,
@ -1558,20 +1642,43 @@ static HRESULT STDMETHODCALLTYPE d2d_effect_context_FindResourceTexture(ID2D1Eff
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateVertexBuffer(ID2D1EffectContext *iface,
const D2D1_VERTEX_BUFFER_PROPERTIES *buffer_properties, const GUID *id,
const D2D1_CUSTOM_VERTEX_BUFFER_PROPERTIES *custom_buffer_properties, ID2D1VertexBuffer **buffer)
const D2D1_CUSTOM_VERTEX_BUFFER_PROPERTIES *custom_buffer_properties,
ID2D1VertexBuffer **buffer)
{
struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface);
struct d2d_device_context *context = effect_context->device_context;
HRESULT hr;
FIXME("iface %p, buffer_properties %p, id %s, custom_buffer_properties %p, buffer %p stub!\n",
iface, buffer_properties, debugstr_guid(id), custom_buffer_properties, buffer);
return E_NOTIMPL;
if (id && d2d_device_get_indexed_object(&context->vertex_buffers, id, (IUnknown **)buffer))
return S_OK;
if (SUCCEEDED(hr = d2d_vertex_buffer_create(buffer)))
{
if (id)
hr = d2d_device_add_indexed_object(&context->vertex_buffers, id, (IUnknown *)*buffer);
}
if (FAILED(hr))
*buffer = NULL;
return hr;
}
static HRESULT STDMETHODCALLTYPE d2d_effect_context_FindVertexBuffer(ID2D1EffectContext *iface,
const GUID *id, ID2D1VertexBuffer **buffer)
{
FIXME("iface %p, id %s, buffer %p stub!\n", iface, debugstr_guid(id), buffer);
struct d2d_effect_context *effect_context = impl_from_ID2D1EffectContext(iface);
struct d2d_device_context *context = effect_context->device_context;
return E_NOTIMPL;
TRACE("iface %p, id %s, buffer %p.\n", iface, debugstr_guid(id), buffer);
if (!d2d_device_get_indexed_object(&context->vertex_buffers, id, (IUnknown **)buffer))
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d2d_effect_context_CreateColorContext(ID2D1EffectContext *iface,

View file

@ -14965,37 +14965,48 @@ static void test_effect_vertex_buffer(BOOL d3d11)
buffer_desc.byteWidth = sizeof(data);
hr = ID2D1EffectContext_CreateVertexBuffer(effect_context, &buffer_desc, NULL, NULL, &buffer);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
if (FAILED(hr)) goto end;
hr = ID2D1EffectContext_CreateVertexBuffer(effect_context, &buffer_desc, NULL, NULL, &buffer2);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(buffer != buffer2, "Unexpected buffer instance.\n");
ID2D1VertexBuffer_Release(buffer2);
/* Mapping static buffer. */
ptr = NULL;
hr = ID2D1VertexBuffer_Map(buffer, &ptr, buffer_desc.byteWidth);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine
ok(!!ptr, "Unexpected pointer.\n");
hr = ID2D1VertexBuffer_Unmap(buffer);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = ID2D1VertexBuffer_Map(buffer, &ptr, buffer_desc.byteWidth + 1);
todo_wine
ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr);
hr = ID2D1VertexBuffer_Map(buffer, &ptr, buffer_desc.byteWidth - 1);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine
ok(!!ptr, "Unexpected pointer.\n");
hr = ID2D1VertexBuffer_Unmap(buffer);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
/* Map already mapped. */
hr = ID2D1VertexBuffer_Map(buffer, &ptr, buffer_desc.byteWidth);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine
ok(!!ptr, "Unexpected pointer.\n");
ptr2 = NULL;
hr = ID2D1VertexBuffer_Map(buffer, &ptr2, buffer_desc.byteWidth);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(ptr == ptr2, "Unexpected pointer.\n");
hr = ID2D1VertexBuffer_Unmap(buffer);
todo_wine
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ID2D1VertexBuffer_Release(buffer);
@ -15084,7 +15095,6 @@ static void test_effect_vertex_buffer(BOOL d3d11)
ID2D1Device_Release(device);
end:
ID2D1Effect_Release(effect);
hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);