コード例 #1
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
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::SetFramebuffer(VkFramebuffer framebuffer, const VkRect2D& render_area)
{
	// Should not be changed within a render pass.
	_assert_(!InRenderPass());
	m_framebuffer = framebuffer;
	m_framebuffer_size = render_area;
}
コード例 #3
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
void StateTracker::EndRenderPass()
{
  if (!InRenderPass())
    return;

  vkCmdEndRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer());
  m_current_render_pass = VK_NULL_HANDLE;
}
コード例 #4
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
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;
}
コード例 #5
0
void StateTracker::SetRenderPass(VkRenderPass load_render_pass, VkRenderPass clear_render_pass)
{
	// Should not be changed within a render pass.
	_assert_(!InRenderPass());

	// The clear and load render passes are compatible, so we don't need to change our pipeline.
	if (m_pipeline_state.render_pass != load_render_pass)
	{
		m_pipeline_state.render_pass = load_render_pass;
		m_dirty_flags |= DIRTY_FLAG_PIPELINE;
	}

	m_load_render_pass = load_render_pass;
	m_clear_render_pass = clear_render_pass;
}
コード例 #6
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
void StateTracker::BeginClearRenderPass(const VkRect2D& area, const VkClearValue* clear_values,
                                        u32 num_clear_values)
{
  ASSERT(!InRenderPass());

  m_current_render_pass = m_framebuffer->GetClearRenderPass();
  m_framebuffer_render_area = area;

  VkRenderPassBeginInfo begin_info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                                      nullptr,
                                      m_current_render_pass,
                                      m_framebuffer->GetFB(),
                                      m_framebuffer_render_area,
                                      num_clear_values,
                                      clear_values};

  vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info,
                       VK_SUBPASS_CONTENTS_INLINE);
}
コード例 #7
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
void StateTracker::BeginDiscardRenderPass()
{
  if (InRenderPass())
    return;

  m_current_render_pass = m_framebuffer->GetDiscardRenderPass();
  m_framebuffer_render_area = m_framebuffer->GetRect();

  VkRenderPassBeginInfo begin_info = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                                      nullptr,
                                      m_current_render_pass,
                                      m_framebuffer->GetFB(),
                                      m_framebuffer_render_area,
                                      0,
                                      nullptr};

  vkCmdBeginRenderPass(g_command_buffer_mgr->GetCurrentCommandBuffer(), &begin_info,
                       VK_SUBPASS_CONTENTS_INLINE);
}
コード例 #8
0
ファイル: StateTracker.cpp プロジェクト: Sintendo/dolphin
void StateTracker::SetFramebuffer(VKFramebuffer* framebuffer)
{
  // Should not be changed within a render pass.
  ASSERT(!InRenderPass());
  m_framebuffer = framebuffer;
}
コード例 #9
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;
}