d3d11: Implement ID3D11DeviceContext::FinishCommandList().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
97d3ea26b9
commit
01658a4a8e
|
@ -583,6 +583,16 @@ struct d3d_device
|
|||
SIZE_T context_state_count;
|
||||
};
|
||||
|
||||
struct d3d11_command_list
|
||||
{
|
||||
ID3D11CommandList ID3D11CommandList_iface;
|
||||
LONG refcount;
|
||||
|
||||
ID3D11Device2 *device;
|
||||
struct wined3d_command_list *wined3d_list;
|
||||
struct wined3d_private_store private_store;
|
||||
};
|
||||
|
||||
static inline struct d3d_device *impl_from_ID3D11Device(ID3D11Device *iface)
|
||||
{
|
||||
return CONTAINING_RECORD((ID3D11Device2 *)iface, struct d3d_device, ID3D11Device2_iface);
|
||||
|
|
|
@ -330,6 +330,124 @@ static void d3d_device_context_state_init(struct d3d_device_context_state *state
|
|||
d3d_device_context_state_AddRef(&state->ID3DDeviceContextState_iface);
|
||||
}
|
||||
|
||||
/* ID3D11CommandList methods */
|
||||
|
||||
static inline struct d3d11_command_list *impl_from_ID3D11CommandList(ID3D11CommandList *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct d3d11_command_list, ID3D11CommandList_iface);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_command_list_QueryInterface(ID3D11CommandList *iface, REFIID iid, void **out)
|
||||
{
|
||||
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||
|
||||
if (IsEqualGUID(iid, &IID_ID3D11CommandList)
|
||||
|| IsEqualGUID(iid, &IID_ID3D11DeviceChild)
|
||||
|| IsEqualGUID(iid, &IID_IUnknown))
|
||||
{
|
||||
ID3D11CommandList_AddRef(iface);
|
||||
*out = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||
*out = NULL;
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE d3d11_command_list_AddRef(ID3D11CommandList *iface)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
ULONG refcount = InterlockedIncrement(&list->refcount);
|
||||
|
||||
TRACE("%p increasing refcount to %u.\n", list, refcount);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE d3d11_command_list_Release(ID3D11CommandList *iface)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
ULONG refcount = InterlockedDecrement(&list->refcount);
|
||||
|
||||
TRACE("%p decreasing refcount to %u.\n", list, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
wined3d_mutex_lock();
|
||||
wined3d_command_list_decref(list->wined3d_list);
|
||||
wined3d_mutex_unlock();
|
||||
wined3d_private_store_cleanup(&list->private_store);
|
||||
ID3D11Device2_Release(list->device);
|
||||
heap_free(list);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d11_command_list_GetDevice(ID3D11CommandList *iface, ID3D11Device **device)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
|
||||
TRACE("iface %p, device %p.\n", iface, device);
|
||||
|
||||
*device = (ID3D11Device *)list->device;
|
||||
ID3D11Device2_AddRef(list->device);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_command_list_GetPrivateData(ID3D11CommandList *iface, REFGUID guid,
|
||||
UINT *data_size, void *data)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
|
||||
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
||||
|
||||
return d3d_get_private_data(&list->private_store, guid, data_size, data);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_command_list_SetPrivateData(ID3D11CommandList *iface, REFGUID guid,
|
||||
UINT data_size, const void *data)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
|
||||
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
||||
|
||||
return d3d_set_private_data(&list->private_store, guid, data_size, data);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d3d11_command_list_SetPrivateDataInterface(ID3D11CommandList *iface,
|
||||
REFGUID guid, const IUnknown *data)
|
||||
{
|
||||
struct d3d11_command_list *list = impl_from_ID3D11CommandList(iface);
|
||||
|
||||
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
|
||||
|
||||
return d3d_set_private_data_interface(&list->private_store, guid, data);
|
||||
}
|
||||
|
||||
static UINT STDMETHODCALLTYPE d3d11_command_list_GetContextFlags(ID3D11CommandList *iface)
|
||||
{
|
||||
TRACE("iface %p.\n", iface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ID3D11CommandListVtbl d3d11_command_list_vtbl =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
d3d11_command_list_QueryInterface,
|
||||
d3d11_command_list_AddRef,
|
||||
d3d11_command_list_Release,
|
||||
/* ID3D11DeviceChild methods */
|
||||
d3d11_command_list_GetDevice,
|
||||
d3d11_command_list_GetPrivateData,
|
||||
d3d11_command_list_SetPrivateData,
|
||||
d3d11_command_list_SetPrivateDataInterface,
|
||||
/* ID3D11CommandList methods */
|
||||
d3d11_command_list_GetContextFlags,
|
||||
};
|
||||
|
||||
static void d3d11_device_context_cleanup(struct d3d11_device_context *context)
|
||||
{
|
||||
wined3d_private_store_cleanup(&context->private_store);
|
||||
|
@ -2635,9 +2753,44 @@ static UINT STDMETHODCALLTYPE d3d11_device_context_GetContextFlags(ID3D11DeviceC
|
|||
static HRESULT STDMETHODCALLTYPE d3d11_device_context_FinishCommandList(ID3D11DeviceContext1 *iface,
|
||||
BOOL restore, ID3D11CommandList **command_list)
|
||||
{
|
||||
struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface);
|
||||
struct d3d11_command_list *object;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, restore %#x, command_list %p.\n", iface, restore, command_list);
|
||||
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
if (context->type == D3D11_DEVICE_CONTEXT_IMMEDIATE)
|
||||
{
|
||||
WARN("Attempt to record command list on an immediate context; returning DXGI_ERROR_INVALID_CALL.\n");
|
||||
return DXGI_ERROR_INVALID_CALL;
|
||||
}
|
||||
|
||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
|
||||
if (FAILED(hr = wined3d_deferred_context_record_command_list(context->wined3d_context,
|
||||
!!restore, &object->wined3d_list)))
|
||||
{
|
||||
WARN("Failed to record wined3d command list, hr %#x.\n", hr);
|
||||
heap_free(object);
|
||||
return hr;
|
||||
}
|
||||
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
object->ID3D11CommandList_iface.lpVtbl = &d3d11_command_list_vtbl;
|
||||
object->refcount = 1;
|
||||
object->device = &context->device->ID3D11Device2_iface;
|
||||
wined3d_private_store_init(&object->private_store);
|
||||
|
||||
ID3D11Device2_AddRef(object->device);
|
||||
|
||||
TRACE("Created command list %p.\n", object);
|
||||
*command_list = &object->ID3D11CommandList_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d11_device_context_CopySubresourceRegion1(ID3D11DeviceContext1 *iface,
|
||||
|
|
|
@ -26,6 +26,59 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
|
|||
|
||||
#define WINED3D_INITIAL_CS_SIZE 4096
|
||||
|
||||
struct wined3d_command_list
|
||||
{
|
||||
LONG refcount;
|
||||
|
||||
struct wined3d_device *device;
|
||||
|
||||
SIZE_T data_size;
|
||||
void *data;
|
||||
|
||||
SIZE_T resource_count;
|
||||
struct wined3d_resource **resources;
|
||||
};
|
||||
|
||||
static void wined3d_command_list_destroy_object(void *object)
|
||||
{
|
||||
struct wined3d_command_list *list = object;
|
||||
|
||||
TRACE("list %p.\n", list);
|
||||
|
||||
heap_free(list->resources);
|
||||
heap_free(list->data);
|
||||
heap_free(list);
|
||||
}
|
||||
|
||||
ULONG CDECL wined3d_command_list_incref(struct wined3d_command_list *list)
|
||||
{
|
||||
ULONG refcount = InterlockedIncrement(&list->refcount);
|
||||
|
||||
TRACE("%p increasing refcount to %u.\n", list, refcount);
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list)
|
||||
{
|
||||
ULONG refcount = InterlockedDecrement(&list->refcount);
|
||||
struct wined3d_device *device = list->device;
|
||||
|
||||
TRACE("%p decreasing refcount to %u.\n", list, refcount);
|
||||
|
||||
if (!refcount)
|
||||
{
|
||||
SIZE_T i;
|
||||
|
||||
for (i = 0; i < list->resource_count; ++i)
|
||||
wined3d_resource_decref(list->resources[i]);
|
||||
|
||||
wined3d_cs_destroy_object(device->cs, wined3d_command_list_destroy_object, list);
|
||||
}
|
||||
|
||||
return refcount;
|
||||
}
|
||||
|
||||
enum wined3d_cs_op
|
||||
{
|
||||
WINED3D_CS_OP_NOP,
|
||||
|
@ -3333,3 +3386,53 @@ void CDECL wined3d_deferred_context_destroy(struct wined3d_device_context *conte
|
|||
heap_free(deferred->data);
|
||||
heap_free(deferred);
|
||||
}
|
||||
|
||||
HRESULT CDECL wined3d_deferred_context_record_command_list(struct wined3d_device_context *context,
|
||||
bool restore, struct wined3d_command_list **list)
|
||||
{
|
||||
struct wined3d_deferred_context *deferred = wined3d_deferred_context_from_context(context);
|
||||
struct wined3d_command_list *object;
|
||||
|
||||
TRACE("context %p, list %p.\n", context, list);
|
||||
|
||||
if (restore)
|
||||
{
|
||||
FIXME("Restoring context state is not implemented.\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (!(object = heap_alloc_zero(sizeof(*object))))
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->refcount = 1;
|
||||
object->device = deferred->c.device;
|
||||
|
||||
if (!(object->data = heap_alloc(deferred->data_size)))
|
||||
{
|
||||
heap_free(object);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
object->data_size = deferred->data_size;
|
||||
memcpy(object->data, deferred->data, deferred->data_size);
|
||||
|
||||
if (!(object->resources = heap_alloc(deferred->resource_count * sizeof(*object->resources))))
|
||||
{
|
||||
heap_free(object->data);
|
||||
heap_free(object);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
object->resource_count = deferred->resource_count;
|
||||
memcpy(object->resources, deferred->resources, deferred->resource_count * sizeof(*object->resources));
|
||||
/* Transfer our references to the resources to the command list. */
|
||||
|
||||
deferred->data_size = 0;
|
||||
deferred->resource_count = 0;
|
||||
|
||||
/* This is in fact recorded into a subsequent command list. */
|
||||
wined3d_device_context_reset_state(&deferred->c);
|
||||
|
||||
TRACE("Created command list %p.\n", object);
|
||||
*list = object;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,12 @@
|
|||
@ cdecl wined3d_buffer_get_resource(ptr)
|
||||
@ cdecl wined3d_buffer_incref(ptr)
|
||||
|
||||
@ cdecl wined3d_command_list_decref(ptr)
|
||||
@ cdecl wined3d_command_list_incref(ptr)
|
||||
|
||||
@ cdecl wined3d_deferred_context_create(ptr ptr)
|
||||
@ cdecl wined3d_deferred_context_destroy(ptr)
|
||||
@ cdecl wined3d_deferred_context_record_command_list(ptr long ptr)
|
||||
|
||||
@ cdecl wined3d_depth_stencil_state_create(ptr ptr ptr ptr ptr)
|
||||
@ cdecl wined3d_depth_stencil_state_decref(ptr)
|
||||
|
|
|
@ -2221,6 +2221,7 @@ struct wined3d;
|
|||
struct wined3d_adapter;
|
||||
struct wined3d_blend_state;
|
||||
struct wined3d_buffer;
|
||||
struct wined3d_command_list;
|
||||
struct wined3d_depth_stencil_state;
|
||||
struct wined3d_device;
|
||||
struct wined3d_device_context;
|
||||
|
@ -2340,8 +2341,13 @@ void * __cdecl wined3d_buffer_get_parent(const struct wined3d_buffer *buffer);
|
|||
struct wined3d_resource * __cdecl wined3d_buffer_get_resource(struct wined3d_buffer *buffer);
|
||||
ULONG __cdecl wined3d_buffer_incref(struct wined3d_buffer *buffer);
|
||||
|
||||
ULONG __cdecl wined3d_command_list_decref(struct wined3d_command_list *list);
|
||||
ULONG __cdecl wined3d_command_list_incref(struct wined3d_command_list *list);
|
||||
|
||||
HRESULT __cdecl wined3d_deferred_context_create(struct wined3d_device *device, struct wined3d_device_context **context);
|
||||
void __cdecl wined3d_deferred_context_destroy(struct wined3d_device_context *context);
|
||||
HRESULT __cdecl wined3d_deferred_context_record_command_list(struct wined3d_device_context *context,
|
||||
bool restore, struct wined3d_command_list **list);
|
||||
|
||||
HRESULT __cdecl wined3d_depth_stencil_state_create(struct wined3d_device *device,
|
||||
const struct wined3d_depth_stencil_state_desc *desc, void *parent,
|
||||
|
|
Loading…
Reference in New Issue