summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
blob: fa513cef7d89fd035a8d261a36ac348ed3681ea4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "Common/Assert.h"
#include "Common/MsgHandler.h"

#include "VideoBackends/Vulkan/ObjectCache.h"
#include "VideoBackends/Vulkan/Util.h"
#include "VideoBackends/Vulkan/VKPipeline.h"
#include "VideoBackends/Vulkan/VKShader.h"
#include "VideoBackends/Vulkan/VertexFormat.h"
#include "VideoBackends/Vulkan/VulkanContext.h"

namespace Vulkan
{
VKPipeline::VKPipeline(VkPipeline pipeline, VkPipelineLayout pipeline_layout,
                       AbstractPipelineUsage usage)
    : m_pipeline(pipeline), m_pipeline_layout(pipeline_layout), m_usage(usage)
{
}

VKPipeline::~VKPipeline()
{
  vkDestroyPipeline(g_vulkan_context->GetDevice(), m_pipeline, nullptr);
}

std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& config)
{
  DEBUG_ASSERT(config.vertex_shader && config.pixel_shader);

  // Get render pass for config.
  VkRenderPass render_pass = g_object_cache->GetRenderPass(
      Util::GetVkFormatForHostTextureFormat(config.framebuffer_state.color_texture_format),
      Util::GetVkFormatForHostTextureFormat(config.framebuffer_state.depth_texture_format),
      config.framebuffer_state.samples, VK_ATTACHMENT_LOAD_OP_LOAD);

  // Get pipeline layout.
  VkPipelineLayout pipeline_layout;
  switch (config.usage)
  {
  case AbstractPipelineUsage::GX:
    pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_STANDARD);
    break;
  case AbstractPipelineUsage::Utility:
    pipeline_layout = g_object_cache->GetPipelineLayout(PIPELINE_LAYOUT_UTILITY);
    break;
  default:
    PanicAlert("Unknown pipeline layout.");
    return nullptr;
  }

  // TODO: Move ShaderCache stuff to here.
  PipelineInfo pinfo;
  pinfo.vertex_format = static_cast<const VertexFormat*>(config.vertex_format);
  pinfo.pipeline_layout = pipeline_layout;
  pinfo.vs = static_cast<const VKShader*>(config.vertex_shader)->GetShaderModule();
  pinfo.ps = static_cast<const VKShader*>(config.pixel_shader)->GetShaderModule();
  pinfo.gs = config.geometry_shader ?
                 static_cast<const VKShader*>(config.geometry_shader)->GetShaderModule() :
                 VK_NULL_HANDLE;
  pinfo.render_pass = render_pass;
  pinfo.rasterization_state.hex = config.rasterization_state.hex;
  pinfo.depth_state.hex = config.depth_state.hex;
  pinfo.blend_state.hex = config.blending_state.hex;
  pinfo.multisampling_state.hex = 0;
  pinfo.multisampling_state.samples = config.framebuffer_state.samples;
  pinfo.multisampling_state.per_sample_shading = config.framebuffer_state.per_sample_shading;

  VkPipeline pipeline = g_shader_cache->CreatePipeline(pinfo);
  if (pipeline == VK_NULL_HANDLE)
    return nullptr;

  return std::make_unique<VKPipeline>(pipeline, pipeline_layout, config.usage);
}
}  // namespace Vulkan