feat: updated engine
This commit is contained in:
parent
cbe99774ff
commit
f4cf6b3999
6607 changed files with 910135 additions and 430025 deletions
|
|
@ -105,6 +105,7 @@ bool RenderingDeviceGraph::_is_write_usage(ResourceUsage p_usage) {
|
|||
case RESOURCE_USAGE_STORAGE_IMAGE_READ:
|
||||
case RESOURCE_USAGE_ATTACHMENT_FRAGMENT_SHADING_RATE_READ:
|
||||
case RESOURCE_USAGE_ATTACHMENT_FRAGMENT_DENSITY_MAP_READ:
|
||||
case RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ:
|
||||
return false;
|
||||
case RESOURCE_USAGE_COPY_TO:
|
||||
case RESOURCE_USAGE_RESOLVE_TO:
|
||||
|
|
@ -114,6 +115,7 @@ bool RenderingDeviceGraph::_is_write_usage(ResourceUsage p_usage) {
|
|||
case RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE:
|
||||
case RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE:
|
||||
case RESOURCE_USAGE_GENERAL:
|
||||
case RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE:
|
||||
return true;
|
||||
default:
|
||||
DEV_ASSERT(false && "Invalid resource tracker usage.");
|
||||
|
|
@ -173,6 +175,8 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage
|
|||
return RDD::BARRIER_ACCESS_UNIFORM_READ_BIT;
|
||||
case RESOURCE_USAGE_INDIRECT_BUFFER_READ:
|
||||
return RDD::BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT;
|
||||
case RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ:
|
||||
return RDD::BARRIER_ACCESS_ACCELERATION_STRUCTURE_READ_BIT;
|
||||
case RESOURCE_USAGE_STORAGE_BUFFER_READ:
|
||||
case RESOURCE_USAGE_STORAGE_IMAGE_READ:
|
||||
case RESOURCE_USAGE_TEXTURE_BUFFER_READ:
|
||||
|
|
@ -196,6 +200,8 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage
|
|||
return RDD::BARRIER_ACCESS_FRAGMENT_DENSITY_MAP_ATTACHMENT_READ_BIT;
|
||||
case RESOURCE_USAGE_GENERAL:
|
||||
return RDD::BarrierAccessBits(RDD::BARRIER_ACCESS_MEMORY_READ_BIT | RDD::BARRIER_ACCESS_MEMORY_WRITE_BIT);
|
||||
case RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE:
|
||||
return RDD::BarrierAccessBits(RDD::BARRIER_ACCESS_ACCELERATION_STRUCTURE_READ_BIT | RDD::BARRIER_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT);
|
||||
default:
|
||||
DEV_ASSERT(false && "Invalid usage.");
|
||||
return RDD::BarrierAccessBits(0);
|
||||
|
|
@ -351,6 +357,12 @@ void RenderingDeviceGraph::_check_discardable_attachment_dependency(ResourceTrac
|
|||
}
|
||||
}
|
||||
|
||||
RenderingDeviceGraph::RaytracingListInstruction *RenderingDeviceGraph::_allocate_raytracing_list_instruction(uint32_t p_instruction_size) {
|
||||
uint32_t raytracing_list_data_offset = raytracing_instruction_list.data.size();
|
||||
raytracing_instruction_list.data.resize(raytracing_list_data_offset + p_instruction_size);
|
||||
return reinterpret_cast<RaytracingListInstruction *>(&raytracing_instruction_list.data[raytracing_list_data_offset]);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_trackers, ResourceUsage *p_resource_usages, uint32_t p_resource_count, int32_t p_command_index, RecordedCommand *r_command) {
|
||||
// Assign the next stages derived from the stages the command requires first.
|
||||
r_command->next_stages = r_command->self_stages;
|
||||
|
|
@ -394,6 +406,13 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
|
|||
|
||||
resource_tracker->reset_if_outdated(tracking_frame);
|
||||
|
||||
resource_tracker->command_index = p_command_index;
|
||||
resource_tracker->usage_index = i;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < p_resource_count; i++) {
|
||||
ResourceTracker *resource_tracker = p_resource_trackers[i];
|
||||
|
||||
const RDD::TextureSubresourceRange &subresources = resource_tracker->texture_subresources;
|
||||
const Rect2i resource_tracker_rect(subresources.base_mipmap, subresources.base_layer, subresources.mipmap_count, subresources.layer_count);
|
||||
Rect2i search_tracker_rect = resource_tracker_rect;
|
||||
|
|
@ -406,6 +425,15 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
|
|||
// This resource depends on a parent resource.
|
||||
resource_tracker->parent->reset_if_outdated(tracking_frame);
|
||||
|
||||
// Quit early if the parent is already in this command.
|
||||
if (resource_tracker->parent->command_index == p_command_index) {
|
||||
DEV_ASSERT(resource_tracker->parent->usage_index != UINT32_MAX);
|
||||
|
||||
ERR_FAIL_COND_MSG(p_resource_usages[resource_tracker->parent->usage_index] != new_resource_usage, "Using a full texture and its slices at the same time with different usages is not allowed.");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (resource_tracker->texture_slice_command_index != p_command_index) {
|
||||
// Indicate this slice has been used by this command.
|
||||
resource_tracker->texture_slice_command_index = p_command_index;
|
||||
|
|
@ -568,6 +596,11 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
|
|||
// Memory barriers are pushed regardless of buffer barriers being used or not.
|
||||
r_command->memory_barrier.src_access = r_command->memory_barrier.src_access | resource_tracker->usage_access;
|
||||
r_command->memory_barrier.dst_access = r_command->memory_barrier.dst_access | new_usage_access;
|
||||
} else if (resource_tracker->acceleration_structure_driver_id.id != 0) {
|
||||
// Make sure the acceleration structure has been built before accessing it from raytracing shaders.
|
||||
_add_acceleration_structure_barrier_to_command(resource_tracker->acceleration_structure_driver_id, resource_tracker->usage_access, new_usage_access, command_acceleration_structure_barriers, r_command->acceleration_structure_barrier_index, r_command->acceleration_structure_barrier_count);
|
||||
r_command->memory_barrier.src_access = r_command->memory_barrier.src_access | resource_tracker->usage_access;
|
||||
r_command->memory_barrier.dst_access = r_command->memory_barrier.dst_access | new_usage_access;
|
||||
} else {
|
||||
DEV_ASSERT(false && "Resource tracker does not contain a valid buffer or texture ID.");
|
||||
}
|
||||
|
|
@ -758,6 +791,66 @@ void RenderingDeviceGraph::_add_buffer_barrier_to_command(RDD::BufferID p_buffer
|
|||
}
|
||||
#endif
|
||||
|
||||
void RenderingDeviceGraph::_add_acceleration_structure_barrier_to_command(RDD::AccelerationStructureID p_acceleration_structure_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, LocalVector<RDD::AccelerationStructureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count) {
|
||||
if (!driver_honors_barriers) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (r_barrier_index < 0) {
|
||||
r_barrier_index = r_barrier_vector.size();
|
||||
}
|
||||
|
||||
RDD::AccelerationStructureBarrier accel_barrier;
|
||||
accel_barrier.acceleration_structure = p_acceleration_structure_id;
|
||||
accel_barrier.src_access = p_src_access;
|
||||
accel_barrier.dst_access = p_dst_access;
|
||||
accel_barrier.offset = 0;
|
||||
accel_barrier.size = RDD::BUFFER_WHOLE_SIZE;
|
||||
r_barrier_vector.push_back(accel_barrier);
|
||||
r_barrier_count++;
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::_run_raytracing_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size) {
|
||||
uint32_t instruction_data_cursor = 0;
|
||||
while (instruction_data_cursor < p_instruction_data_size) {
|
||||
DEV_ASSERT((instruction_data_cursor + sizeof(RaytracingListInstruction)) <= p_instruction_data_size);
|
||||
|
||||
const RaytracingListInstruction *instruction = reinterpret_cast<const RaytracingListInstruction *>(&p_instruction_data[instruction_data_cursor]);
|
||||
switch (instruction->type) {
|
||||
case RaytracingListInstruction::TYPE_BIND_PIPELINE: {
|
||||
const RaytracingListBindPipelineInstruction *bind_pipeline_instruction = reinterpret_cast<const RaytracingListBindPipelineInstruction *>(instruction);
|
||||
driver->command_bind_raytracing_pipeline(p_command_buffer, bind_pipeline_instruction->pipeline);
|
||||
instruction_data_cursor += sizeof(RaytracingListBindPipelineInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_BIND_UNIFORM_SET: {
|
||||
const RaytracingListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast<const RaytracingListBindUniformSetInstruction *>(instruction);
|
||||
driver->command_bind_raytracing_uniform_set(p_command_buffer, bind_uniform_set_instruction->uniform_set, bind_uniform_set_instruction->shader, bind_uniform_set_instruction->set_index);
|
||||
instruction_data_cursor += sizeof(RaytracingListBindUniformSetInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_TRACE_RAYS: {
|
||||
const RaytracingListTraceRaysInstruction *trace_rays_instruction = reinterpret_cast<const RaytracingListTraceRaysInstruction *>(instruction);
|
||||
driver->command_trace_rays(p_command_buffer, trace_rays_instruction->raygen_sbt, trace_rays_instruction->miss_sbt, trace_rays_instruction->hit_sbt, trace_rays_instruction->width, trace_rays_instruction->height, trace_rays_instruction->depth);
|
||||
instruction_data_cursor += sizeof(RaytracingListTraceRaysInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_SET_PUSH_CONSTANT: {
|
||||
const RaytracingListSetPushConstantInstruction *set_push_constant_instruction = reinterpret_cast<const RaytracingListSetPushConstantInstruction *>(instruction);
|
||||
const VectorView push_constant_data_view(reinterpret_cast<const uint32_t *>(set_push_constant_instruction->data()), set_push_constant_instruction->size / sizeof(uint32_t));
|
||||
driver->command_bind_push_constants(p_command_buffer, set_push_constant_instruction->shader, 0, push_constant_data_view);
|
||||
instruction_data_cursor += sizeof(RaytracingListSetPushConstantInstruction);
|
||||
instruction_data_cursor += set_push_constant_instruction->size;
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_UNIFORM_SET_PREPARE_FOR_USE: {
|
||||
const RaytracingListUniformSetPrepareForUseInstruction *uniform_set_prepare_for_use_instruction = reinterpret_cast<const RaytracingListUniformSetPrepareForUseInstruction *>(instruction);
|
||||
driver->command_uniform_set_prepare_for_use(p_command_buffer, uniform_set_prepare_for_use_instruction->uniform_set, uniform_set_prepare_for_use_instruction->shader, uniform_set_prepare_for_use_instruction->set_index);
|
||||
instruction_data_cursor += sizeof(RaytracingListUniformSetPrepareForUseInstruction);
|
||||
} break;
|
||||
default:
|
||||
DEV_ASSERT(false && "Unknown raytracing list instruction type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::_run_compute_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size) {
|
||||
uint32_t instruction_data_cursor = 0;
|
||||
while (instruction_data_cursor < p_instruction_data_size) {
|
||||
|
|
@ -1004,6 +1097,14 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
|
|||
_run_label_command_change(r_command_buffer, command->label_index, p_level, false, true, &p_sorted_commands[i], p_sorted_commands_count - i, r_current_label_index, r_current_label_level);
|
||||
|
||||
switch (command->type) {
|
||||
case RecordedCommand::TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_BUILD: {
|
||||
const RecordedBottomLevelAccelerationStructureBuildCommand *blas_build_command = reinterpret_cast<const RecordedBottomLevelAccelerationStructureBuildCommand *>(command);
|
||||
driver->command_build_blas(r_command_buffer, blas_build_command->acceleration_structure, blas_build_command->scratch_buffer);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_TOP_LEVEL_ACCELERATION_STRUCTURE_BUILD: {
|
||||
const RecordedTopLevelAccelerationStructureBuildCommand *tlas_build_command = reinterpret_cast<const RecordedTopLevelAccelerationStructureBuildCommand *>(command);
|
||||
driver->command_build_tlas(r_command_buffer, tlas_build_command->acceleration_structure, tlas_build_command->scratch_buffer, tlas_build_command->instance_buffer, tlas_build_command->instance_offset, tlas_build_command->instance_count);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_BUFFER_CLEAR: {
|
||||
const RecordedBufferClearCommand *buffer_clear_command = reinterpret_cast<const RecordedBufferClearCommand *>(command);
|
||||
driver->command_clear_buffer(r_command_buffer, buffer_clear_command->buffer, buffer_clear_command->offset, buffer_clear_command->size);
|
||||
|
|
@ -1027,8 +1128,12 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
|
|||
const RecordedDriverCallbackCommand *driver_callback_command = reinterpret_cast<const RecordedDriverCallbackCommand *>(command);
|
||||
driver_callback_command->callback(driver, r_command_buffer, driver_callback_command->userdata);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_RAYTRACING_LIST: {
|
||||
const RecordedRaytracingListCommand *raytracing_list_command = reinterpret_cast<const RecordedRaytracingListCommand *>(command);
|
||||
_run_raytracing_list_command(r_command_buffer, raytracing_list_command->instruction_data(), raytracing_list_command->instruction_data_size);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_COMPUTE_LIST: {
|
||||
if (device.workarounds.avoid_compute_after_draw && workarounds_state.draw_list_found) {
|
||||
if (driver_workarounds.avoid_compute_after_draw && workarounds_state.draw_list_found) {
|
||||
// Avoid compute after draw workaround. Refer to the comment that enables this in the Vulkan driver for more information.
|
||||
workarounds_state.draw_list_found = false;
|
||||
|
||||
|
|
@ -1052,7 +1157,7 @@ void RenderingDeviceGraph::_run_render_commands(int32_t p_level, const RecordedC
|
|||
_run_compute_list_command(r_command_buffer, compute_list_command->instruction_data(), compute_list_command->instruction_data_size);
|
||||
} break;
|
||||
case RecordedCommand::TYPE_DRAW_LIST: {
|
||||
if (device.workarounds.avoid_compute_after_draw) {
|
||||
if (driver_workarounds.avoid_compute_after_draw) {
|
||||
// Indicate that a draw list was encountered for the workaround.
|
||||
workarounds_state.draw_list_found = true;
|
||||
}
|
||||
|
|
@ -1313,6 +1418,12 @@ void RenderingDeviceGraph::_group_barriers_for_render_commands(RDD::CommandBuffe
|
|||
barrier_group.buffer_barriers.push_back(recorded_barrier);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Gather acceleration structure barriers.
|
||||
for (int32_t j = 0; j < command->acceleration_structure_barrier_count; j++) {
|
||||
const RDD::AccelerationStructureBarrier &recorded_barrier = command_acceleration_structure_barriers[command->acceleration_structure_barrier_index + j];
|
||||
barrier_group.acceleration_structure_barriers.push_back(recorded_barrier);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_full_memory_barrier) {
|
||||
|
|
@ -1329,7 +1440,8 @@ void RenderingDeviceGraph::_group_barriers_for_render_commands(RDD::CommandBuffe
|
|||
#else
|
||||
const bool are_buffer_barriers_empty = true;
|
||||
#endif
|
||||
if (is_memory_barrier_empty && are_texture_barriers_empty && are_buffer_barriers_empty) {
|
||||
const bool are_acceleration_structure_barriers_empty = barrier_group.acceleration_structure_barriers.is_empty();
|
||||
if (is_memory_barrier_empty && are_texture_barriers_empty && are_buffer_barriers_empty && are_acceleration_structure_barriers_empty) {
|
||||
// Commands don't require synchronization.
|
||||
return;
|
||||
}
|
||||
|
|
@ -1341,12 +1453,13 @@ void RenderingDeviceGraph::_group_barriers_for_render_commands(RDD::CommandBuffe
|
|||
#else
|
||||
const VectorView<RDD::BufferBarrier> buffer_barriers = VectorView<RDD::BufferBarrier>();
|
||||
#endif
|
||||
const VectorView<RDD::AccelerationStructureBarrier> acceleration_structure_barriers = !are_acceleration_structure_barriers_empty ? barrier_group.acceleration_structure_barriers : VectorView<RDD::AccelerationStructureBarrier>();
|
||||
|
||||
driver->command_pipeline_barrier(p_command_buffer, barrier_group.src_stages, barrier_group.dst_stages, memory_barriers, buffer_barriers, texture_barriers);
|
||||
driver->command_pipeline_barrier(p_command_buffer, barrier_group.src_stages, barrier_group.dst_stages, memory_barriers, buffer_barriers, texture_barriers, acceleration_structure_barriers);
|
||||
|
||||
bool separate_texture_barriers = !barrier_group.normalization_barriers.is_empty() && !barrier_group.transition_barriers.is_empty();
|
||||
if (separate_texture_barriers) {
|
||||
driver->command_pipeline_barrier(p_command_buffer, barrier_group.src_stages, barrier_group.dst_stages, VectorView<RDD::MemoryAccessBarrier>(), VectorView<RDD::BufferBarrier>(), barrier_group.transition_barriers);
|
||||
driver->command_pipeline_barrier(p_command_buffer, barrier_group.src_stages, barrier_group.dst_stages, VectorView<RDD::MemoryAccessBarrier>(), VectorView<RDD::BufferBarrier>(), barrier_group.transition_barriers, VectorView<RDD::AccelerationStructureBarrier>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1525,6 +1638,46 @@ void RenderingDeviceGraph::_print_draw_list(const uint8_t *p_instruction_data, u
|
|||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::_print_raytracing_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size) {
|
||||
uint32_t instruction_data_cursor = 0;
|
||||
while (instruction_data_cursor < p_instruction_data_size) {
|
||||
DEV_ASSERT((instruction_data_cursor + sizeof(RaytracingListInstruction)) <= p_instruction_data_size);
|
||||
|
||||
const RaytracingListInstruction *instruction = reinterpret_cast<const RaytracingListInstruction *>(&p_instruction_data[instruction_data_cursor]);
|
||||
switch (instruction->type) {
|
||||
case RaytracingListInstruction::TYPE_BIND_PIPELINE: {
|
||||
const RaytracingListBindPipelineInstruction *bind_pipeline_instruction = reinterpret_cast<const RaytracingListBindPipelineInstruction *>(instruction);
|
||||
print_line("\tBIND PIPELINE ID", itos(bind_pipeline_instruction->pipeline.id));
|
||||
instruction_data_cursor += sizeof(RaytracingListBindPipelineInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_BIND_UNIFORM_SET: {
|
||||
const RaytracingListBindUniformSetInstruction *bind_uniform_set_instruction = reinterpret_cast<const RaytracingListBindUniformSetInstruction *>(instruction);
|
||||
print_line("\tBIND UNIFORM SET ID", itos(bind_uniform_set_instruction->uniform_set.id), "SHADER ID", itos(bind_uniform_set_instruction->shader.id));
|
||||
instruction_data_cursor += sizeof(RaytracingListBindUniformSetInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_SET_PUSH_CONSTANT: {
|
||||
const RaytracingListSetPushConstantInstruction *set_push_constant_instruction = reinterpret_cast<const RaytracingListSetPushConstantInstruction *>(instruction);
|
||||
print_line("\tSET PUSH CONSTANT SIZE", set_push_constant_instruction->size);
|
||||
instruction_data_cursor += sizeof(RaytracingListSetPushConstantInstruction);
|
||||
instruction_data_cursor += set_push_constant_instruction->size;
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_TRACE_RAYS: {
|
||||
const RaytracingListTraceRaysInstruction *trace_rays_instruction = reinterpret_cast<const RaytracingListTraceRaysInstruction *>(instruction);
|
||||
print_line("\tTRACE RAYS WIDTH", itos(trace_rays_instruction->width), "HEIGHT", itos(trace_rays_instruction->height));
|
||||
instruction_data_cursor += sizeof(RaytracingListTraceRaysInstruction);
|
||||
} break;
|
||||
case RaytracingListInstruction::TYPE_UNIFORM_SET_PREPARE_FOR_USE: {
|
||||
const RaytracingListUniformSetPrepareForUseInstruction *uniform_set_prepare_for_use_instruction = reinterpret_cast<const RaytracingListUniformSetPrepareForUseInstruction *>(instruction);
|
||||
print_line("\tUNIFORM SET PREPARE FOR USE ID", itos(uniform_set_prepare_for_use_instruction->uniform_set.id), "SHADER ID", itos(uniform_set_prepare_for_use_instruction->shader.id), "INDEX", itos(uniform_set_prepare_for_use_instruction->set_index));
|
||||
instruction_data_cursor += sizeof(RaytracingListUniformSetPrepareForUseInstruction);
|
||||
} break;
|
||||
default:
|
||||
DEV_ASSERT(false && "Unknown raytracing list instruction type.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::_print_compute_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size) {
|
||||
uint32_t instruction_data_cursor = 0;
|
||||
while (instruction_data_cursor < p_instruction_data_size) {
|
||||
|
|
@ -1575,13 +1728,13 @@ void RenderingDeviceGraph::_print_compute_list(const uint8_t *p_instruction_data
|
|||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::initialize(RDD *p_driver, RenderingContextDriver::Device p_device, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame) {
|
||||
void RenderingDeviceGraph::initialize(RDD *p_driver, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame) {
|
||||
DEV_ASSERT(p_driver != nullptr);
|
||||
DEV_ASSERT(p_render_pass_creation_function != nullptr);
|
||||
DEV_ASSERT(p_frame_count > 0);
|
||||
|
||||
driver = p_driver;
|
||||
device = p_device;
|
||||
driver_workarounds = p_driver->get_driver_workarounds();
|
||||
render_pass_creation_function = p_render_pass_creation_function;
|
||||
frames.resize(p_frame_count);
|
||||
|
||||
|
|
@ -1623,6 +1776,7 @@ void RenderingDeviceGraph::begin() {
|
|||
command_normalization_barriers.clear();
|
||||
command_transition_barriers.clear();
|
||||
command_buffer_barriers.clear();
|
||||
command_acceleration_structure_barriers.clear();
|
||||
command_label_chars.clear();
|
||||
command_label_colors.clear();
|
||||
command_label_offsets.clear();
|
||||
|
|
@ -1645,6 +1799,63 @@ void RenderingDeviceGraph::begin() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_blas_build(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers) {
|
||||
int32_t command_index;
|
||||
RecordedBottomLevelAccelerationStructureBuildCommand *command = static_cast<RecordedBottomLevelAccelerationStructureBuildCommand *>(_allocate_command(sizeof(RecordedBottomLevelAccelerationStructureBuildCommand), command_index));
|
||||
command->type = RecordedCommand::TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_BUILD;
|
||||
command->self_stages = RDD::PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT;
|
||||
command->acceleration_structure = p_acceleration_structure;
|
||||
command->scratch_buffer = p_scratch_buffer;
|
||||
|
||||
thread_local LocalVector<ResourceTracker *> trackers;
|
||||
thread_local LocalVector<ResourceUsage> usages;
|
||||
|
||||
// Sources and destination.
|
||||
uint32_t resource_count = p_src_trackers.size() + 1;
|
||||
trackers.resize(resource_count);
|
||||
usages.resize(resource_count);
|
||||
|
||||
for (uint32_t i = 0; i < p_src_trackers.size(); ++i) {
|
||||
trackers[i] = p_src_trackers[i];
|
||||
usages[i] = RESOURCE_USAGE_STORAGE_BUFFER_READ;
|
||||
}
|
||||
|
||||
trackers[resource_count - 1] = p_dst_tracker;
|
||||
usages[resource_count - 1] = RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE;
|
||||
|
||||
_add_command_to_graph(trackers.ptr(), usages.ptr(), usages.size(), command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_tlas_build(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, RDD::BufferID p_instance_buffer, uint32_t p_instance_offset, uint32_t p_instance_count, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers) {
|
||||
int32_t command_index;
|
||||
RecordedTopLevelAccelerationStructureBuildCommand *command = static_cast<RecordedTopLevelAccelerationStructureBuildCommand *>(_allocate_command(sizeof(RecordedTopLevelAccelerationStructureBuildCommand), command_index));
|
||||
command->type = RecordedCommand::TYPE_TOP_LEVEL_ACCELERATION_STRUCTURE_BUILD;
|
||||
command->self_stages = RDD::PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT;
|
||||
command->acceleration_structure = p_acceleration_structure;
|
||||
command->scratch_buffer = p_scratch_buffer;
|
||||
command->instance_buffer = p_instance_buffer;
|
||||
command->instance_offset = p_instance_offset;
|
||||
command->instance_count = p_instance_count;
|
||||
|
||||
thread_local LocalVector<ResourceTracker *> trackers;
|
||||
thread_local LocalVector<ResourceUsage> usages;
|
||||
|
||||
// Sources and destination.
|
||||
uint32_t resource_count = p_src_trackers.size() + 1;
|
||||
trackers.resize(resource_count);
|
||||
usages.resize(resource_count);
|
||||
|
||||
for (uint32_t i = 0; i < p_src_trackers.size(); ++i) {
|
||||
trackers[i] = p_src_trackers[i];
|
||||
usages[i] = RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ;
|
||||
}
|
||||
|
||||
trackers[resource_count - 1] = p_dst_tracker;
|
||||
usages[resource_count - 1] = RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE;
|
||||
|
||||
_add_command_to_graph(trackers.ptr(), usages.ptr(), usages.size(), command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size) {
|
||||
DEV_ASSERT(p_dst_tracker != nullptr);
|
||||
|
||||
|
|
@ -1735,6 +1946,92 @@ void RenderingDeviceGraph::add_driver_callback(RDD::DriverCallback p_callback, v
|
|||
_add_command_to_graph((ResourceTracker **)p_trackers.ptr(), (ResourceUsage *)p_usages.ptr(), p_trackers.size(), command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_begin() {
|
||||
raytracing_instruction_list.clear();
|
||||
raytracing_instruction_list.index++;
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_bind_pipeline(RDD::RaytracingPipelineID p_pipeline) {
|
||||
RaytracingListBindPipelineInstruction *instruction = reinterpret_cast<RaytracingListBindPipelineInstruction *>(_allocate_raytracing_list_instruction(sizeof(RaytracingListBindPipelineInstruction)));
|
||||
instruction->type = RaytracingListInstruction::TYPE_BIND_PIPELINE;
|
||||
instruction->pipeline = p_pipeline;
|
||||
raytracing_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_RAY_TRACING_SHADER_BIT);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) {
|
||||
RaytracingListBindUniformSetInstruction *instruction = reinterpret_cast<RaytracingListBindUniformSetInstruction *>(_allocate_raytracing_list_instruction(sizeof(RaytracingListBindUniformSetInstruction)));
|
||||
instruction->type = RaytracingListInstruction::TYPE_BIND_UNIFORM_SET;
|
||||
instruction->shader = p_shader;
|
||||
instruction->uniform_set = p_uniform_set;
|
||||
instruction->set_index = set_index;
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size) {
|
||||
uint32_t instruction_size = sizeof(RaytracingListSetPushConstantInstruction) + p_data_size;
|
||||
RaytracingListSetPushConstantInstruction *instruction = reinterpret_cast<RaytracingListSetPushConstantInstruction *>(_allocate_raytracing_list_instruction(instruction_size));
|
||||
instruction->type = RaytracingListInstruction::TYPE_SET_PUSH_CONSTANT;
|
||||
instruction->size = p_data_size;
|
||||
instruction->shader = p_shader;
|
||||
memcpy(instruction->data(), p_data, p_data_size);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_trace_rays(const RDD::ShaderBindingTable &p_raygen_sbt, const RDD::ShaderBindingTable &p_miss_sbt, const RDD::ShaderBindingTable &p_hit_sbt, uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
|
||||
RaytracingListTraceRaysInstruction *instruction = reinterpret_cast<RaytracingListTraceRaysInstruction *>(_allocate_raytracing_list_instruction(sizeof(RaytracingListTraceRaysInstruction)));
|
||||
instruction->type = RaytracingListInstruction::TYPE_TRACE_RAYS;
|
||||
instruction->raygen_sbt = p_raygen_sbt;
|
||||
instruction->miss_sbt = p_miss_sbt;
|
||||
instruction->hit_sbt = p_hit_sbt;
|
||||
instruction->width = p_width;
|
||||
instruction->height = p_height;
|
||||
instruction->depth = p_depth;
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) {
|
||||
RaytracingListUniformSetPrepareForUseInstruction *instruction = reinterpret_cast<RaytracingListUniformSetPrepareForUseInstruction *>(_allocate_raytracing_list_instruction(sizeof(RaytracingListUniformSetPrepareForUseInstruction)));
|
||||
instruction->type = RaytracingListInstruction::TYPE_UNIFORM_SET_PREPARE_FOR_USE;
|
||||
instruction->shader = p_shader;
|
||||
instruction->uniform_set = p_uniform_set;
|
||||
instruction->set_index = set_index;
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage) {
|
||||
DEV_ASSERT(p_tracker != nullptr);
|
||||
|
||||
p_tracker->reset_if_outdated(tracking_frame);
|
||||
|
||||
if (p_tracker->raytracing_list_index != raytracing_instruction_list.index) {
|
||||
raytracing_instruction_list.command_trackers.push_back(p_tracker);
|
||||
raytracing_instruction_list.command_tracker_usages.push_back(p_usage);
|
||||
p_tracker->raytracing_list_index = raytracing_instruction_list.index;
|
||||
p_tracker->raytracing_list_usage = p_usage;
|
||||
}
|
||||
#ifdef DEV_ENABLED
|
||||
else if (p_tracker->raytracing_list_usage != p_usage) {
|
||||
ERR_FAIL_MSG(vformat("Tracker can't have more than one type of usage in the same raytracing list. Raytracing list usage is %d and the requested usage is %d.", p_tracker->raytracing_list_usage, p_usage));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages) {
|
||||
DEV_ASSERT(p_trackers.size() == p_usages.size());
|
||||
|
||||
for (uint32_t i = 0; i < p_trackers.size(); i++) {
|
||||
add_raytracing_list_usage(p_trackers[i], p_usages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_raytracing_list_end() {
|
||||
int32_t command_index;
|
||||
uint32_t instruction_data_size = raytracing_instruction_list.data.size();
|
||||
uint32_t command_size = sizeof(RecordedRaytracingListCommand) + instruction_data_size;
|
||||
RecordedRaytracingListCommand *command = static_cast<RecordedRaytracingListCommand *>(_allocate_command(command_size, command_index));
|
||||
command->type = RecordedCommand::TYPE_RAYTRACING_LIST;
|
||||
command->self_stages = raytracing_instruction_list.stages;
|
||||
command->instruction_data_size = instruction_data_size;
|
||||
memcpy(command->instruction_data(), raytracing_instruction_list.data.ptr(), instruction_data_size);
|
||||
_add_command_to_graph(raytracing_instruction_list.command_trackers.ptr(), raytracing_instruction_list.command_tracker_usages.ptr(), raytracing_instruction_list.command_trackers.size(), command_index, command);
|
||||
}
|
||||
|
||||
void RenderingDeviceGraph::add_compute_list_begin(RDD::BreadcrumbMarker p_phase, uint32_t p_breadcrumb_data) {
|
||||
compute_instruction_list.clear();
|
||||
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
|
||||
|
|
@ -2362,13 +2659,16 @@ void RenderingDeviceGraph::end(bool p_reorder_commands, bool p_full_barriers, RD
|
|||
}
|
||||
|
||||
// Batch buffer, texture, draw lists and compute operations together.
|
||||
const uint32_t PriorityTable[RecordedCommand::TYPE_MAX] = {
|
||||
const uint32_t PriorityTable[] = {
|
||||
0, // TYPE_NONE
|
||||
6, // TYPE_BOTTOM_LEVEL_ACCELERATION_STRUCTURE_BUILD
|
||||
6, // TYPE_TOP_LEVEL_ACCELERATION_STRUCTURE_BUILD
|
||||
1, // TYPE_BUFFER_CLEAR
|
||||
1, // TYPE_BUFFER_COPY
|
||||
1, // TYPE_BUFFER_GET_DATA
|
||||
1, // TYPE_BUFFER_UPDATE
|
||||
4, // TYPE_COMPUTE_LIST
|
||||
7, // TYPE_RAYTRACING_LIST
|
||||
3, // TYPE_DRAW_LIST
|
||||
2, // TYPE_TEXTURE_CLEAR_COLOR
|
||||
2, // TYPE_TEXTURE_CLEAR_DEPTH_STENCIL
|
||||
|
|
@ -2379,6 +2679,7 @@ void RenderingDeviceGraph::end(bool p_reorder_commands, bool p_full_barriers, RD
|
|||
2, // TYPE_CAPTURE_TIMESTAMP
|
||||
5, // TYPE_DRIVER_CALLBACK
|
||||
};
|
||||
static_assert(std_size(PriorityTable) == RecordedCommand::TYPE_MAX, "PriorityTable must have one entry per RecordedCommand::Type");
|
||||
|
||||
commands_sorted.clear();
|
||||
commands_sorted.resize(command_count);
|
||||
|
|
@ -2418,7 +2719,7 @@ void RenderingDeviceGraph::end(bool p_reorder_commands, bool p_full_barriers, RD
|
|||
int32_t current_label_level = -1;
|
||||
_run_label_command_change(r_command_buffer, -1, -1, true, true, nullptr, 0, current_label_index, current_label_level);
|
||||
|
||||
if (device.workarounds.avoid_compute_after_draw) {
|
||||
if (driver_workarounds.avoid_compute_after_draw) {
|
||||
// Reset the state of the workaround.
|
||||
workarounds_state.draw_list_found = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue