mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
libs/vkd3d: Implement indirect draws.
This commit is contained in:
parent
882d54dacb
commit
b000952e4f
@ -3282,14 +3282,52 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandL
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList *iface,
|
||||
ID3D12CommandSignature *command_signature,
|
||||
UINT max_command_count, ID3D12Resource *arg_buffer,
|
||||
ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer,
|
||||
UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset)
|
||||
{
|
||||
FIXME("iface %p, command_signature %p, max_command_count %u, arg_buffer %p, "
|
||||
"arg_buffer_offset %#"PRIx64", count_buffer %p, count_buffer_offset %#"PRIx64" stub!\n",
|
||||
struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature);
|
||||
struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer);
|
||||
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
||||
const D3D12_COMMAND_SIGNATURE_DESC *signature_desc;
|
||||
unsigned int i;
|
||||
|
||||
TRACE("iface %p, command_signature %p, max_command_count %u, arg_buffer %p, "
|
||||
"arg_buffer_offset %#"PRIx64", count_buffer %p, count_buffer_offset %#"PRIx64".\n",
|
||||
iface, command_signature, max_command_count, arg_buffer, arg_buffer_offset,
|
||||
count_buffer, count_buffer_offset);
|
||||
|
||||
if (count_buffer)
|
||||
{
|
||||
FIXME("Count buffers not implemented.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
signature_desc = &sig_impl->desc;
|
||||
for (i = 0; i < signature_desc->NumArgumentDescs; ++i)
|
||||
{
|
||||
const D3D12_INDIRECT_ARGUMENT_DESC *arg_desc = &signature_desc->pArgumentDescs[i];
|
||||
|
||||
switch (arg_desc->Type)
|
||||
{
|
||||
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
|
||||
if (!d3d12_command_list_begin_render_pass(list, vk_procs))
|
||||
{
|
||||
WARN("Failed to begin render pass, ignoring draw.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
VK_CALL(vkCmdDrawIndirect(list->vk_command_buffer, arg_impl->u.vk_buffer,
|
||||
arg_buffer_offset, max_command_count, signature_desc->ByteStride));
|
||||
|
||||
VK_CALL(vkCmdEndRenderPass(list->vk_command_buffer));
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Ignoring unhandled argument type %#x.\n", arg_desc->Type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct ID3D12GraphicsCommandListVtbl d3d12_command_list_vtbl =
|
||||
@ -3888,6 +3926,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSign
|
||||
{
|
||||
struct d3d12_device *device = signature->device;
|
||||
|
||||
vkd3d_free((void *)signature->desc.pArgumentDescs);
|
||||
vkd3d_free(signature);
|
||||
|
||||
ID3D12Device_Release(&device->ID3D12Device_iface);
|
||||
@ -3952,7 +3991,16 @@ static const struct ID3D12CommandSignatureVtbl d3d12_command_signature_vtbl =
|
||||
d3d12_command_signature_GetDevice,
|
||||
};
|
||||
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device, struct d3d12_command_signature **signature)
|
||||
struct d3d12_command_signature *unsafe_impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface)
|
||||
{
|
||||
if (!iface)
|
||||
return NULL;
|
||||
assert(iface->lpVtbl == &d3d12_command_signature_vtbl);
|
||||
return CONTAINING_RECORD(iface, struct d3d12_command_signature, ID3D12CommandSignature_iface);
|
||||
}
|
||||
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_COMMAND_SIGNATURE_DESC *desc,
|
||||
struct d3d12_command_signature **signature)
|
||||
{
|
||||
struct d3d12_command_signature *object;
|
||||
|
||||
@ -3961,6 +4009,16 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, struct d3d12
|
||||
|
||||
object->ID3D12CommandSignature_iface.lpVtbl = &d3d12_command_signature_vtbl;
|
||||
object->refcount = 1;
|
||||
|
||||
object->desc = *desc;
|
||||
if (!(object->desc.pArgumentDescs = vkd3d_calloc(desc->NumArgumentDescs, sizeof(*desc->pArgumentDescs))))
|
||||
{
|
||||
vkd3d_free(object);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
memcpy((void *)object->desc.pArgumentDescs, desc->pArgumentDescs,
|
||||
desc->NumArgumentDescs * sizeof(*desc->pArgumentDescs));
|
||||
|
||||
object->device = device;
|
||||
ID3D12Device_AddRef(&device->ID3D12Device_iface);
|
||||
|
||||
|
@ -1444,7 +1444,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic
|
||||
TRACE("iface %p, desc %p, root_signature %p, iid %s, command_signature %p.\n",
|
||||
iface, desc, root_signature, debugstr_guid(iid), command_signature);
|
||||
|
||||
if (FAILED(hr = d3d12_command_signature_create(device, &object)))
|
||||
if (FAILED(hr = d3d12_command_signature_create(device, desc, &object)))
|
||||
return hr;
|
||||
|
||||
return return_interface((IUnknown *)&object->ID3D12CommandSignature_iface,
|
||||
|
@ -494,11 +494,14 @@ struct d3d12_command_signature
|
||||
ID3D12CommandSignature ID3D12CommandSignature_iface;
|
||||
LONG refcount;
|
||||
|
||||
D3D12_COMMAND_SIGNATURE_DESC desc;
|
||||
|
||||
struct d3d12_device *device;
|
||||
};
|
||||
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device,
|
||||
HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_COMMAND_SIGNATURE_DESC *desc,
|
||||
struct d3d12_command_signature **signature) DECLSPEC_HIDDEN;
|
||||
struct d3d12_command_signature *unsafe_impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface) DECLSPEC_HIDDEN;
|
||||
|
||||
struct vkd3d_vulkan_info
|
||||
{
|
||||
|
@ -11488,6 +11488,56 @@ static void test_query_pipeline_statistics(void)
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
static void test_execute_indirect(void)
|
||||
{
|
||||
D3D12_COMMAND_SIGNATURE_DESC signature_desc;
|
||||
D3D12_INDIRECT_ARGUMENT_DESC argument_desc;
|
||||
ID3D12CommandSignature *command_signature;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
ID3D12Resource *argument_buffer;
|
||||
struct test_context context;
|
||||
ID3D12CommandQueue *queue;
|
||||
HRESULT hr;
|
||||
|
||||
static const D3D12_DRAW_ARGUMENTS argument_data = {3, 1, 0, 0};
|
||||
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
if (!init_test_context(&context, NULL))
|
||||
return;
|
||||
command_list = context.list;
|
||||
queue = context.queue;
|
||||
|
||||
argument_buffer = create_upload_buffer(context.device, sizeof(argument_data), &argument_data);
|
||||
|
||||
argument_desc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
|
||||
|
||||
signature_desc.ByteStride = sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
signature_desc.NumArgumentDescs = 1;
|
||||
signature_desc.pArgumentDescs = &argument_desc;
|
||||
signature_desc.NodeMask = 0;
|
||||
hr = ID3D12Device_CreateCommandSignature(context.device, &signature_desc,
|
||||
NULL, &IID_ID3D12CommandSignature, (void **)&command_signature);
|
||||
ok(SUCCEEDED(hr), "Failed to create command signature, hr %#x.\n", hr);
|
||||
|
||||
ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
|
||||
|
||||
ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
|
||||
ID3D12GraphicsCommandList_ExecuteIndirect(command_list, command_signature, 1, argument_buffer, 0, NULL, 0);
|
||||
|
||||
transition_resource_state(command_list, context.render_target,
|
||||
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
|
||||
|
||||
ID3D12CommandSignature_Release(command_signature);
|
||||
ID3D12Resource_Release(argument_buffer);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
START_TEST(d3d12)
|
||||
{
|
||||
bool enable_debug_layer = false;
|
||||
@ -11561,4 +11611,5 @@ START_TEST(d3d12)
|
||||
run_test(test_create_query_heap);
|
||||
run_test(test_query_timestamp);
|
||||
run_test(test_query_pipeline_statistics);
|
||||
run_test(test_execute_indirect);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user