Skip to content

Commit

Permalink
vkd3d: Implement baseline workgraph functionality.
Browse files Browse the repository at this point in the history
Good enough to bring up SimpleClassify and ComputeRasterizer demos.

Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
  • Loading branch information
HansKristian-Work committed Oct 16, 2024
1 parent 224982b commit 3840edf
Show file tree
Hide file tree
Showing 6 changed files with 3,372 additions and 7 deletions.
15 changes: 15 additions & 0 deletions include/vkd3d_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,21 @@ enum vkd3d_shader_node_launch_type
VKD3D_SHADER_NODE_LAUNCH_TYPE_THREAD = 3
};

/* For emulation path. */
struct vkd3d_shader_node_input_push_signature
{
VkDeviceAddress node_payload_bda;
VkDeviceAddress node_linear_offset_bda;
VkDeviceAddress node_total_nodes_bda;
VkDeviceAddress node_payload_stride_or_offsets_bda;
VkDeviceAddress node_payload_output_bda;
VkDeviceAddress node_payload_output_atomic_bda;
VkDeviceAddress local_root_signature_bda;
uint32_t node_payload_output_offset;
uint32_t node_payload_output_stride;
uint32_t node_remaining_recursion_levels;
};

struct vkd3d_shader_node_input_data
{
const char *node_id; /* This is often same as entry point name, but does not have to be. */
Expand Down
47 changes: 43 additions & 4 deletions libs/vkd3d/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -5701,6 +5701,7 @@ static void d3d12_command_list_reset_api_state(struct d3d12_command_list *list,

list->state = NULL;
list->rt_state = NULL;
memset(&list->wg_state, 0, sizeof(list->wg_state));
list->active_pipeline_type = VKD3D_PIPELINE_TYPE_NONE;

memset(list->so_buffers, 0, sizeof(list->so_buffers));
Expand Down Expand Up @@ -16869,14 +16870,52 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBufferStripCutValue(d
}
}

static void STDMETHODCALLTYPE d3d12_command_list_SetProgram(d3d12_command_list_iface *iface, const D3D12_SET_PROGRAM_DESC *desc)
static void STDMETHODCALLTYPE d3d12_command_list_SetProgram(
d3d12_command_list_iface *iface, const D3D12_SET_PROGRAM_DESC *desc)
{
FIXME("iface %p, desc %p, stub!\n", iface, desc);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
struct d3d12_wg_state_object *wg_state;
uint32_t wg_state_program_index;
TRACE("iface %p, desc %p\n", iface, desc);

if (desc->Type != D3D12_PROGRAM_TYPE_WORK_GRAPH)
{
FIXME("Unsupported type %u.\n", desc->Type);
memset(&list->wg_state, 0, sizeof(list->wg_state));
return;
}

list->wg_state = desc->WorkGraph;

/* We only get program identifier, not the state object? Spicy ... */
wg_state = (struct d3d12_wg_state_object *)(uintptr_t)desc->WorkGraph.ProgramIdentifier.OpaqueData[1];
wg_state_program_index = desc->WorkGraph.ProgramIdentifier.OpaqueData[0];

if (wg_state)
{
if (wg_state_program_index >= wg_state->programs_count)
{
ERR("program index %u is out of bounds (%u programs).\n",

Check warning on line 16898 in libs/vkd3d/command.c

View workflow job for this annotation

GitHub Actions / build-set-linux

format ‘%u’ expects argument of type ‘unsigned int’, but argument 6 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]

Check warning on line 16898 in libs/vkd3d/command.c

View workflow job for this annotation

GitHub Actions / build-set-linux

format ‘%u’ expects argument of type ‘unsigned int’, but argument 6 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
wg_state_program_index, wg_state->programs_count);
memset(&list->wg_state, 0, sizeof(list->wg_state));
return;
}

if (desc->WorkGraph.Flags & D3D12_SET_WORK_GRAPH_FLAG_INITIALIZE)
{
/* It's somewhat ambiguous if we should initialize scratch on SetProgram time or not.
* Assume we can. */
d3d12_command_list_workgraph_initialize_scratch(list);
}
}
}

static void STDMETHODCALLTYPE d3d12_command_list_DispatchGraph(d3d12_command_list_iface *iface, const D3D12_DISPATCH_GRAPH_DESC *desc)
static void STDMETHODCALLTYPE d3d12_command_list_DispatchGraph(
d3d12_command_list_iface *iface, const D3D12_DISPATCH_GRAPH_DESC *desc)
{
FIXME("iface %p, desc %p, stub!\n", iface, desc);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
TRACE("iface %p, desc %p\n", iface, desc);
d3d12_command_list_workgraph_dispatch(list, desc);
}

