vk_rasterizer: Move vertex array setup to AccelerateDrawBatch
* Avoids state invalidating due to scheduler flushes
This commit is contained in:
		| @@ -143,6 +143,7 @@ protected: | |||||||
|     Memory::MemorySystem& memory; |     Memory::MemorySystem& memory; | ||||||
|     Pica::Regs& regs; |     Pica::Regs& regs; | ||||||
|  |  | ||||||
|  |     VertexArrayInfo vertex_info; | ||||||
|     std::vector<HardwareVertex> vertex_batch; |     std::vector<HardwareVertex> vertex_batch; | ||||||
|     bool shader_dirty = true; |     bool shader_dirty = true; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -955,8 +955,8 @@ void RendererVulkan::DrawScreens(Frame* frame, const Layout::FramebufferLayout& | |||||||
|         const vk::ImageMemoryBarrier render_barrier = { |         const vk::ImageMemoryBarrier render_barrier = { | ||||||
|             .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite, |             .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite, | ||||||
|             .dstAccessMask = vk::AccessFlagBits::eTransferRead, |             .dstAccessMask = vk::AccessFlagBits::eTransferRead, | ||||||
|             .oldLayout = vk::ImageLayout::eGeneral, |             .oldLayout = vk::ImageLayout::eTransferSrcOptimal, | ||||||
|             .newLayout = vk::ImageLayout::eGeneral, |             .newLayout = vk::ImageLayout::eTransferSrcOptimal, | ||||||
|             .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |             .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | ||||||
|             .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |             .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | ||||||
|             .image = image, |             .image = image, | ||||||
|   | |||||||
| @@ -52,6 +52,8 @@ constexpr vk::ImageUsageFlags NULL_STORAGE_USAGE = NULL_USAGE | vk::ImageUsageFl | |||||||
| struct DrawParams { | struct DrawParams { | ||||||
|     u32 vertex_count; |     u32 vertex_count; | ||||||
|     s32 vertex_offset; |     s32 vertex_offset; | ||||||
|  |     u32 binding_count; | ||||||
|  |     std::array<u32, 16> bindings; | ||||||
|     bool is_indexed; |     bool is_indexed; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -175,8 +177,8 @@ void RasterizerVulkan::SyncFixedState() { | |||||||
|     SyncDepthWriteMask(); |     SyncDepthWriteMask(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_min, | void RasterizerVulkan::SetupVertexArray() { | ||||||
|                                         u32 vs_input_index_max) { |     const auto [vs_input_index_min, vs_input_index_max, vs_input_size] = vertex_info; | ||||||
|     auto [array_ptr, array_offset, invalidate] = stream_buffer.Map(vs_input_size, 16); |     auto [array_ptr, array_offset, invalidate] = stream_buffer.Map(vs_input_size, 16); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -270,12 +272,6 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi | |||||||
|  |  | ||||||
|     // Assign the rest of the attributes to the last binding |     // Assign the rest of the attributes to the last binding | ||||||
|     SetupFixedAttribs(); |     SetupFixedAttribs(); | ||||||
|  |  | ||||||
|     // Bind the generated bindings |  | ||||||
|     scheduler.Record([this, binding_count = layout.binding_count, |  | ||||||
|                       vertex_offsets = binding_offsets](vk::CommandBuffer cmdbuf) { |  | ||||||
|         cmdbuf.bindVertexBuffers(0, binding_count, vertex_buffers.data(), vertex_offsets.data()); |  | ||||||
|     }); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void RasterizerVulkan::SetupFixedAttribs() { | void RasterizerVulkan::SetupFixedAttribs() { | ||||||
| @@ -366,13 +362,7 @@ bool RasterizerVulkan::AccelerateDrawBatch(bool is_indexed) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return Draw(true, is_indexed); |     pipeline_info.rasterization.topology.Assign(regs.pipeline.triangle_topology); | ||||||
| } |  | ||||||
|  |  | ||||||
| bool RasterizerVulkan::AccelerateDrawBatchInternal(bool is_indexed) { |  | ||||||
|     const auto [vs_input_index_min, vs_input_index_max, vs_input_size] = |  | ||||||
|         AnalyzeVertexArray(is_indexed, instance.GetMinVertexStrideAlignment()); |  | ||||||
|  |  | ||||||
|     if (regs.pipeline.triangle_topology == TriangleTopology::Fan && |     if (regs.pipeline.triangle_topology == TriangleTopology::Fan && | ||||||
|         !instance.IsTriangleFanSupported()) { |         !instance.IsTriangleFanSupported()) { | ||||||
|         LOG_DEBUG(Render_Vulkan, |         LOG_DEBUG(Render_Vulkan, | ||||||
| @@ -380,31 +370,43 @@ bool RasterizerVulkan::AccelerateDrawBatchInternal(bool is_indexed) { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SetupVertexArray(vs_input_size, vs_input_index_min, vs_input_index_max); |     // Vertex data analysis and setup might involve rasterizer cache memory flushes | ||||||
|     if (is_indexed) { |     // so perform it early to avoid invalidating our state in the middle of the draw | ||||||
|         SetupIndexArray(); |     vertex_info = AnalyzeVertexArray(is_indexed, instance.GetMinVertexStrideAlignment()); | ||||||
|     } |     SetupVertexArray(); | ||||||
|  |  | ||||||
|     if (!SetupVertexShader()) { |     if (!SetupVertexShader()) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!SetupGeometryShader()) { |     if (!SetupGeometryShader()) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pipeline_info.rasterization.topology.Assign(regs.pipeline.triangle_topology); |     return Draw(true, is_indexed); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool RasterizerVulkan::AccelerateDrawBatchInternal(bool is_indexed) { | ||||||
|  |     if (is_indexed) { | ||||||
|  |         SetupIndexArray(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (!pipeline_cache.BindPipeline(pipeline_info, !async_shaders)) { |     if (!pipeline_cache.BindPipeline(pipeline_info, !async_shaders)) { | ||||||
|         return true; ///< Skip draw call when pipeline is not ready |         return true; // Skip draw call when pipeline is not ready | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const DrawParams params = { |     const DrawParams params = { | ||||||
|         .vertex_count = regs.pipeline.num_vertices, |         .vertex_count = regs.pipeline.num_vertices, | ||||||
|         .vertex_offset = -static_cast<s32>(vs_input_index_min), |         .vertex_offset = -static_cast<s32>(vertex_info.vs_input_index_min), | ||||||
|  |         .binding_count = pipeline_info.vertex_layout.binding_count, | ||||||
|  |         .bindings = binding_offsets, | ||||||
|         .is_indexed = is_indexed, |         .is_indexed = is_indexed, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     scheduler.Record([params](vk::CommandBuffer cmdbuf) { |     scheduler.Record([this, params](vk::CommandBuffer cmdbuf) { | ||||||
|  |         std::array<u64, 16> offsets; | ||||||
|  |         std::copy(params.bindings.begin(), params.bindings.end(), offsets.begin()); | ||||||
|  |  | ||||||
|  |         cmdbuf.bindVertexBuffers(0, params.binding_count, vertex_buffers.data(), offsets.data()); | ||||||
|         if (params.is_indexed) { |         if (params.is_indexed) { | ||||||
|             cmdbuf.drawIndexed(params.vertex_count, 1, 0, params.vertex_offset, 0); |             cmdbuf.drawIndexed(params.vertex_count, 1, 0, params.vertex_offset, 0); | ||||||
|         } else { |         } else { | ||||||
| @@ -448,6 +450,12 @@ void RasterizerVulkan::DrawTriangles() { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     pipeline_info.rasterization.topology.Assign(Pica::PipelineRegs::TriangleTopology::List); | ||||||
|  |     pipeline_info.vertex_layout = software_layout; | ||||||
|  |  | ||||||
|  |     pipeline_cache.UseTrivialVertexShader(); | ||||||
|  |     pipeline_cache.UseTrivialGeometryShader(); | ||||||
|  |  | ||||||
|     Draw(false, false); |     Draw(false, false); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -706,10 +714,6 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { | |||||||
|     if (accelerate) { |     if (accelerate) { | ||||||
|         succeeded = AccelerateDrawBatchInternal(is_indexed); |         succeeded = AccelerateDrawBatchInternal(is_indexed); | ||||||
|     } else { |     } else { | ||||||
|         pipeline_info.rasterization.topology.Assign(Pica::PipelineRegs::TriangleTopology::List); |  | ||||||
|         pipeline_info.vertex_layout = software_layout; |  | ||||||
|         pipeline_cache.UseTrivialVertexShader(); |  | ||||||
|         pipeline_cache.UseTrivialGeometryShader(); |  | ||||||
|         pipeline_cache.BindPipeline(pipeline_info, true); |         pipeline_cache.BindPipeline(pipeline_info, true); | ||||||
|  |  | ||||||
|         const u32 max_vertices = STREAM_BUFFER_SIZE / sizeof(HardwareVertex); |         const u32 max_vertices = STREAM_BUFFER_SIZE / sizeof(HardwareVertex); | ||||||
|   | |||||||
| @@ -135,7 +135,7 @@ private: | |||||||
|     void SetupIndexArray(); |     void SetupIndexArray(); | ||||||
|  |  | ||||||
|     /// Setup vertex array for AccelerateDrawBatch |     /// Setup vertex array for AccelerateDrawBatch | ||||||
|     void SetupVertexArray(u32 vs_input_size, u32 vs_input_index_min, u32 vs_input_index_max); |     void SetupVertexArray(); | ||||||
|  |  | ||||||
|     /// Setup the fixed attribute emulation in vulkan |     /// Setup the fixed attribute emulation in vulkan | ||||||
|     void SetupFixedAttribs(); |     void SetupFixedAttribs(); | ||||||
| @@ -162,7 +162,7 @@ private: | |||||||
|     PipelineCache pipeline_cache; |     PipelineCache pipeline_cache; | ||||||
|  |  | ||||||
|     VertexLayout software_layout; |     VertexLayout software_layout; | ||||||
|     std::array<u64, 16> binding_offsets{}; |     std::array<u32, 16> binding_offsets{}; | ||||||
|     std::array<bool, 16> enable_attributes{}; |     std::array<bool, 16> enable_attributes{}; | ||||||
|     std::array<vk::Buffer, 16> vertex_buffers; |     std::array<vk::Buffer, 16> vertex_buffers; | ||||||
|     vk::Sampler default_sampler; |     vk::Sampler default_sampler; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user