示例#1
0
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;
}
示例#2
0
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();
}
示例#3
0
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;
}
示例#4
0
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;
}