mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 07:09:48 -06:00
Move most backend functionality to VideoCommon
This commit is contained in:
@ -6,9 +6,9 @@
|
||||
#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/VKTexture.h"
|
||||
#include "VideoBackends/Vulkan/VertexFormat.h"
|
||||
#include "VideoBackends/Vulkan/VulkanContext.h"
|
||||
|
||||
@ -25,14 +25,213 @@ VKPipeline::~VKPipeline()
|
||||
vkDestroyPipeline(g_vulkan_context->GetDevice(), m_pipeline, nullptr);
|
||||
}
|
||||
|
||||
static bool IsStripPrimitiveTopology(VkPrimitiveTopology topology)
|
||||
{
|
||||
return topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
|
||||
topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
|
||||
topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
|
||||
topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
|
||||
}
|
||||
|
||||
static VkPipelineRasterizationStateCreateInfo
|
||||
GetVulkanRasterizationState(const RasterizationState& state)
|
||||
{
|
||||
static constexpr std::array<VkCullModeFlags, 4> cull_modes = {
|
||||
{VK_CULL_MODE_NONE, VK_CULL_MODE_BACK_BIT, VK_CULL_MODE_FRONT_BIT,
|
||||
VK_CULL_MODE_FRONT_AND_BACK}};
|
||||
|
||||
bool depth_clamp = g_ActiveConfig.backend_info.bSupportsDepthClamp;
|
||||
|
||||
return {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineRasterizationStateCreateFlags flags
|
||||
depth_clamp, // VkBool32 depthClampEnable
|
||||
VK_FALSE, // VkBool32 rasterizerDiscardEnable
|
||||
VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
|
||||
cull_modes[state.cullmode], // VkCullModeFlags cullMode
|
||||
VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace
|
||||
VK_FALSE, // VkBool32 depthBiasEnable
|
||||
0.0f, // float depthBiasConstantFactor
|
||||
0.0f, // float depthBiasClamp
|
||||
0.0f, // float depthBiasSlopeFactor
|
||||
1.0f // float lineWidth
|
||||
};
|
||||
}
|
||||
|
||||
static VkPipelineMultisampleStateCreateInfo GetVulkanMultisampleState(const FramebufferState& state)
|
||||
{
|
||||
return {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineMultisampleStateCreateFlags flags
|
||||
static_cast<VkSampleCountFlagBits>(
|
||||
state.samples.Value()), // VkSampleCountFlagBits rasterizationSamples
|
||||
state.per_sample_shading, // VkBool32 sampleShadingEnable
|
||||
1.0f, // float minSampleShading
|
||||
nullptr, // const VkSampleMask* pSampleMask;
|
||||
VK_FALSE, // VkBool32 alphaToCoverageEnable
|
||||
VK_FALSE // VkBool32 alphaToOneEnable
|
||||
};
|
||||
}
|
||||
|
||||
static VkPipelineDepthStencilStateCreateInfo GetVulkanDepthStencilState(const DepthState& state)
|
||||
{
|
||||
// Less/greater are swapped due to inverted depth.
|
||||
VkCompareOp compare_op;
|
||||
bool inverted_depth = !g_ActiveConfig.backend_info.bSupportsReversedDepthRange;
|
||||
switch (state.func)
|
||||
{
|
||||
case ZMode::NEVER:
|
||||
compare_op = VK_COMPARE_OP_NEVER;
|
||||
break;
|
||||
case ZMode::LESS:
|
||||
compare_op = inverted_depth ? VK_COMPARE_OP_GREATER : VK_COMPARE_OP_LESS;
|
||||
break;
|
||||
case ZMode::EQUAL:
|
||||
compare_op = VK_COMPARE_OP_EQUAL;
|
||||
break;
|
||||
case ZMode::LEQUAL:
|
||||
compare_op = inverted_depth ? VK_COMPARE_OP_GREATER_OR_EQUAL : VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
break;
|
||||
case ZMode::GREATER:
|
||||
compare_op = inverted_depth ? VK_COMPARE_OP_LESS : VK_COMPARE_OP_GREATER;
|
||||
break;
|
||||
case ZMode::NEQUAL:
|
||||
compare_op = VK_COMPARE_OP_NOT_EQUAL;
|
||||
break;
|
||||
case ZMode::GEQUAL:
|
||||
compare_op = inverted_depth ? VK_COMPARE_OP_LESS_OR_EQUAL : VK_COMPARE_OP_GREATER_OR_EQUAL;
|
||||
break;
|
||||
case ZMode::ALWAYS:
|
||||
compare_op = VK_COMPARE_OP_ALWAYS;
|
||||
break;
|
||||
default:
|
||||
compare_op = VK_COMPARE_OP_ALWAYS;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineDepthStencilStateCreateFlags flags
|
||||
state.testenable, // VkBool32 depthTestEnable
|
||||
state.updateenable, // VkBool32 depthWriteEnable
|
||||
compare_op, // VkCompareOp depthCompareOp
|
||||
VK_FALSE, // VkBool32 depthBoundsTestEnable
|
||||
VK_FALSE, // VkBool32 stencilTestEnable
|
||||
{}, // VkStencilOpState front
|
||||
{}, // VkStencilOpState back
|
||||
0.0f, // float minDepthBounds
|
||||
1.0f // float maxDepthBounds
|
||||
};
|
||||
}
|
||||
|
||||
static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendingState& state)
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState vk_state = {};
|
||||
vk_state.blendEnable = static_cast<VkBool32>(state.blendenable);
|
||||
vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
|
||||
vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD;
|
||||
|
||||
if (state.usedualsrc && g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
|
||||
{
|
||||
static constexpr std::array<VkBlendFactor, 8> src_factors = {
|
||||
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
|
||||
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
|
||||
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
|
||||
|
||||
vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
|
||||
vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
|
||||
vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
|
||||
vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
|
||||
}
|
||||
else
|
||||
{
|
||||
static constexpr std::array<VkBlendFactor, 8> src_factors = {
|
||||
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
|
||||
|
||||
static constexpr std::array<VkBlendFactor, 8> dst_factors = {
|
||||
{VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
|
||||
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
|
||||
|
||||
vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
|
||||
vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
|
||||
vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
|
||||
vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
|
||||
}
|
||||
|
||||
if (state.colorupdate)
|
||||
{
|
||||
vk_state.colorWriteMask =
|
||||
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
vk_state.colorWriteMask = 0;
|
||||
}
|
||||
|
||||
if (state.alphaupdate)
|
||||
vk_state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
|
||||
|
||||
return vk_state;
|
||||
}
|
||||
|
||||
static VkPipelineColorBlendStateCreateInfo
|
||||
GetVulkanColorBlendState(const BlendingState& state,
|
||||
const VkPipelineColorBlendAttachmentState* attachments,
|
||||
uint32_t num_attachments)
|
||||
{
|
||||
static constexpr std::array<VkLogicOp, 16> vk_logic_ops = {
|
||||
{VK_LOGIC_OP_CLEAR, VK_LOGIC_OP_AND, VK_LOGIC_OP_AND_REVERSE, VK_LOGIC_OP_COPY,
|
||||
VK_LOGIC_OP_AND_INVERTED, VK_LOGIC_OP_NO_OP, VK_LOGIC_OP_XOR, VK_LOGIC_OP_OR,
|
||||
VK_LOGIC_OP_NOR, VK_LOGIC_OP_EQUIVALENT, VK_LOGIC_OP_INVERT, VK_LOGIC_OP_OR_REVERSE,
|
||||
VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}};
|
||||
|
||||
VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable);
|
||||
if (vk_logic_op_enable && !g_ActiveConfig.backend_info.bSupportsLogicOp)
|
||||
{
|
||||
// At the time of writing, Adreno and Mali drivers didn't support logic ops.
|
||||
// The "emulation" through blending path has been removed, so just disable it completely.
|
||||
// These drivers don't support dual-source blend either, so issues are to be expected.
|
||||
vk_logic_op_enable = VK_FALSE;
|
||||
}
|
||||
|
||||
VkLogicOp vk_logic_op = vk_logic_op_enable ? vk_logic_ops[state.logicmode] : VK_LOGIC_OP_CLEAR;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo vk_state = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineColorBlendStateCreateFlags flags
|
||||
vk_logic_op_enable, // VkBool32 logicOpEnable
|
||||
vk_logic_op, // VkLogicOp logicOp
|
||||
num_attachments, // uint32_t attachmentCount
|
||||
attachments, // const VkPipelineColorBlendAttachmentState* pAttachments
|
||||
{1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4]
|
||||
};
|
||||
|
||||
return vk_state;
|
||||
}
|
||||
|
||||
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),
|
||||
VKTexture::GetVkFormatForHostTextureFormat(config.framebuffer_state.color_texture_format),
|
||||
VKTexture::GetVkFormatForHostTextureFormat(config.framebuffer_state.depth_texture_format),
|
||||
config.framebuffer_state.samples, VK_ATTACHMENT_LOAD_OP_LOAD);
|
||||
|
||||
// Get pipeline layout.
|
||||
@ -50,26 +249,144 @@ std::unique_ptr<VKPipeline> VKPipeline::Create(const AbstractPipelineConfig& con
|
||||
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;
|
||||
// Declare descriptors for empty vertex buffers/attributes
|
||||
static const VkPipelineVertexInputStateCreateInfo empty_vertex_input_state = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkPipelineVertexInputStateCreateFlags flags
|
||||
0, // uint32_t vertexBindingDescriptionCount
|
||||
nullptr, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
|
||||
0, // uint32_t vertexAttributeDescriptionCount
|
||||
nullptr // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
|
||||
};
|
||||
|
||||
VkPipeline pipeline = g_shader_cache->CreatePipeline(pinfo);
|
||||
if (pipeline == VK_NULL_HANDLE)
|
||||
return nullptr;
|
||||
// Vertex inputs
|
||||
const VkPipelineVertexInputStateCreateInfo& vertex_input_state =
|
||||
config.vertex_format ?
|
||||
static_cast<const VertexFormat*>(config.vertex_format)->GetVertexInputStateInfo() :
|
||||
empty_vertex_input_state;
|
||||
|
||||
// Input assembly
|
||||
static constexpr std::array<VkPrimitiveTopology, 4> vk_primitive_topologies = {
|
||||
{VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}};
|
||||
VkPipelineInputAssemblyStateCreateInfo input_assembly_state = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
|
||||
vk_primitive_topologies[static_cast<u32>(config.rasterization_state.primitive.Value())],
|
||||
VK_FALSE};
|
||||
|
||||
// See Vulkan spec, section 19:
|
||||
// If topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
|
||||
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
|
||||
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
|
||||
// primitiveRestartEnable must be VK_FALSE
|
||||
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart &&
|
||||
IsStripPrimitiveTopology(input_assembly_state.topology))
|
||||
{
|
||||
input_assembly_state.primitiveRestartEnable = VK_TRUE;
|
||||
}
|
||||
|
||||
// Shaders to stages
|
||||
VkPipelineShaderStageCreateInfo shader_stages[3];
|
||||
uint32_t num_shader_stages = 0;
|
||||
if (config.vertex_shader)
|
||||
{
|
||||
shader_stages[num_shader_stages++] = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
nullptr,
|
||||
0,
|
||||
VK_SHADER_STAGE_VERTEX_BIT,
|
||||
static_cast<const VKShader*>(config.vertex_shader)->GetShaderModule(),
|
||||
"main"};
|
||||
}
|
||||
if (config.geometry_shader)
|
||||
{
|
||||
shader_stages[num_shader_stages++] = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
nullptr,
|
||||
0,
|
||||
VK_SHADER_STAGE_GEOMETRY_BIT,
|
||||
static_cast<const VKShader*>(config.geometry_shader)->GetShaderModule(),
|
||||
"main"};
|
||||
}
|
||||
if (config.pixel_shader)
|
||||
{
|
||||
shader_stages[num_shader_stages++] = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
nullptr,
|
||||
0,
|
||||
VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
static_cast<const VKShader*>(config.pixel_shader)->GetShaderModule(),
|
||||
"main"};
|
||||
}
|
||||
|
||||
// Fill in Vulkan descriptor structs from our state structures.
|
||||
VkPipelineRasterizationStateCreateInfo rasterization_state =
|
||||
GetVulkanRasterizationState(config.rasterization_state);
|
||||
VkPipelineMultisampleStateCreateInfo multisample_state =
|
||||
GetVulkanMultisampleState(config.framebuffer_state);
|
||||
VkPipelineDepthStencilStateCreateInfo depth_stencil_state =
|
||||
GetVulkanDepthStencilState(config.depth_state);
|
||||
VkPipelineColorBlendAttachmentState blend_attachment_state =
|
||||
GetVulkanAttachmentBlendState(config.blending_state);
|
||||
VkPipelineColorBlendStateCreateInfo blend_state =
|
||||
GetVulkanColorBlendState(config.blending_state, &blend_attachment_state, 1);
|
||||
|
||||
// This viewport isn't used, but needs to be specified anyway.
|
||||
static const VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
|
||||
static const VkRect2D scissor = {{0, 0}, {1, 1}};
|
||||
static const VkPipelineViewportStateCreateInfo viewport_state = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
nullptr,
|
||||
0, // VkPipelineViewportStateCreateFlags flags;
|
||||
1, // uint32_t viewportCount
|
||||
&viewport, // const VkViewport* pViewports
|
||||
1, // uint32_t scissorCount
|
||||
&scissor // const VkRect2D* pScissors
|
||||
};
|
||||
|
||||
// Set viewport and scissor dynamic state so we can change it elsewhere.
|
||||
static const VkDynamicState dynamic_states[] = {VK_DYNAMIC_STATE_VIEWPORT,
|
||||
VK_DYNAMIC_STATE_SCISSOR};
|
||||
static const VkPipelineDynamicStateCreateInfo dynamic_state = {
|
||||
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, nullptr,
|
||||
0, // VkPipelineDynamicStateCreateFlags flags
|
||||
static_cast<u32>(ArraySize(dynamic_states)), // uint32_t dynamicStateCount
|
||||
dynamic_states // const VkDynamicState* pDynamicStates
|
||||
};
|
||||
|
||||
// Combine to full pipeline info structure.
|
||||
VkGraphicsPipelineCreateInfo pipeline_info = {
|
||||
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
nullptr, // VkStructureType sType
|
||||
0, // VkPipelineCreateFlags flags
|
||||
num_shader_stages, // uint32_t stageCount
|
||||
shader_stages, // const VkPipelineShaderStageCreateInfo* pStages
|
||||
&vertex_input_state, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState
|
||||
&input_assembly_state, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState
|
||||
nullptr, // const VkPipelineTessellationStateCreateInfo* pTessellationState
|
||||
&viewport_state, // const VkPipelineViewportStateCreateInfo* pViewportState
|
||||
&rasterization_state, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState
|
||||
&multisample_state, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState
|
||||
&depth_stencil_state, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState
|
||||
&blend_state, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState
|
||||
&dynamic_state, // const VkPipelineDynamicStateCreateInfo* pDynamicState
|
||||
pipeline_layout, // VkPipelineLayout layout
|
||||
render_pass, // VkRenderPass renderPass
|
||||
0, // uint32_t subpass
|
||||
VK_NULL_HANDLE, // VkPipeline basePipelineHandle
|
||||
-1 // int32_t basePipelineIndex
|
||||
};
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkResult res =
|
||||
vkCreateGraphicsPipelines(g_vulkan_context->GetDevice(), g_object_cache->GetPipelineCache(),
|
||||
1, &pipeline_info, nullptr, &pipeline);
|
||||
if (res != VK_SUCCESS)
|
||||
{
|
||||
LOG_VULKAN_ERROR(res, "vkCreateGraphicsPipelines failed: ");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
return std::make_unique<VKPipeline>(pipeline, pipeline_layout, config.usage);
|
||||
}
|
||||
|
Reference in New Issue
Block a user