Skip to content

Commit

Permalink
Implement indirect draws
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 30, 2024
1 parent 9a28393 commit dcdedd3
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@
#include <WinPixEventRuntime/pix3.h>
#endif

void kope_d3d12_command_list_destroy(kope_g5_command_list *list) {
list->d3d12.list->Release();
}

void kope_d3d12_command_list_begin_render_pass(kope_g5_command_list *list, const kope_g5_render_pass_parameters *parameters) {
list->d3d12.compute_pipeline_set = false;
list->d3d12.compute_pipe = NULL;
list->d3d12.ray_pipe = NULL;

D3D12_CPU_DESCRIPTOR_HANDLE render_target_views = list->d3d12.rtv_descriptors->GetCPUDescriptorHandleForHeapStart();

Expand Down Expand Up @@ -196,6 +201,10 @@ void kope_d3d12_command_list_set_vertex_buffer(kope_g5_command_list *list, uint3
}

void kope_d3d12_command_list_set_render_pipeline(kope_g5_command_list *list, kope_d3d12_render_pipeline *pipeline) {
list->d3d12.render_pipe = pipeline;
list->d3d12.ray_pipe = NULL;
list->d3d12.compute_pipe = NULL;

list->d3d12.list->SetPipelineState(pipeline->pipe);
list->d3d12.list->SetGraphicsRootSignature(pipeline->root_signature);
}
Expand All @@ -215,7 +224,7 @@ void kope_d3d12_command_list_set_descriptor_table(kope_g5_command_list *list, ui
if (set->descriptor_count > 0) {
D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor = list->d3d12.device->descriptor_heap->GetGPUDescriptorHandleForHeapStart();
gpu_descriptor.ptr += set->descriptor_allocation.offset * list->d3d12.device->cbv_srv_uav_increment;
if (list->d3d12.compute_pipeline_set) {
if (list->d3d12.compute_pipe != NULL || list->d3d12.ray_pipe != NULL) {
list->d3d12.list->SetComputeRootDescriptorTable(table_index, gpu_descriptor);
}
else {
Expand All @@ -227,7 +236,7 @@ void kope_d3d12_command_list_set_descriptor_table(kope_g5_command_list *list, ui
if (set->sampler_count > 0) {
D3D12_GPU_DESCRIPTOR_HANDLE gpu_descriptor = list->d3d12.device->sampler_heap->GetGPUDescriptorHandleForHeapStart();
gpu_descriptor.ptr += set->sampler_allocation.offset * list->d3d12.device->sampler_increment;
if (list->d3d12.compute_pipeline_set) {
if (list->d3d12.compute_pipe != NULL || list->d3d12.ray_pipe != NULL) {
list->d3d12.list->SetComputeRootDescriptorTable(table_index, gpu_descriptor);
}
else {
Expand All @@ -237,7 +246,7 @@ void kope_d3d12_command_list_set_descriptor_table(kope_g5_command_list *list, ui
}

void kope_d3d12_command_list_set_root_constants(kope_g5_command_list *list, uint32_t table_index, const void *data, size_t data_size) {
if (list->d3d12.compute_pipeline_set) {
if (list->d3d12.compute_pipe != NULL || list->d3d12.ray_pipe != NULL) {
list->d3d12.list->SetComputeRoot32BitConstants(table_index, (UINT)(data_size / 4), data, 0);
}
else {
Expand Down Expand Up @@ -484,7 +493,9 @@ void kope_d3d12_command_list_clear_buffer(kope_g5_command_list *list, kope_g5_bu
}

void kope_d3d12_command_list_set_compute_pipeline(kope_g5_command_list *list, kope_d3d12_compute_pipeline *pipeline) {
list->d3d12.compute_pipeline_set = true;
list->d3d12.compute_pipe = pipeline;
list->d3d12.ray_pipe = NULL;
list->d3d12.render_pipe = NULL;
list->d3d12.list->SetPipelineState(pipeline->pipe);
list->d3d12.list->SetComputeRootSignature(pipeline->root_signature);
}
Expand Down Expand Up @@ -602,7 +613,8 @@ void kope_d3d12_command_list_set_ray_pipeline(kope_g5_command_list *list, kope_d
list->d3d12.list->SetPipelineState1(pipeline->pipe);
list->d3d12.list->SetComputeRootSignature(pipeline->root_signature);
list->d3d12.ray_pipe = pipeline;
list->d3d12.compute_pipeline_set = true;
list->d3d12.compute_pipe = NULL;
list->d3d12.render_pipe = NULL;
}

void kope_d3d12_command_list_trace_rays(kope_g5_command_list *list, uint32_t width, uint32_t height, uint32_t depth) {
Expand Down Expand Up @@ -694,3 +706,18 @@ void kope_d3d12_command_list_resolve_query_set(kope_g5_command_list *list, kope_
query_set->d3d12.query_type == KOPE_G5_QUERY_TYPE_OCCLUSION ? D3D12_QUERY_TYPE_OCCLUSION : D3D12_QUERY_TYPE_TIMESTAMP,
first_query, query_count, destination->d3d12.resource, destination_offset);
}
void kope_d3d12_command_list_draw_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset, uint32_t max_draw_count,
kope_g5_buffer *count_buffer, uint64_t count_offset) {
list->d3d12.list->ExecuteIndirect(list->d3d12.render_pipe->draw_command_signature, max_draw_count, indirect_buffer->d3d12.resource, indirect_offset,
count_buffer != NULL ? count_buffer->d3d12.resource : NULL, count_offset);
}

void kope_d3d12_command_list_draw_indexed_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset,
uint32_t max_draw_count, kope_g5_buffer *count_buffer, uint64_t count_offset) {
list->d3d12.list->ExecuteIndirect(list->d3d12.render_pipe->draw_indexed_command_signature, max_draw_count, indirect_buffer->d3d12.resource, indirect_offset,
count_buffer != NULL ? count_buffer->d3d12.resource : NULL, count_offset);
}

void kope_d3d12_command_list_compute_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset) {
list->d3d12.list->ExecuteIndirect(list->d3d12.compute_pipe->compute_command_signature, 1, indirect_buffer->d3d12.resource, indirect_offset, NULL, 0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
extern "C" {
#endif

void kope_d3d12_command_list_destroy(kope_g5_command_list *list);

void kope_d3d12_command_list_copy_buffer_to_buffer(kope_g5_command_list *list, kope_g5_buffer *source, uint64_t source_offset, kope_g5_buffer *destination,
uint64_t destination_offset, uint64_t size);

Expand Down Expand Up @@ -88,6 +90,14 @@ void kope_d3d12_command_list_end_occlusion_query(kope_g5_command_list *list);
void kope_d3d12_command_list_resolve_query_set(kope_g5_command_list *list, kope_g5_query_set *query_set, uint32_t first_query, uint32_t query_count,
kope_g5_buffer *destination, uint64_t destination_offset);

void kope_d3d12_command_list_draw_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset, uint32_t max_draw_count,
kope_g5_buffer *count_buffer, uint64_t count_offset);

void kope_d3d12_command_list_draw_indexed_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset,
uint32_t max_draw_count, kope_g5_buffer *count_buffer, uint64_t count_offset);

void kope_d3d12_command_list_compute_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset);

#ifdef __cplusplus
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ extern "C" {

struct kope_d3d12_device;
struct kope_d3d12_texture;
struct kope_d3d12_compute_pipeline;
struct kope_d3d12_ray_pipeline;
struct kope_d3d12_rendery_pipeline;
struct kope_g5_query_set;

struct ID3D12Fence;
Expand All @@ -36,7 +38,9 @@ typedef struct kope_d3d12_command_list {
// set when a framebuffer is attached to a render-pass so we don't render into it during scan-out
uint64_t blocking_frame_index;

bool compute_pipeline_set;
struct kope_d3d12_render_pipeline *render_pipe;

struct kope_d3d12_compute_pipeline *compute_pipe;

struct kope_d3d12_ray_pipeline *ray_pipe;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,9 @@ void kope_d3d12_device_create_command_list(kope_g5_device *device, kope_g5_comma
kinc_microsoft_affirm(device->d3d12.device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, list->d3d12.allocator[list->d3d12.current_allocator_index],
NULL, IID_GRAPHICS_PPV_ARGS(&list->d3d12.list)));

list->d3d12.compute_pipeline_set = false;

list->d3d12.compute_pipe = NULL;
list->d3d12.ray_pipe = NULL;
list->d3d12.render_pipe = NULL;

{
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
Expand Down
30 changes: 30 additions & 0 deletions Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,26 @@ void kope_d3d12_render_pipeline_init(kope_d3d12_device *device, kope_d3d12_rende

kinc_microsoft_affirm(
device->device->CreateRootSignature(0, desc.VS.pShaderBytecode, desc.VS.BytecodeLength, IID_GRAPHICS_PPV_ARGS(&pipe->root_signature)));

D3D12_INDIRECT_ARGUMENT_DESC indirect_args[2];
indirect_args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW;
indirect_args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
indirect_args[1].Constant.RootParameterIndex = 0;
indirect_args[1].Constant.DestOffsetIn32BitValues = 0;
indirect_args[1].Constant.Num32BitValuesToSet = 1;

D3D12_COMMAND_SIGNATURE_DESC command_signature_desc;
command_signature_desc.ByteStride = sizeof(kope_g5_draw_arguments);
command_signature_desc.NumArgumentDescs = 2;
command_signature_desc.pArgumentDescs = indirect_args;

device->device->CreateCommandSignature(&command_signature_desc, pipe->root_signature, IID_GRAPHICS_PPV_ARGS(&pipe->draw_command_signature));

indirect_args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;

command_signature_desc.ByteStride = sizeof(kope_g5_draw_indexed_arguments);

device->device->CreateCommandSignature(&command_signature_desc, pipe->root_signature, IID_GRAPHICS_PPV_ARGS(&pipe->draw_indexed_command_signature));
}

void kope_d3d12_render_pipeline_destroy(kope_d3d12_render_pipeline *pipe) {
Expand All @@ -353,6 +373,16 @@ void kope_d3d12_compute_pipeline_init(kope_d3d12_device *device, kope_d3d12_comp

kinc_microsoft_affirm(
device->device->CreateRootSignature(0, desc.CS.pShaderBytecode, desc.CS.BytecodeLength, IID_GRAPHICS_PPV_ARGS(&pipe->root_signature)));

D3D12_INDIRECT_ARGUMENT_DESC indirect_args[2];
indirect_args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH;

D3D12_COMMAND_SIGNATURE_DESC command_signature_desc;
command_signature_desc.ByteStride = sizeof(kope_g5_compute_arguments);
command_signature_desc.NumArgumentDescs = 1;
command_signature_desc.pArgumentDescs = indirect_args;

device->device->CreateCommandSignature(&command_signature_desc, pipe->root_signature, IID_GRAPHICS_PPV_ARGS(&pipe->compute_command_signature));
}

void kope_d3d12_compute_pipeline_destroy(kope_d3d12_compute_pipeline *pipe) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ struct ID3D12RootSignature;
typedef struct kope_d3d12_render_pipeline {
struct ID3D12PipelineState *pipe;
struct ID3D12RootSignature *root_signature;
struct ID3D12CommandSignature *draw_command_signature;
struct ID3D12CommandSignature *draw_indexed_command_signature;
} kope_d3d12_render_pipeline;

typedef struct kope_d3d12_compute_pipeline_parameters {
Expand All @@ -211,6 +213,7 @@ typedef struct kope_d3d12_compute_pipeline_parameters {
typedef struct kope_d3d12_compute_pipeline {
struct ID3D12PipelineState *pipe;
struct ID3D12RootSignature *root_signature;
struct ID3D12CommandSignature *compute_command_signature;
} kope_d3d12_compute_pipeline;

typedef struct kope_d3d12_ray_pipeline_parameters {
Expand Down
18 changes: 18 additions & 0 deletions Sources/kope/graphics5/commandlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

#include <assert.h>

void kope_g5_command_list_destroy(kope_g5_command_list *list) {
KOPE_G5_CALL1(command_list_destroy, list);
}

void kope_g5_command_list_copy_buffer_to_buffer(kope_g5_command_list *list, kope_g5_buffer *source, uint64_t source_offset, kope_g5_buffer *destination,
uint64_t destination_offset, uint64_t size) {
KOPE_G5_CALL6(command_list_copy_buffer_to_buffer, list, source, source_offset, destination, destination_offset, size);
Expand Down Expand Up @@ -130,3 +134,17 @@ void kope_g5_command_list_resolve_query_set(kope_g5_command_list *list, kope_g5_
kope_g5_buffer *destination, uint64_t destination_offset) {
KOPE_G5_CALL6(command_list_resolve_query_set, list, query_set, first_query, query_count, destination, destination_offset);
}

void kope_g5_command_list_draw_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset, uint32_t max_draw_count,
kope_g5_buffer *count_buffer, uint64_t count_offset) {
KOPE_G5_CALL6(command_list_draw_indirect, list, indirect_buffer, indirect_offset, max_draw_count, count_buffer, count_offset);
}

void kope_g5_command_list_draw_indexed_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset, uint32_t max_draw_count,
kope_g5_buffer *count_buffer, uint64_t count_offset) {
KOPE_G5_CALL6(command_list_draw_indexed_indirect, list, indirect_buffer, indirect_offset, max_draw_count, count_buffer, count_offset);
}

void kope_g5_command_list_compute_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset) {
KOPE_G5_CALL3(command_list_compute_indirect, list, indirect_buffer, indirect_offset);
}
31 changes: 28 additions & 3 deletions Sources/kope/graphics5/commandlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,34 @@ KOPE_FUNC void kope_g5_command_list_draw(kope_g5_command_list *list, uint32_t ve
KOPE_FUNC void kope_g5_command_list_draw_indexed(kope_g5_command_list *list, uint32_t index_count, uint32_t instance_count, uint32_t first_index,
int32_t base_vertex, uint32_t first_instance);

KOPE_FUNC void kope_g5_command_list_draw_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset);

KOPE_FUNC void kope_g5_command_list_draw_indexed_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset);
typedef struct kope_g5_draw_arguments {
uint32_t vertex_count;
uint32_t instance_count;
uint32_t first_vertex;
uint32_t first_instance;
uint32_t automatic_draw_index;
} kope_g5_draw_arguments;

typedef struct kope_g5_draw_indexed_arguments {
uint32_t index_count;
uint32_t instance_count;
uint32_t first_index;
int32_t base_vertex;
uint32_t first_instance;
uint32_t automatic_draw_index;
} kope_g5_draw_indexed_arguments;

typedef struct kope_g5_compute_arguments {
uint32_t workgroup_count_x;
uint32_t workgroup_count_y;
uint32_t workgroup_count_z;
} kope_g5_compute_arguments;

KOPE_FUNC void kope_g5_command_list_draw_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset,
uint32_t max_draw_count, kope_g5_buffer *count_buffer, uint64_t count_offset);

KOPE_FUNC void kope_g5_command_list_draw_indexed_indirect(kope_g5_command_list *list, kope_g5_buffer *indirect_buffer, uint64_t indirect_offset,
uint32_t max_draw_count, kope_g5_buffer *count_buffer, uint64_t count_offset);

KOPE_FUNC void kope_g5_command_list_set_viewport(kope_g5_command_list *list, float x, float y, float width, float height, float min_depth, float max_depth);

Expand Down

0 comments on commit dcdedd3

Please sign in to comment.