diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer.cpp index 08acae418..43a21d8ab 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer.cpp @@ -4,6 +4,37 @@ #include +static uint64_t find_max_execution_index_all(kope_g5_buffer *buffer) { + uint64_t max_execution_index = 0; + + for (uint32_t range_index = 0; range_index < buffer->d3d12.ranges_count; ++range_index) { + uint64_t execution_index = buffer->d3d12.ranges[range_index].execution_index; + if (execution_index > max_execution_index) { + max_execution_index = execution_index; + } + } + + return max_execution_index; +} + +static uint64_t find_max_execution_index(kope_g5_buffer *buffer, uint64_t offset, uint64_t size) { + uint64_t max_execution_index = 0; + + for (uint32_t range_index = 0; range_index < buffer->d3d12.ranges_count; ++range_index) { + kope_d3d12_buffer_range range = buffer->d3d12.ranges[range_index]; + + if (range.size == UINT64_MAX || (offset >= range.offset && offset < range.offset + range.size) || + (offset + size > range.offset && offset + size <= range.offset + range.size)) { + uint64_t execution_index = buffer->d3d12.ranges[range_index].execution_index; + if (execution_index > max_execution_index) { + max_execution_index = execution_index; + } + } + } + + return max_execution_index; +} + void kope_d3d12_buffer_set_name(kope_g5_buffer *buffer, const char *name) { wchar_t wstr[1024]; kinc_microsoft_convert_string(wstr, name, 1024); @@ -15,7 +46,7 @@ void kope_d3d12_buffer_destroy(kope_g5_buffer *buffer) { } void *kope_d3d12_buffer_try_to_lock_all(kope_g5_buffer *buffer) { - if (check_for_fence(buffer->d3d12.device->d3d12.execution_fence, buffer->d3d12.latest_execution_index)) { + if (check_for_fence(buffer->d3d12.device->d3d12.execution_fence, find_max_execution_index_all(buffer))) { buffer->d3d12.locked_data_offset = 0; buffer->d3d12.locked_data_size = UINT64_MAX; @@ -29,7 +60,7 @@ void *kope_d3d12_buffer_try_to_lock_all(kope_g5_buffer *buffer) { void *kope_d3d12_buffer_lock_all(kope_g5_buffer *buffer) { wait_for_fence(buffer->d3d12.device, buffer->d3d12.device->d3d12.execution_fence, buffer->d3d12.device->d3d12.execution_event, - buffer->d3d12.latest_execution_index); + find_max_execution_index_all(buffer)); buffer->d3d12.locked_data_offset = 0; buffer->d3d12.locked_data_size = UINT64_MAX; @@ -39,7 +70,7 @@ void *kope_d3d12_buffer_lock_all(kope_g5_buffer *buffer) { } void *kope_d3d12_buffer_try_to_lock(kope_g5_buffer *buffer, uint64_t offset, uint64_t size) { - if (check_for_fence(buffer->d3d12.device->d3d12.execution_fence, buffer->d3d12.latest_execution_index)) { + if (check_for_fence(buffer->d3d12.device->d3d12.execution_fence, find_max_execution_index(buffer, offset, size))) { D3D12_RANGE read_range; D3D12_RANGE *read_range_pointer = NULL; @@ -62,7 +93,7 @@ void *kope_d3d12_buffer_try_to_lock(kope_g5_buffer *buffer, uint64_t offset, uin void *kope_d3d12_buffer_lock(kope_g5_buffer *buffer, uint64_t offset, uint64_t size) { wait_for_fence(buffer->d3d12.device, buffer->d3d12.device->d3d12.execution_fence, buffer->d3d12.device->d3d12.execution_event, - buffer->d3d12.latest_execution_index); + find_max_execution_index(buffer, offset, size)); D3D12_RANGE read_range; D3D12_RANGE *read_range_pointer = NULL; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer_structs.h index 21b2c2375..8166027c5 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/buffer_structs.h @@ -11,6 +11,14 @@ extern "C" { struct kope_g5_device; +#define KOPE_D3D12_MAX_BUFFER_RANGES 16 + +typedef struct kope_d3d12_buffer_range { + uint64_t offset; + uint64_t size; + uint64_t execution_index; +} kope_d3d12_buffer_range; + typedef struct kope_d3d12_buffer { struct kope_g5_device *device; @@ -24,7 +32,9 @@ typedef struct kope_d3d12_buffer { bool cpu_write; bool cpu_read; - uint64_t latest_execution_index; + + kope_d3d12_buffer_range ranges[KOPE_D3D12_MAX_BUFFER_RANGES]; + uint32_t ranges_count; } kope_d3d12_buffer; #ifdef __cplusplus diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp index 640df4ae5..6537af249 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist.cpp @@ -729,6 +729,11 @@ void kope_d3d12_command_list_compute_indirect(kope_g5_command_list *list, kope_g } void kope_d3d12_command_list_queue_buffer_access(kope_g5_command_list *list, kope_g5_buffer *buffer) { - list->d3d12.queued_buffer_accesses[list->d3d12.queued_buffer_accesses_count] = buffer; + kope_d3d12_buffer_access access; + access.buffer = buffer; + access.offset = 0; + access.size = UINT64_MAX; + + list->d3d12.queued_buffer_accesses[list->d3d12.queued_buffer_accesses_count] = access; list->d3d12.queued_buffer_accesses_count += 1; } diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h index 08b0d0460..c09a34d59 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/commandlist_structs.h @@ -22,6 +22,12 @@ struct ID3D12Fence; #define KOPE_D3D12_COMMAND_LIST_MAX_QUEUED_BUFFER_ACCESSES 256 +typedef struct kope_d3d12_buffer_access { + kope_g5_buffer *buffer; + uint64_t offset; + uint64_t size; +} kope_d3d12_buffer_access; + typedef struct kope_d3d12_command_list { struct kope_d3d12_device *device; @@ -53,7 +59,7 @@ typedef struct kope_d3d12_command_list { uint32_t timestamp_beginning_of_pass_write_index; uint32_t timestamp_end_of_pass_write_index; - kope_g5_buffer *queued_buffer_accesses[KOPE_D3D12_COMMAND_LIST_MAX_QUEUED_BUFFER_ACCESSES]; + kope_d3d12_buffer_access queued_buffer_accesses[KOPE_D3D12_COMMAND_LIST_MAX_QUEUED_BUFFER_ACCESSES]; uint32_t queued_buffer_accesses_count; bool presenting; diff --git a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp index 3a8433c74..0059c3ab0 100644 --- a/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp +++ b/Backends/Graphics5/Direct3D12/Sources/kope/direct3d12/device.cpp @@ -259,7 +259,7 @@ void kope_d3d12_device_create_buffer(kope_g5_device *device, const kope_g5_buffe buffer->d3d12.device = device; - buffer->d3d12.latest_execution_index = 0; + buffer->d3d12.ranges_count = 0; buffer->d3d12.cpu_read = (parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_READ) != 0; buffer->d3d12.cpu_write = (parameters->usage_flags & KOPE_G5_BUFFER_USAGE_CPU_WRITE) != 0; @@ -563,7 +563,12 @@ void kope_d3d12_device_execute_command_list(kope_g5_device *device, kope_g5_comm list->d3d12.list->Close(); for (uint32_t buffer_access_index = 0; buffer_access_index < list->d3d12.queued_buffer_accesses_count; ++buffer_access_index) { - list->d3d12.queued_buffer_accesses[buffer_access_index]->d3d12.latest_execution_index = device->d3d12.execution_index; + kope_d3d12_buffer_access access = list->d3d12.queued_buffer_accesses[buffer_access_index]; + kope_g5_buffer *buffer = access.buffer; + + buffer->d3d12.ranges[buffer->d3d12.ranges_count].execution_index = device->d3d12.execution_index; + buffer->d3d12.ranges[buffer->d3d12.ranges_count].offset = access.offset; + buffer->d3d12.ranges[buffer->d3d12.ranges_count].size = access.size; } list->d3d12.queued_buffer_accesses_count = 0;