#define VKD3D_DECLARE_D3D12_GRAPHICS_COMMAND_LIST_VARIANT(name, set_table_variant) \
Expand Down
6 changes: 4 additions & 2 deletions libs/vkd3d/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -6951,8 +6951,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(d3d12_device_ifa

if (desc->Type == D3D12_STATE_OBJECT_TYPE_EXECUTABLE)
{
FIXME("Workgraph PSOs currently not supported.\n");
return E_NOTIMPL;
struct d3d12_wg_state_object *state;
if (FAILED(hr = d3d12_wg_state_object_create(device, desc, &state)))
return hr;
return return_interface(&state->ID3D12StateObject_iface, &IID_ID3D12StateObject, iid, state_object);
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion libs/vkd3d/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ vkd3d_src = [
'acceleration_structure.c',
'swapchain.c',
'queue_timeline.c',
'address_binding_tracker.c'
'address_binding_tracker.c',
'workgraphs.c'
]

if enable_renderdoc
Expand Down
50 changes: 50 additions & 0 deletions libs/vkd3d/vkd3d_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -2949,6 +2949,7 @@ struct d3d12_command_list

struct d3d12_pipeline_state *state;
struct d3d12_rt_state_object *rt_state;
D3D12_SET_WORK_GRAPH_DESC wg_state;
const struct d3d12_rt_state_object_variant *rt_state_variant;
uint32_t current_compute_meta_flags;

Expand Down Expand Up @@ -5372,6 +5373,7 @@ HRESULT d3d_blob_create(void *buffer, SIZE_T size, struct d3d_blob **blob);
/* ID3D12StateObject */
typedef ID3D12StateObject d3d12_state_object_iface;
typedef ID3D12StateObjectProperties1 d3d12_state_object_properties_iface;
typedef ID3D12WorkGraphProperties d3d12_work_graph_properties_iface;

struct d3d12_rt_state_object_identifier
{
Expand Down Expand Up @@ -5547,6 +5549,54 @@ static inline struct d3d12_rt_state_object *rt_impl_from_ID3D12StateObject(ID3D1
return CONTAINING_RECORD(iface, struct d3d12_rt_state_object, ID3D12StateObject_iface);
}

struct d3d12_wg_state_object_program;
struct d3d12_wg_state_object_module;

struct d3d12_wg_state_object_ring
{
VkBuffer vk_buffer;
VkDeviceAddress va;
struct vkd3d_device_memory_allocation allocation;
};

struct d3d12_wg_state_object
{
d3d12_state_object_iface ID3D12StateObject_iface;
d3d12_state_object_properties_iface ID3D12StateObjectProperties1_iface;
d3d12_work_graph_properties_iface ID3D12WorkGraphProperties_iface;
LONG refcount;
LONG internal_refcount;
D3D12_STATE_OBJECT_TYPE type;
struct d3d12_device *device;

struct d3d12_wg_state_object_program *programs;
size_t programs_count;

struct vkd3d_shader_library_entry_point *entry_points;
size_t entry_points_count;

struct d3d12_wg_state_object_module *modules;
size_t modules_count;

/* Very hacky. Allocate huge scratch buffers that can hold execution state.
* Generally speaking, these buffers should be allocated in ring-buffers on device. */
struct d3d12_wg_state_object_ring unrolled_offsets;
struct d3d12_wg_state_object_ring payload[2];

struct vkd3d_private_store private_store;
};

void d3d12_command_list_workgraph_initialize_scratch(struct d3d12_command_list *list);
void d3d12_command_list_workgraph_dispatch(struct d3d12_command_list *list, const D3D12_DISPATCH_GRAPH_DESC *desc);

static inline struct d3d12_wg_state_object *wg_impl_from_ID3D12StateObject(ID3D12StateObject *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_wg_state_object, ID3D12StateObject_iface);
}

HRESULT d3d12_wg_state_object_create(struct d3d12_device *device, const D3D12_STATE_OBJECT_DESC *desc,
struct d3d12_wg_state_object **object);

/* ID3D12MetaCommand */
struct d3d12_meta_command;

Expand Down
Loading

0 comments on commit 3840edf

Please sign in to comment.