diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 7b7f71d67d1..ea5f3be926b 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -487,6 +487,7 @@ struct GHOST_InstanceVK { device_features.drawIndirectFirstInstance = VK_TRUE; device_features.fragmentStoresAndAtomics = VK_TRUE; device_features.samplerAnisotropy = device.features.features.samplerAnisotropy; + device_features.wideLines = device.features.features.wideLines; VkDeviceCreateInfo device_create_info = {}; device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; diff --git a/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_indirect_node.hh b/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_indirect_node.hh index 1c24ad48a32..b0c47f6880e 100644 --- a/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_indirect_node.hh +++ b/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_indirect_node.hh @@ -17,10 +17,9 @@ namespace blender::gpu::render_graph { * Information stored inside the render graph node. See `VKRenderGraphNode`. */ struct VKDrawIndexedIndirectData { - VKPipelineData pipeline_data; + VKPipelineDataGraphics graphics; VKIndexBufferBinding index_buffer; VKVertexBufferBindings vertex_buffers; - VKViewportData viewport_data; VkBuffer indirect_buffer; VkDeviceSize offset; uint32_t draw_count; @@ -51,8 +50,8 @@ class VKDrawIndexedIndirectNode static void set_node_data(Node &node, Storage &storage, const CreateInfo &create_info) { node.storage_index = storage.draw_indexed_indirect.append_and_get_index(create_info.node_data); - vk_pipeline_data_copy(storage.draw_indexed_indirect[node.storage_index].pipeline_data, - create_info.node_data.pipeline_data); + vk_pipeline_data_copy(storage.draw_indexed_indirect[node.storage_index].graphics, + create_info.node_data.graphics); } /** @@ -82,10 +81,10 @@ class VKDrawIndexedIndirectNode Data &data, VKBoundPipelines &r_bound_pipelines) override { - vk_pipeline_viewport_set_commands( - command_buffer, data.viewport_data, r_bound_pipelines.graphics.viewport_state); + vk_pipeline_dynamic_graphics_build_commands( + command_buffer, data.graphics.viewport, data.graphics.line_width, r_bound_pipelines); vk_pipeline_data_build_commands(command_buffer, - data.pipeline_data, + data.graphics.pipeline_data, r_bound_pipelines.graphics.pipeline, VK_PIPELINE_BIND_POINT_GRAPHICS, VK_SHADER_STAGE_ALL_GRAPHICS); @@ -99,7 +98,7 @@ class VKDrawIndexedIndirectNode void free_data(Data &data) { - vk_pipeline_data_free(data.pipeline_data); + vk_pipeline_data_free(data.graphics); } }; } // namespace blender::gpu::render_graph diff --git a/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_node.hh b/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_node.hh index 97a7826ba27..0d6aa2e4d4e 100644 --- a/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_node.hh +++ b/source/blender/gpu/vulkan/render_graph/nodes/vk_draw_indexed_node.hh @@ -17,10 +17,9 @@ namespace blender::gpu::render_graph { * Information stored inside the render graph node. See `VKRenderGraphNode`. */ struct VKDrawIndexedData { - VKPipelineData pipeline_data; + VKPipelineDataGraphics graphics; VKIndexBufferBinding index_buffer; VKVertexBufferBindings vertex_buffers; - VKViewportData viewport_data; uint32_t index_count; uint32_t instance_count; uint32_t first_index; @@ -51,8 +50,8 @@ class VKDrawIndexedNode : public VKNodeInfo line_width, + VKBoundPipelines &r_bound_pipelines) { - if (assign_if_different(r_viewport_state, viewport_data)) { - command_buffer.set_viewport(viewport_data.viewports); - command_buffer.set_scissor(viewport_data.scissors); + if (assign_if_different(r_bound_pipelines.graphics.viewport_state, viewport)) { + command_buffer.set_viewport(viewport.viewports); + command_buffer.set_scissor(viewport.scissors); + } + if (assign_if_different(r_bound_pipelines.graphics.line_width, line_width)) { + if (line_width.has_value()) { + command_buffer.set_line_width(*line_width); + } } } diff --git a/source/blender/gpu/vulkan/render_graph/nodes/vk_pipeline_data.hh b/source/blender/gpu/vulkan/render_graph/nodes/vk_pipeline_data.hh index 052bcb65a5d..37c30b0d87e 100644 --- a/source/blender/gpu/vulkan/render_graph/nodes/vk_pipeline_data.hh +++ b/source/blender/gpu/vulkan/render_graph/nodes/vk_pipeline_data.hh @@ -65,6 +65,12 @@ struct VKViewportData { } }; +struct VKPipelineDataGraphics { + VKPipelineData pipeline_data; + VKViewportData viewport; + std::optional line_width; +}; + /** Resources bound for a compute/graphics pipeline. */ struct VKBoundPipeline { VkPipeline vk_pipeline; @@ -119,6 +125,7 @@ struct VKBoundPipelines { VKIndexBufferBinding index_buffer; VKVertexBufferBindings vertex_buffers; VKViewportData viewport_state; + std::optional line_width; } graphics; }; @@ -130,15 +137,23 @@ struct VKBoundPipelines { * guardedalloc. */ void vk_pipeline_data_copy(VKPipelineData &dst, const VKPipelineData &src); +static inline void vk_pipeline_data_copy(VKPipelineDataGraphics &dst, + const VKPipelineDataGraphics &src) +{ + vk_pipeline_data_copy(dst.pipeline_data, src.pipeline_data); +} /** - * Record commands that set the viewport and scissor only if the desired - * viewport state is different than the current viewport state. + * Record commands that update the dynamic state. * + * - viewports + * - scissors + * - line width */ -void vk_pipeline_viewport_set_commands(VKCommandBufferInterface &command_buffer, - const VKViewportData &viewport_data, - VKViewportData &r_viewport_state); +void vk_pipeline_dynamic_graphics_build_commands(VKCommandBufferInterface &command_buffer, + const VKViewportData &viewport, + const std::optional line_width, + VKBoundPipelines &r_bound_pipelines); /** * Record the commands to the given command buffer to bind the descriptor set, pipeline and push @@ -161,6 +176,10 @@ void vk_pipeline_data_build_commands(VKCommandBufferInterface &command_buffer, * Free localized data created by `vk_pipeline_data_copy`. */ void vk_pipeline_data_free(VKPipelineData &data); +static inline void vk_pipeline_data_free(VKPipelineDataGraphics &data) +{ + vk_pipeline_data_free(data.pipeline_data); +} void vk_index_buffer_binding_build_links(VKResourceStateTracker &resources, VKRenderGraphNodeLinks &node_links, diff --git a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_render.cc b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_render.cc index b0da2a593a3..49e0f4e936c 100644 --- a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_render.cc +++ b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_render.cc @@ -172,13 +172,13 @@ TEST_P(VKRenderGraphTestRender, begin_draw_end) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -258,13 +258,13 @@ TEST_P(VKRenderGraphTestRender, begin_draw_end__layered) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } diff --git a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_scheduler.cc b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_scheduler.cc index 7b75a1a7a66..45a1c0ccd06 100644 --- a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_scheduler.cc +++ b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_scheduler.cc @@ -574,13 +574,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_draw_copy_framebuffer_draw_end) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline_combine; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout_combine; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline_combine; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout_combine; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -606,13 +606,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_draw_copy_framebuffer_draw_end) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline_background; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout_background; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline_background; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout_background; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -775,13 +775,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_update_draw_update_draw_update_draw_end draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 1; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -802,13 +802,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_update_draw_update_draw_update_draw_end draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 2; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -829,13 +829,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_update_draw_update_draw_update_draw_end draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 3; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -1000,13 +1000,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_draw_copy_to_attachment_draw_end) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } @@ -1032,13 +1032,13 @@ TEST_P(VKRenderGraphTestScheduler, begin_draw_copy_to_attachment_draw_end) draw.node_data.first_vertex = 0; draw.node_data.instance_count = 1; draw.node_data.vertex_count = 4; - draw.node_data.pipeline_data.push_constants_data = nullptr; - draw.node_data.pipeline_data.push_constants_size = 0; - draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; - draw.node_data.pipeline_data.vk_pipeline = pipeline; - draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout; - draw.node_data.viewport_data.viewports.append(VkViewport{}); - draw.node_data.viewport_data.scissors.append(VkRect2D{}); + draw.node_data.graphics.pipeline_data.push_constants_data = nullptr; + draw.node_data.graphics.pipeline_data.push_constants_size = 0; + draw.node_data.graphics.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE; + draw.node_data.graphics.pipeline_data.vk_pipeline = pipeline; + draw.node_data.graphics.pipeline_data.vk_pipeline_layout = pipeline_layout; + draw.node_data.graphics.viewport.viewports.append(VkViewport{}); + draw.node_data.graphics.viewport.scissors.append(VkRect2D{}); render_graph->add_node(draw); } diff --git a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_types.hh b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_types.hh index 6f010e5369e..0cba741cdf4 100644 --- a/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_types.hh +++ b/source/blender/gpu/vulkan/render_graph/tests/vk_render_graph_test_types.hh @@ -453,6 +453,14 @@ class CommandBufferLog : public VKCommandBufferInterface { log_.append(ss.str()); } + void set_line_width(const float line_width) override + { + EXPECT_TRUE(is_recording_); + std::stringstream ss; + ss << "set_line_width(line_width=" << line_width << ")"; + log_.append(ss.str()); + } + void begin_debug_utils_label(const VkDebugUtilsLabelEXT * /*vk_debug_utils_label*/) override {} void end_debug_utils_label() override {} diff --git a/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.cc b/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.cc index ff1532bf940..784bafe09b1 100644 --- a/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.cc +++ b/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.cc @@ -264,6 +264,10 @@ void VKCommandBufferWrapper::set_scissor(const Vector scissors) { vkCmdSetScissor(vk_command_buffer_, 0, scissors.size(), scissors.data()); } +void VKCommandBufferWrapper::set_line_width(const float line_width) +{ + vkCmdSetLineWidth(vk_command_buffer_, line_width); +} void VKCommandBufferWrapper::begin_rendering(const VkRenderingInfo *p_rendering_info) { diff --git a/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.hh b/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.hh index 49aed69a40a..2aece7eca32 100644 --- a/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.hh +++ b/source/blender/gpu/vulkan/render_graph/vk_command_buffer_wrapper.hh @@ -131,6 +131,7 @@ class VKCommandBufferInterface { uint32_t query_count) = 0; virtual void set_viewport(const Vector viewports) = 0; virtual void set_scissor(const Vector scissors) = 0; + virtual void set_line_width(const float line_width) = 0; /* VK_KHR_dynamic_rendering */ virtual void begin_rendering(const VkRenderingInfo *p_rendering_info) = 0; @@ -257,6 +258,7 @@ class VKCommandBufferWrapper : public VKCommandBufferInterface { const void *p_values) override; void set_viewport(const Vector viewports) override; void set_scissor(const Vector scissors) override; + void set_line_width(const float line_width) override; void begin_query(VkQueryPool vk_query_pool, uint32_t query_index, VkQueryControlFlags vk_query_control_flags) override; diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 7e3dab8a215..a96513cf3ce 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -428,6 +428,7 @@ void VKBackend::detect_workarounds(VKDevice &device) extensions.dynamic_rendering_unused_attachments = false; extensions.descriptor_buffer = false; extensions.pageable_device_local_memory = false; + extensions.wide_lines = false; GCaps.stencil_export_support = false; device.workarounds_ = workarounds; @@ -439,6 +440,7 @@ void VKBackend::detect_workarounds(VKDevice &device) device.physical_device_vulkan_12_features_get().shaderOutputLayer; extensions.shader_output_viewport_index = device.physical_device_vulkan_12_features_get().shaderOutputViewportIndex; + extensions.wide_lines = device.physical_device_features_get().wideLines; extensions.fragment_shader_barycentric = device.supports_extension( VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); extensions.dynamic_rendering_local_read = device.supports_extension( diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc index 77917354c3e..baf1b29eafe 100644 --- a/source/blender/gpu/vulkan/vk_batch.cc +++ b/source/blender/gpu/vulkan/vk_batch.cc @@ -44,14 +44,14 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i draw_indexed.node_data.first_instance = instance_first; context.active_framebuffer_get()->vk_viewports_append( - draw_indexed.node_data.viewport_data.viewports); + draw_indexed.node_data.graphics.viewport.viewports); context.active_framebuffer_get()->vk_render_areas_append( - draw_indexed.node_data.viewport_data.scissors); + draw_indexed.node_data.graphics.viewport.scissors); draw_indexed.node_data.index_buffer.buffer = index_buffer->vk_handle(); draw_indexed.node_data.index_buffer.index_type = index_buffer->vk_index_type(); vao.bind(draw_indexed.node_data.vertex_buffers); - context.update_pipeline_data(prim_type, vao, draw_indexed.node_data.pipeline_data); + context.update_pipeline_data(prim_type, vao, draw_indexed.node_data.graphics); context.render_graph().add_node(draw_indexed); } @@ -61,12 +61,13 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i draw.node_data.instance_count = instance_count; draw.node_data.first_vertex = vertex_first; draw.node_data.first_instance = instance_first; - context.active_framebuffer_get()->vk_viewports_append(draw.node_data.viewport_data.viewports); + context.active_framebuffer_get()->vk_viewports_append( + draw.node_data.graphics.viewport.viewports); context.active_framebuffer_get()->vk_render_areas_append( - draw.node_data.viewport_data.scissors); + draw.node_data.graphics.viewport.scissors); vao.bind(draw.node_data.vertex_buffers); - context.update_pipeline_data(prim_type, vao, draw.node_data.pipeline_data); + context.update_pipeline_data(prim_type, vao, draw.node_data.graphics); context.render_graph().add_node(draw); } @@ -114,14 +115,14 @@ void VKBatch::multi_draw_indirect(const VkBuffer indirect_buffer, draw_indexed_indirect.node_data.stride = stride; context.active_framebuffer_get()->vk_viewports_append( - draw_indexed_indirect.node_data.viewport_data.viewports); + draw_indexed_indirect.node_data.graphics.viewport.viewports); context.active_framebuffer_get()->vk_render_areas_append( - draw_indexed_indirect.node_data.viewport_data.scissors); + draw_indexed_indirect.node_data.graphics.viewport.scissors); draw_indexed_indirect.node_data.index_buffer.buffer = index_buffer->vk_handle(); draw_indexed_indirect.node_data.index_buffer.index_type = index_buffer->vk_index_type(); vao.bind(draw_indexed_indirect.node_data.vertex_buffers); - context.update_pipeline_data(prim_type, vao, draw_indexed_indirect.node_data.pipeline_data); + context.update_pipeline_data(prim_type, vao, draw_indexed_indirect.node_data.graphics); context.render_graph().add_node(draw_indexed_indirect); } @@ -131,12 +132,13 @@ void VKBatch::multi_draw_indirect(const VkBuffer indirect_buffer, draw.node_data.offset = offset; draw.node_data.draw_count = count; draw.node_data.stride = stride; - context.active_framebuffer_get()->vk_viewports_append(draw.node_data.viewport_data.viewports); + context.active_framebuffer_get()->vk_viewports_append( + draw.node_data.graphics.viewport.viewports); context.active_framebuffer_get()->vk_render_areas_append( - draw.node_data.viewport_data.scissors); + draw.node_data.graphics.viewport.scissors); vao.bind(draw.node_data.vertex_buffers); - context.update_pipeline_data(prim_type, vao, draw.node_data.pipeline_data); + context.update_pipeline_data(prim_type, vao, draw.node_data.graphics); context.render_graph().add_node(draw); } diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 9e3b2c05393..49710b8bb49 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -285,7 +285,7 @@ void VKContext::rendering_end() void VKContext::update_pipeline_data(GPUPrimType primitive, VKVertexAttributeObject &vao, - render_graph::VKPipelineData &r_pipeline_data) + render_graph::VKPipelineDataGraphics &r_pipeline_data) { VKShader &vk_shader = unwrap(*shader); VKFrameBuffer &framebuffer = *active_framebuffer_get(); @@ -296,10 +296,28 @@ void VKContext::update_pipeline_data(GPUPrimType primitive, GPU_shader_uniform_1f(shader, "size", -point_size); } + /* Dynamic state line width */ + const bool is_line_primitive = ELEM(primitive, + GPU_PRIM_LINES, + GPU_PRIM_LINE_LOOP, + GPU_PRIM_LINE_STRIP, + GPU_PRIM_LINES_ADJ, + GPU_PRIM_LINE_STRIP_ADJ); + + if (is_line_primitive) { + const bool supports_wide_lines = VKBackend::get().device.extensions_get().wide_lines; + r_pipeline_data.line_width = supports_wide_lines ? + state_manager_get().mutable_state.line_width : + 1.0f; + } + else { + r_pipeline_data.line_width.reset(); + } + update_pipeline_data(vk_shader, vk_shader.ensure_and_get_graphics_pipeline( primitive, vao, state_manager_get(), framebuffer, constants_state_), - r_pipeline_data); + r_pipeline_data.pipeline_data); } void VKContext::update_pipeline_data(render_graph::VKPipelineData &r_pipeline_data) diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index 5de362dbf90..8bd19765945 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -135,7 +135,7 @@ class VKContext : public Context, NonCopyable { void update_pipeline_data(render_graph::VKPipelineData &r_pipeline_data); void update_pipeline_data(GPUPrimType primitive, VKVertexAttributeObject &vao, - render_graph::VKPipelineData &r_pipeline_data); + render_graph::VKPipelineDataGraphics &r_pipeline_data); void sync_backbuffer(); diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index 22e74fe2d04..8bbca42204a 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -38,6 +38,7 @@ void VKExtensions::log() const " - [%c] shader output viewport index\n" " - [%c] shader output layer\n" " - [%c] fragment shader barycentric\n" + " - [%c] wide lines\n" "Device extensions\n" " - [%c] descriptor buffer\n" " - [%c] dynamic rendering local read\n" @@ -50,6 +51,7 @@ void VKExtensions::log() const shader_output_viewport_index ? 'X' : ' ', shader_output_layer ? 'X' : ' ', fragment_shader_barycentric ? 'X' : ' ', + wide_lines ? 'X' : ' ', descriptor_buffer ? 'X' : ' ', dynamic_rendering_local_read ? 'X' : ' ', dynamic_rendering_unused_attachments ? 'X' : ' ', diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index b3ef23407d8..cf102ed9571 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -41,6 +41,12 @@ struct VKExtensions { */ bool fragment_shader_barycentric = false; + /** + * Does the device support wide line rendering + * VkPhysicalDeviceFeatures::wideLines + */ + bool wide_lines = false; + /** * Does the device support VK_KHR_dynamic_rendering_local_read enabled. */ diff --git a/source/blender/gpu/vulkan/vk_immediate.cc b/source/blender/gpu/vulkan/vk_immediate.cc index 44e5f08c94c..f3dd7eaf87b 100644 --- a/source/blender/gpu/vulkan/vk_immediate.cc +++ b/source/blender/gpu/vulkan/vk_immediate.cc @@ -90,12 +90,13 @@ void VKImmediate::end() draw.node_data.first_vertex = 0; draw.node_data.first_instance = 0; - context.active_framebuffer_get()->vk_viewports_append(draw.node_data.viewport_data.viewports); + context.active_framebuffer_get()->vk_viewports_append( + draw.node_data.graphics.viewport.viewports); context.active_framebuffer_get()->vk_render_areas_append( - draw.node_data.viewport_data.scissors); + draw.node_data.graphics.viewport.scissors); vertex_attributes_.bind(draw.node_data.vertex_buffers); - context.update_pipeline_data(prim_type, vertex_attributes_, draw.node_data.pipeline_data); + context.update_pipeline_data(prim_type, vertex_attributes_, draw.node_data.graphics); context.render_graph().add_node(draw); } diff --git a/source/blender/gpu/vulkan/vk_pipeline_pool.cc b/source/blender/gpu/vulkan/vk_pipeline_pool.cc index 16965231a8c..f634958e367 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_pool.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_pool.cc @@ -101,7 +101,8 @@ VKPipelinePool::VKPipelinePool() vk_pipeline_rasterization_provoking_vertex_state_info_.provokingVertexMode = VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT; - vk_dynamic_states_ = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; + vk_dynamic_states_ = { + VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_LINE_WIDTH}; vk_pipeline_dynamic_state_create_info_ = {}; vk_pipeline_dynamic_state_create_info_.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; @@ -300,7 +301,13 @@ VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graph VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT; /* Dynamic state */ - vk_pipeline_dynamic_state_create_info_.dynamicStateCount = vk_dynamic_states_.size(); + const bool is_line_topology = ELEM(graphics_info.vertex_in.vk_topology, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP); + vk_pipeline_dynamic_state_create_info_.dynamicStateCount = is_line_topology ? + vk_dynamic_states_.size() : + vk_dynamic_states_.size() - 1; vk_pipeline_dynamic_state_create_info_.pDynamicStates = vk_dynamic_states_.data(); /* Viewport state */ @@ -583,7 +590,7 @@ VkPipeline VKPipelinePool::get_or_create_graphics_pipeline(VKGraphicsInfo &graph VKBackend &backend = VKBackend::get(); VKDevice &device = backend.device; if (device.extensions_get().descriptor_buffer) { - vk_graphics_pipeline_create_info_.flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; + vk_graphics_pipeline_create_info_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; } VkPipeline pipeline = VK_NULL_HANDLE;