2 #include <QGuiApplication>
14 #define LOC QString("VulkanRender: ")
29 : m_vulkanRender(Render)
46 : m_vulkanRender(Other ? Other->Render() : nullptr),
47 m_vulkanDevice(Other ? Other->
Device() : nullptr),
48 m_vulkanFuncs(Other ? Other->Funcs() : nullptr),
49 m_vulkanWindow(Other ? Other->Window() : nullptr)
59 LOG(VB_GENERAL, LOG_ERR,
"VulkanBase: Invalid Myth vulkan object");
107 if (!MythShaderVulkan::InitGLSLang())
108 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise GLSLang");
110 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created");
116 MythShaderVulkan::InitGLSLang(
true);
118 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Destroyed");
133 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
138 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
143 static bool s_debugged =
false;
151 m_window->vulkanInstance()->functions()
165 result.append(tr(
"QPA platform") +
"\t: " + QGuiApplication::platformName());
166 result.append(tr(
"Vulkan details:"));
167 result.append(tr(
"Driver name") +
"\t: " +
m_debugInfo[
"drivername"]);
168 result.append(tr(
"Driver info") +
"\t: " +
m_debugInfo[
"driverinfo"]);
169 result.append(tr(
"Device name") +
"\t: " +
m_debugInfo[
"devicename"]);
170 result.append(tr(
"Device type") +
"\t: " +
m_debugInfo[
"devicetype"]);
171 result.append(tr(
"API version") +
"\t: " +
m_debugInfo[
"apiversion"]);
177 auto deviceType = [](VkPhysicalDeviceType
Type)
181 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "Software";
182 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "Integrated GPU";
183 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "Discrete GPU";
184 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "Virtual GPU";
190 auto version = [](uint32_t Version)
192 return QString(
"%1.%2.%3").arg(VK_VERSION_MAJOR(Version))
193 .arg(VK_VERSION_MINOR(Version))
194 .arg(VK_VERSION_PATCH(Version));
197 const auto * props =
m_window->physicalDeviceProperties();
200 const auto & limits = props->limits;
201 auto devextensions =
m_window->supportedDeviceExtensions();
202 auto instextensions =
m_window->vulkanInstance()->supportedExtensions();
204 if (instextensions.contains(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
206 auto raw =
m_window->vulkanInstance()->getInstanceProcAddr(
"vkGetPhysicalDeviceProperties2");
207 auto proc =
reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2
>(raw);
210 VkPhysicalDeviceDriverPropertiesKHR driverprops { };
211 driverprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
212 driverprops.pNext =
nullptr;
214 VkPhysicalDeviceProperties2 devprops { };
215 devprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
216 devprops.pNext = &driverprops;
218 proc(
m_window->physicalDevice(), &devprops);
219 m_debugInfo.insert(
"drivername", driverprops.driverName);
220 m_debugInfo.insert(
"driverinfo", driverprops.driverInfo);
221 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver name : %1").arg(driverprops.driverName));
222 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver info : %1").arg(driverprops.driverInfo));
226 m_debugInfo.insert(
"devicename", props->deviceName);
227 m_debugInfo.insert(
"devicetype", deviceType(props->deviceType));
230 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt platform : %1").arg(QGuiApplication::platformName()));
231 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device name : %1").arg(props->deviceName));
232 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device type : %1").arg(deviceType(props->deviceType)));
233 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"API version : %1").arg(
version(props->apiVersion)));
234 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device ID : 0x%1").arg(props->deviceID, 0, 16));
235 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver version : %1").arg(
version(props->driverVersion)));
236 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max image size : %1x%1").arg(limits.maxImageDimension2D));
237 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max framebuffer : %1x%2")
238 .arg(limits.maxFramebufferWidth).arg(limits.maxFramebufferHeight));
239 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max allocations : %1").arg(limits.maxMemoryAllocationCount));
240 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max samplers : %1").arg(limits.maxSamplerAllocationCount));
241 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Min alignment : %1").arg(limits.minMemoryMapAlignment));
245 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 device extensions supported:").arg(devextensions.size()));
246 for (
const auto& extension : std::as_const(devextensions))
247 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
249 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 instance extensions supported:").arg(instextensions.size()));
250 for (
const auto& extension : std::as_const(instextensions))
251 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
253 auto layers =
m_window->vulkanInstance()->supportedLayers();
254 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 layer types supported:").arg(layers.size()));
255 for (
const auto& layer : std::as_const(layers))
256 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 Version: %2").arg(layer.name.constData()).arg(layer.version));
262 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
267 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
274 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
288 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
294 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
301 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Starting frame rendering before last is finished");
320 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Spontaneous frame");
334 VkClearColorValue clearColor = {{ 0.0F, 0.0F, 0.0F, 1.0F }};
335 VkClearDepthStencilValue clearDS = { 1.0F, 0 };
336 std::array<VkClearValue,2> clearValues {};
337 clearValues[0].color = clearColor;
338 clearValues[1].depthStencil = clearDS;
341 VkCommandBuffer commandbuffer =
m_window->currentCommandBuffer();
342 QSize size =
m_window->swapChainImageSize();
343 VkRenderPassBeginInfo rpBeginInfo;
344 memset(&rpBeginInfo, 0,
sizeof(rpBeginInfo));
345 rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
346 rpBeginInfo.renderPass =
m_window->defaultRenderPass();
347 rpBeginInfo.framebuffer =
m_window->currentFramebuffer();
348 rpBeginInfo.clearValueCount = 2;
349 rpBeginInfo.pClearValues = clearValues.data();
350 rpBeginInfo.renderArea.extent.width =
static_cast<uint32_t
>(size.width());
351 rpBeginInfo.renderArea.extent.height =
static_cast<uint32_t
>(size.height());
352 m_devFuncs->vkCmdBeginRenderPass(commandbuffer, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
366 VkImageLayout OldLayout,
367 VkImageLayout NewLayout,
368 VkCommandBuffer CommandBuffer)
373 VkImageMemoryBarrier barrier{};
374 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
375 barrier.oldLayout = OldLayout;
376 barrier.newLayout = NewLayout;
377 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
378 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
379 barrier.image = Image;
380 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
381 barrier.subresourceRange.baseMipLevel = 0;
382 barrier.subresourceRange.levelCount = 1;
383 barrier.subresourceRange.baseArrayLayer = 0;
384 barrier.subresourceRange.layerCount = 1;
386 VkPipelineStageFlags sourceStage = 0;
387 VkPipelineStageFlags destinationStage = 0;
388 if (OldLayout == VK_IMAGE_LAYOUT_UNDEFINED && NewLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
390 barrier.srcAccessMask = 0;
391 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
392 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
393 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
395 else if (OldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && NewLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
397 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
398 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
399 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
400 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
404 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unsupported layout transition");
407 m_devFuncs->vkCmdPipelineBarrier(commandbuffer, sourceStage, destinationStage,
408 0, 0,
nullptr, 0,
nullptr, 1, &barrier);
414 uint32_t Width, uint32_t Height,
415 VkCommandBuffer CommandBuffer)
418 VkBufferImageCopy region { };
419 region.bufferOffset = 0;
420 region.bufferRowLength = 0;
421 region.bufferImageHeight = 0;
422 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
423 region.imageSubresource.mipLevel = 0;
424 region.imageSubresource.baseArrayLayer = 0;
425 region.imageSubresource.layerCount = 1;
426 region.imageOffset = { 0, 0, 0 };
427 region.imageExtent = { Width, Height, 1 };
428 m_devFuncs->vkCmdCopyBufferToImage(commandbuffer,
Buffer, Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
435 VkBufferCopy region { };
440 m_devFuncs->vkCmdCopyBuffer(CommandBuffer, Src, Dst, 1, ®ion);
445 m_devFuncs->vkCmdCopyBuffer(cmdbuf, Src, Dst, 1, ®ion);
451 VkBufferUsageFlags Usage,
454 VkDeviceMemory &Memory)
456 VkBufferCreateInfo bufferInfo { };
457 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
458 bufferInfo.size = Size;
459 bufferInfo.usage = Usage;
460 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
464 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create buffer");
468 VkMemoryRequirements requirements;
471 VkMemoryAllocateInfo allocInfo { };
472 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
473 allocInfo.allocationSize = requirements.size;
476 allocInfo.memoryTypeIndex =
type.value();
477 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocInfo,
nullptr, &Memory) == VK_SUCCESS)
482 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate buffer memory");
486 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce buffer memory type");
496 VkSamplerCreateInfo samplerinfo { };
497 memset(&samplerinfo, 0,
sizeof(samplerinfo));
498 samplerinfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
499 samplerinfo.minFilter = Min;
500 samplerinfo.magFilter = Mag;
501 samplerinfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
502 samplerinfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
503 samplerinfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
504 samplerinfo.anisotropyEnable = VK_FALSE;
505 samplerinfo.maxAnisotropy = 1;
506 samplerinfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
507 samplerinfo.unnormalizedCoordinates = VK_FALSE;
508 samplerinfo.compareEnable = VK_FALSE;
509 samplerinfo.compareOp = VK_COMPARE_OP_ALWAYS;
510 samplerinfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
511 if (
m_devFuncs->vkCreateSampler(
m_device, &samplerinfo,
nullptr, &result) != VK_SUCCESS)
512 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create image sampler");
541 VkImageTiling Tiling,
542 VkImageUsageFlags Usage,
545 VkDeviceMemory &ImageMemory)
547 VkImageCreateInfo imageinfo { };
548 imageinfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
549 imageinfo.imageType = VK_IMAGE_TYPE_2D;
550 imageinfo.extent.width =
static_cast<uint32_t
>(Size.width());
551 imageinfo.extent.height =
static_cast<uint32_t
>(Size.height());
552 imageinfo.extent.depth = 1;
553 imageinfo.mipLevels = 1;
554 imageinfo.arrayLayers = 1;
555 imageinfo.format =
Format;
556 imageinfo.tiling = Tiling;
557 imageinfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
558 imageinfo.usage = Usage;
559 imageinfo.samples = VK_SAMPLE_COUNT_1_BIT;
560 imageinfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
564 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Vulkan image");
568 VkMemoryRequirements requirements;
571 VkMemoryAllocateInfo allocinfo { };
572 allocinfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
573 allocinfo.allocationSize = requirements.size;
576 allocinfo.memoryTypeIndex =
type.value();
577 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocinfo,
nullptr, &ImageMemory) == VK_SUCCESS)
582 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate image memory");
586 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce image memory type");
595 std::optional<uint32_t> result;
596 VkPhysicalDeviceMemoryProperties memoryprops;
597 m_funcs->vkGetPhysicalDeviceMemoryProperties(
m_window->physicalDevice(), &memoryprops);
599 for (uint32_t i = 0; i < memoryprops.memoryTypeCount; i++)
601 if ((Filter & (1 << i)) && (memoryprops.memoryTypes[i].propertyFlags &
Properties) ==
Properties)
613 VkCommandBufferAllocateInfo allocinfo { };
614 allocinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
615 allocinfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
616 allocinfo.commandPool =
m_window->graphicsCommandPool();
617 allocinfo.commandBufferCount = 1;
618 VkCommandBuffer commandbuffer =
nullptr;
620 VkCommandBufferBeginInfo begininfo { };
621 begininfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
622 begininfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
623 m_devFuncs->vkBeginCommandBuffer(commandbuffer, &begininfo);
624 return commandbuffer;
630 VkSubmitInfo submitinfo{};
631 submitinfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
632 submitinfo.commandBufferCount = 1;
633 submitinfo.pCommandBuffers = &
Buffer;
640 const QRect Viewport,
641 std::vector<VkDynamicState> Dynamic)
643 if (!(Shader && Viewport.isValid()))
647 const auto & shaderstages = Shader->
Stages();
650 VkPipelineInputAssemblyStateCreateInfo inputassembly { };
651 inputassembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
653 inputassembly.primitiveRestartEnable = VK_FALSE;
656 VkViewport viewport { };
657 viewport.x =
static_cast<float>(Viewport.left());
658 viewport.y =
static_cast<float>(Viewport.left());
659 viewport.width =
static_cast<float>(Viewport.width());
660 viewport.height =
static_cast<float>(Viewport.height());
661 viewport.minDepth = 0.0F;
662 viewport.maxDepth = 1.0F;
664 VkRect2D scissor { };
665 scissor.offset = { Viewport.left(), Viewport.top() };
666 scissor.extent = {
static_cast<uint32_t
>(Viewport.width()),
static_cast<uint32_t
>(Viewport.height()) };
668 VkPipelineViewportStateCreateInfo viewportstate { };
669 viewportstate.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
670 viewportstate.viewportCount = 1;
671 viewportstate.pViewports = &viewport;
672 viewportstate.scissorCount = 1;
673 viewportstate.pScissors = &scissor;
676 VkPipelineVertexInputStateCreateInfo vertexinput { };
678 if (vertexattribs.empty())
680 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
681 vertexinput.vertexBindingDescriptionCount = 0;
682 vertexinput.pVertexBindingDescriptions =
nullptr;
683 vertexinput.vertexAttributeDescriptionCount = 0;
684 vertexinput.pVertexAttributeDescriptions =
nullptr;
688 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
689 vertexinput.vertexBindingDescriptionCount = 1;
691 vertexinput.vertexAttributeDescriptionCount =
static_cast<uint32_t
>(vertexattribs.size());
692 vertexinput.pVertexAttributeDescriptions = vertexattribs.data();
696 VkPipelineMultisampleStateCreateInfo multisampling { };
697 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
698 multisampling.sampleShadingEnable = VK_FALSE;
699 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
702 VkPipelineColorBlendAttachmentState colorblendattachment { };
703 colorblendattachment.blendEnable = VK_TRUE;
704 colorblendattachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
705 colorblendattachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
706 colorblendattachment.colorBlendOp = VK_BLEND_OP_ADD;
707 colorblendattachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
708 colorblendattachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
709 colorblendattachment.alphaBlendOp = VK_BLEND_OP_ADD;
710 colorblendattachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
711 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
713 VkPipelineColorBlendStateCreateInfo colorBlending{};
714 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
715 colorBlending.logicOpEnable = VK_FALSE;
716 colorBlending.logicOp = VK_LOGIC_OP_COPY;
717 colorBlending.attachmentCount = 1;
718 colorBlending.pAttachments = &colorblendattachment;
719 colorBlending.blendConstants[0] = 0.0F;
720 colorBlending.blendConstants[1] = 0.0F;
721 colorBlending.blendConstants[2] = 0.0F;
722 colorBlending.blendConstants[3] = 0.0F;
725 VkPipelineRasterizationStateCreateInfo rasterizer { };
726 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
727 rasterizer.depthClampEnable = VK_FALSE;
728 rasterizer.rasterizerDiscardEnable = VK_FALSE;
729 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
730 rasterizer.lineWidth = 1.0F;
731 rasterizer.cullMode = VK_CULL_MODE_NONE;
732 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
733 rasterizer.depthBiasEnable = VK_FALSE;
736 VkPipelineDepthStencilStateCreateInfo depthstencil { };
737 depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
738 depthstencil.pNext =
nullptr;
739 depthstencil.flags = 0;
740 depthstencil.depthTestEnable = VK_FALSE;
741 depthstencil.depthWriteEnable = VK_FALSE;
742 depthstencil.depthCompareOp = VK_COMPARE_OP_NEVER;
743 depthstencil.depthBoundsTestEnable = VK_FALSE;
744 depthstencil.stencilTestEnable = VK_FALSE;
745 depthstencil.front = { };
746 depthstencil.back = { };
747 depthstencil.minDepthBounds = 0.0F;
748 depthstencil.maxDepthBounds = 1.0F;
751 VkPipelineDynamicStateCreateInfo dynamic { };
752 dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
753 dynamic.dynamicStateCount = Dynamic.empty() ? 0 :
static_cast<uint32_t
>(Dynamic.size());
754 dynamic.pDynamicStates = Dynamic.empty() ? nullptr : Dynamic.data();
757 VkGraphicsPipelineCreateInfo pipelinecreate { };
758 pipelinecreate.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
759 pipelinecreate.pNext =
nullptr;
760 pipelinecreate.flags = 0;
761 pipelinecreate.stageCount =
static_cast<uint32_t
>(shaderstages.size());
762 pipelinecreate.pStages = shaderstages.data();
763 pipelinecreate.pVertexInputState = &vertexinput;
764 pipelinecreate.pInputAssemblyState = &inputassembly;
765 pipelinecreate.pTessellationState =
nullptr;
766 pipelinecreate.pViewportState = &viewportstate;
767 pipelinecreate.pRasterizationState = &rasterizer;
768 pipelinecreate.pMultisampleState = &multisampling;
769 pipelinecreate.pDepthStencilState = &depthstencil;
770 pipelinecreate.pColorBlendState = &colorBlending;
771 pipelinecreate.pDynamicState = &dynamic;
773 pipelinecreate.renderPass =
m_window->defaultRenderPass();
774 pipelinecreate.subpass = 0;
776 pipelinecreate.basePipelineIndex = 0;
782 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create graphics pipeline");