bool StateTracker::BindCompute() { if (!m_compute_shader) return false; // Can't kick compute in a render pass. if (InRenderPass()) EndRenderPass(); const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); if (m_dirty_flags & DIRTY_FLAG_COMPUTE_SHADER) { vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_compute_shader->GetComputePipeline()); } if (!UpdateComputeDescriptorSet()) { WARN_LOG(VIDEO, "Failed to get a compute descriptor set, executing buffer"); Renderer::GetInstance()->ExecuteCommandBuffer(false, false); if (!UpdateComputeDescriptorSet()) { // Something strange going on. ERROR_LOG(VIDEO, "Failed to get descriptor set, skipping dispatch"); return false; } } m_dirty_flags &= ~DIRTY_FLAG_COMPUTE_SHADER; return true; }
void StateTracker::EndClearRenderPass() { if (m_current_render_pass != m_framebuffer->GetClearRenderPass()) return; // End clear render pass. Bind() will call BeginRenderPass() which // will switch to the load/store render pass. EndRenderPass(); }
bool StateTracker::Bind() { // Must have a pipeline. if (!m_pipeline) return false; // Check the render area if we were in a clear pass. if (m_current_render_pass == m_framebuffer->GetClearRenderPass() && !IsViewportWithinRenderArea()) EndRenderPass(); // Get a new descriptor set if any parts have changed if (!UpdateDescriptorSet()) { // We can fail to allocate descriptors if we exhaust the pool for this command buffer. WARN_LOG(VIDEO, "Failed to get a descriptor set, executing buffer"); Renderer::GetInstance()->ExecuteCommandBuffer(false, false); if (!UpdateDescriptorSet()) { // Something strange going on. ERROR_LOG(VIDEO, "Failed to get descriptor set, skipping draw"); return false; } } // Start render pass if not already started if (!InRenderPass()) BeginRenderPass(); // Re-bind parts of the pipeline const VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); if (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER) vkCmdBindVertexBuffers(command_buffer, 0, 1, &m_vertex_buffer, &m_vertex_buffer_offset); if (m_dirty_flags & DIRTY_FLAG_INDEX_BUFFER) vkCmdBindIndexBuffer(command_buffer, m_index_buffer, m_index_buffer_offset, m_index_type); if (m_dirty_flags & DIRTY_FLAG_PIPELINE) vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline->GetVkPipeline()); if (m_dirty_flags & DIRTY_FLAG_VIEWPORT) vkCmdSetViewport(command_buffer, 0, 1, &m_viewport); if (m_dirty_flags & DIRTY_FLAG_SCISSOR) vkCmdSetScissor(command_buffer, 0, 1, &m_scissor); m_dirty_flags &= ~(DIRTY_FLAG_VERTEX_BUFFER | DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_PIPELINE | DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR); return true; }
bool StateTracker::Bind(bool rebind_all /*= false*/) { // Check the render area if we were in a clear pass. if (m_current_render_pass == m_clear_render_pass && !IsViewportWithinRenderArea()) EndRenderPass(); // Get new pipeline object if any parts have changed if (m_dirty_flags & DIRTY_FLAG_PIPELINE && !UpdatePipeline()) { ERROR_LOG(VIDEO, "Failed to get pipeline object, skipping draw"); return false; } // Get a new descriptor set if any parts have changed if (m_dirty_flags & DIRTY_FLAG_ALL_DESCRIPTOR_SETS && !UpdateDescriptorSet()) { // We can fail to allocate descriptors if we exhaust the pool for this command buffer. WARN_LOG(VIDEO, "Failed to get a descriptor set, executing buffer"); Util::ExecuteCurrentCommandsAndRestoreState(false, false); if (!UpdateDescriptorSet()) { // Something strange going on. ERROR_LOG(VIDEO, "Failed to get descriptor set, skipping draw"); return false; } } // Start render pass if not already started if (!InRenderPass()) BeginRenderPass(); // Re-bind parts of the pipeline VkCommandBuffer command_buffer = g_command_buffer_mgr->GetCurrentCommandBuffer(); if (m_dirty_flags & DIRTY_FLAG_PIPELINE_BINDING || rebind_all) vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_object); if (m_dirty_flags & DIRTY_FLAG_VERTEX_BUFFER || rebind_all) vkCmdBindVertexBuffers(command_buffer, 0, 1, &m_vertex_buffer, &m_vertex_buffer_offset); if (m_dirty_flags & DIRTY_FLAG_INDEX_BUFFER || rebind_all) vkCmdBindIndexBuffer(command_buffer, m_index_buffer, m_index_buffer_offset, m_index_type); if (m_dirty_flags & DIRTY_FLAG_DESCRIPTOR_SET_BINDING || rebind_all) { vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_state.pipeline_layout, 0, m_num_active_descriptor_sets, m_descriptor_sets.data(), NUM_UBO_DESCRIPTOR_SET_BINDINGS, m_bindings.uniform_buffer_offsets.data()); } else if (m_dirty_flags & DIRTY_FLAG_DYNAMIC_OFFSETS) { vkCmdBindDescriptorSets( command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline_state.pipeline_layout, DESCRIPTOR_SET_BIND_POINT_UNIFORM_BUFFERS, 1, &m_descriptor_sets[DESCRIPTOR_SET_BIND_POINT_UNIFORM_BUFFERS], NUM_UBO_DESCRIPTOR_SET_BINDINGS, m_bindings.uniform_buffer_offsets.data()); } if (m_dirty_flags & DIRTY_FLAG_VIEWPORT || rebind_all) vkCmdSetViewport(command_buffer, 0, 1, &m_viewport); if (m_dirty_flags & DIRTY_FLAG_SCISSOR || rebind_all) vkCmdSetScissor(command_buffer, 0, 1, &m_scissor); m_dirty_flags = 0; return true; }