Simplify pipeline stages used by draw list.

As detailed in the comment, it seems it's necessary to rely on ALL_GRAPHICS even if all the stage bits are manually specified.
Also fixes an issue that snuck by into a previous commit where breadcrumbs were only supposed to be enabled on dev or debug builds.
This commit is contained in:
Dario 2024-10-22 10:18:03 -03:00
parent 4ad424234f
commit 933fca0d90
3 changed files with 16 additions and 35 deletions

View file

@ -3823,7 +3823,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin_for_screen(DisplayS
clear_value.color = p_clear_color;
RDD::RenderPassID render_pass = driver->swap_chain_get_render_pass(sc_it->value);
draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, clear_value, true, false, RDD::BreadcrumbMarker::BLIT_PASS);
draw_graph.add_draw_list_begin(render_pass, fb_it->value, viewport, clear_value, RDD::BreadcrumbMarker::BLIT_PASS);
draw_graph.add_draw_list_set_viewport(viewport);
draw_graph.add_draw_list_set_scissor(viewport);
@ -3876,8 +3876,6 @@ Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer,
thread_local LocalVector<RDD::RenderPassClearValue> clear_values;
thread_local LocalVector<RDG::ResourceTracker *> resource_trackers;
thread_local LocalVector<RDG::ResourceUsage> resource_usages;
bool uses_color = false;
bool uses_depth = false;
clear_values.clear();
clear_values.resize(p_framebuffer->texture_ids.size());
resource_trackers.clear();
@ -3907,20 +3905,18 @@ Error RenderingDevice::_draw_list_render_pass_begin(Framebuffer *p_framebuffer,
resource_trackers.push_back(texture->draw_tracker);
resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE);
uses_color = true;
} else if (texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
clear_value.depth = p_clear_depth;
clear_value.stencil = p_clear_stencil;
resource_trackers.push_back(texture->draw_tracker);
resource_usages.push_back(RDG::RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE);
uses_depth = true;
}
clear_values[clear_values_count++] = clear_value;
}
}
draw_graph.add_draw_list_begin(p_render_pass, p_framebuffer_driver_id, Rect2i(p_viewport_offset, p_viewport_size), clear_values, uses_color, uses_depth, p_breadcrumb);
draw_graph.add_draw_list_begin(p_render_pass, p_framebuffer_driver_id, Rect2i(p_viewport_offset, p_viewport_size), clear_values, p_breadcrumb);
draw_graph.add_draw_list_usages(resource_trackers, resource_usages);
// Mark textures as bound.
@ -4095,7 +4091,7 @@ void RenderingDevice::draw_list_bind_render_pipeline(DrawListID p_list, RID p_re
dl->state.pipeline = p_render_pipeline;
draw_graph.add_draw_list_bind_pipeline(pipeline->driver_id, pipeline->stage_bits);
draw_graph.add_draw_list_bind_pipeline(pipeline->driver_id);
if (dl->state.pipeline_shader != pipeline->shader) {
// Shader changed, so descriptor sets may become incompatible.

View file

@ -34,7 +34,10 @@
#define FORCE_FULL_ACCESS_BITS 0
#define PRINT_RESOURCE_TRACKER_TOTAL 0
#define PRINT_COMMAND_RECORDING 0
#if defined(DEV_ENABLED) || defined(DEBUG_ENABLED)
#define INSERT_BREADCRUMBS 1
#endif
RenderingDeviceGraph::RenderingDeviceGraph() {
driver_honors_barriers = false;
@ -1424,7 +1427,6 @@ void RenderingDeviceGraph::add_compute_list_bind_pipeline(RDD::PipelineID p_pipe
ComputeListBindPipelineInstruction *instruction = reinterpret_cast<ComputeListBindPipelineInstruction *>(_allocate_compute_list_instruction(sizeof(ComputeListBindPipelineInstruction)));
instruction->type = ComputeListInstruction::TYPE_BIND_PIPELINE;
instruction->pipeline = p_pipeline;
compute_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT);
}
void RenderingDeviceGraph::add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) {
@ -1448,7 +1450,6 @@ void RenderingDeviceGraph::add_compute_list_dispatch_indirect(RDD::BufferID p_bu
instruction->type = ComputeListInstruction::TYPE_DISPATCH_INDIRECT;
instruction->buffer = p_buffer;
instruction->offset = p_offset;
compute_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_DRAW_INDIRECT_BIT);
}
void RenderingDeviceGraph::add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size) {
@ -1500,13 +1501,13 @@ void RenderingDeviceGraph::add_compute_list_end() {
uint32_t command_size = sizeof(RecordedComputeListCommand) + instruction_data_size;
RecordedComputeListCommand *command = static_cast<RecordedComputeListCommand *>(_allocate_command(command_size, command_index));
command->type = RecordedCommand::TYPE_COMPUTE_LIST;
command->self_stages = compute_instruction_list.stages;
command->self_stages = RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT | RDD::PIPELINE_STAGE_DRAW_INDIRECT_BIT;
command->instruction_data_size = instruction_data_size;
memcpy(command->instruction_data(), compute_instruction_list.data.ptr(), instruction_data_size);
_add_command_to_graph(compute_instruction_list.command_trackers.ptr(), compute_instruction_list.command_tracker_usages.ptr(), compute_instruction_list.command_trackers.size(), command_index, command);
}
void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb) {
void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, uint32_t p_breadcrumb) {
draw_instruction_list.clear();
draw_instruction_list.index++;
draw_instruction_list.render_pass = p_render_pass;
@ -1517,15 +1518,6 @@ void RenderingDeviceGraph::add_draw_list_begin(RDD::RenderPassID p_render_pass,
for (uint32_t i = 0; i < p_clear_values.size(); i++) {
draw_instruction_list.clear_values[i] = p_clear_values[i];
}
if (p_uses_color) {
draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}
if (p_uses_depth) {
draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
}
}
void RenderingDeviceGraph::add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset) {
@ -1534,17 +1526,12 @@ void RenderingDeviceGraph::add_draw_list_bind_index_buffer(RDD::BufferID p_buffe
instruction->buffer = p_buffer;
instruction->format = p_format;
instruction->offset = p_offset;
if (instruction->buffer.id != 0) {
draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT);
}
}
void RenderingDeviceGraph::add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits) {
void RenderingDeviceGraph::add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline) {
DrawListBindPipelineInstruction *instruction = reinterpret_cast<DrawListBindPipelineInstruction *>(_allocate_draw_list_instruction(sizeof(DrawListBindPipelineInstruction)));
instruction->type = DrawListInstruction::TYPE_BIND_PIPELINE;
instruction->pipeline = p_pipeline;
draw_instruction_list.stages = draw_instruction_list.stages | p_pipeline_stage_bits;
}
void RenderingDeviceGraph::add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index) {
@ -1569,10 +1556,6 @@ void RenderingDeviceGraph::add_draw_list_bind_vertex_buffers(VectorView<RDD::Buf
vertex_buffers[i] = p_vertex_buffers[i];
vertex_buffer_offsets[i] = p_vertex_buffer_offsets[i];
}
if (instruction->vertex_buffers_count > 0) {
draw_instruction_list.stages.set_flag(RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT);
}
}
void RenderingDeviceGraph::add_draw_list_clear_attachments(VectorView<RDD::AttachmentClear> p_attachments_clear, VectorView<Rect2i> p_attachments_clear_rect) {
@ -1711,13 +1694,17 @@ void RenderingDeviceGraph::add_draw_list_end() {
command_buffer_type = RDD::COMMAND_BUFFER_TYPE_PRIMARY;
}
// The usage of PIPELINE_STAGE_ALL_GRAPHICS_BIT is intentional to cover all possible graphics operations performed by draw lists.
// During testing, the VLL indicated there were possible synchronization errors between frames, even when specifying manually all
// the bits the Vulkan specification claims are equivalent. However, using ALL_GRAPHICS has shown different behavior and solved
// the errors reported by the synchronization layer. There's no exact explanation as to why this happens at the moment.
int32_t command_index;
uint32_t clear_values_size = sizeof(RDD::RenderPassClearValue) * draw_instruction_list.clear_values.size();
uint32_t instruction_data_size = draw_instruction_list.data.size();
uint32_t command_size = sizeof(RecordedDrawListCommand) + clear_values_size + instruction_data_size;
RecordedDrawListCommand *command = static_cast<RecordedDrawListCommand *>(_allocate_command(command_size, command_index));
command->type = RecordedCommand::TYPE_DRAW_LIST;
command->self_stages = draw_instruction_list.stages;
command->self_stages = RDD::PIPELINE_STAGE_ALL_GRAPHICS_BIT;
command->instruction_data_size = instruction_data_size;
command->render_pass = draw_instruction_list.render_pass;
command->framebuffer = draw_instruction_list.framebuffer;

View file

@ -209,14 +209,12 @@ private:
LocalVector<uint8_t> data;
LocalVector<ResourceTracker *> command_trackers;
LocalVector<ResourceUsage> command_tracker_usages;
BitField<RDD::PipelineStageBits> stages;
int32_t index = 0;
void clear() {
data.clear();
command_trackers.clear();
command_tracker_usages.clear();
stages.clear();
}
};
@ -670,9 +668,9 @@ public:
void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
void add_compute_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
void add_compute_list_end();
void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, bool p_uses_color, bool p_uses_depth, uint32_t p_breadcrumb = 0);
void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<RDD::RenderPassClearValue> p_clear_values, uint32_t p_breadcrumb = 0);
void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset);
void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits);
void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline);
void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
void add_draw_list_bind_vertex_buffers(VectorView<RDD::BufferID> p_vertex_buffers, VectorView<uint64_t> p_vertex_buffer_offsets);
void add_draw_list_clear_attachments(VectorView<RDD::AttachmentClear> p_attachments_clear, VectorView<Rect2i> p_attachments_clear_rect);