2#include <QGuiApplication>
5#include "libmythbase/mythconfig.h"
15#define LOC QString("VulkanRender: ")
30 : m_vulkanRender(Render)
47 : m_vulkanRender(Other ? Other->Render() : nullptr),
48 m_vulkanDevice(Other ? Other->
Device() : nullptr),
49 m_vulkanFuncs(Other ? Other->Funcs() : nullptr),
50 m_vulkanWindow(Other ? Other->Window() : nullptr)
60 LOG(VB_GENERAL, LOG_ERR,
"VulkanBase: Invalid Myth vulkan object");
108 if (!MythShaderVulkan::InitGLSLang())
109 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to initialise GLSLang");
111 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Created");
117 MythShaderVulkan::InitGLSLang(
true);
119 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Destroyed");
134 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
139 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
144 static bool s_debugged =
false;
152 m_window->vulkanInstance()->functions()
166 result.append(tr(
"QPA platform") +
"\t: " + QGuiApplication::platformName());
167 result.append(tr(
"Vulkan details:"));
168 result.append(tr(
"Driver name") +
"\t: " +
m_debugInfo[
"drivername"]);
169 result.append(tr(
"Driver info") +
"\t: " +
m_debugInfo[
"driverinfo"]);
170 result.append(tr(
"Device name") +
"\t: " +
m_debugInfo[
"devicename"]);
171 result.append(tr(
"Device type") +
"\t: " +
m_debugInfo[
"devicetype"]);
172 result.append(tr(
"API version") +
"\t: " +
m_debugInfo[
"apiversion"]);
178 auto deviceType = [](VkPhysicalDeviceType
Type)
182 case VK_PHYSICAL_DEVICE_TYPE_CPU:
return "Software";
183 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
return "Integrated GPU";
184 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
return "Discrete GPU";
185 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
return "Virtual GPU";
191 auto version = [](uint32_t Version)
193 return QString(
"%1.%2.%3").arg(VK_VERSION_MAJOR(Version))
194 .arg(VK_VERSION_MINOR(Version))
195 .arg(VK_VERSION_PATCH(Version));
198 const auto * props =
m_window->physicalDeviceProperties();
201 const auto & limits = props->limits;
202 auto devextensions =
m_window->supportedDeviceExtensions();
203 auto instextensions =
m_window->vulkanInstance()->supportedExtensions();
205 if (instextensions.contains(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
207 auto raw =
m_window->vulkanInstance()->getInstanceProcAddr(
"vkGetPhysicalDeviceProperties2");
208 auto proc =
reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2
>(raw);
211 VkPhysicalDeviceDriverPropertiesKHR driverprops {
212 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
214 .driverID =
static_cast<VkDriverId
>(0),
217 .conformanceVersion = {},
220 VkPhysicalDeviceProperties2 devprops { };
221 devprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
222 devprops.pNext = &driverprops;
224 proc(
m_window->physicalDevice(), &devprops);
225 m_debugInfo.insert(
"drivername", driverprops.driverName);
226 m_debugInfo.insert(
"driverinfo", driverprops.driverInfo);
227 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver name : %1").arg(driverprops.driverName));
228 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver info : %1").arg(driverprops.driverInfo));
232 m_debugInfo.insert(
"devicename", props->deviceName);
233 m_debugInfo.insert(
"devicetype", deviceType(props->deviceType));
236 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt platform : %1").arg(QGuiApplication::platformName()));
237 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device name : %1").arg(props->deviceName));
238 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device type : %1").arg(deviceType(props->deviceType)));
239 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"API version : %1").arg(
version(props->apiVersion)));
240 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device ID : 0x%1").arg(props->deviceID, 0, 16));
241 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver version : %1").arg(
version(props->driverVersion)));
242 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max image size : %1x%1").arg(limits.maxImageDimension2D));
243 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max framebuffer : %1x%2")
244 .arg(limits.maxFramebufferWidth).arg(limits.maxFramebufferHeight));
245 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max allocations : %1").arg(limits.maxMemoryAllocationCount));
246 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max samplers : %1").arg(limits.maxSamplerAllocationCount));
247 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Min alignment : %1").arg(limits.minMemoryMapAlignment));
251 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 device extensions supported:").arg(devextensions.size()));
252 for (
const auto& extension : std::as_const(devextensions))
253 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
255 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 instance extensions supported:").arg(instextensions.size()));
256 for (
const auto& extension : std::as_const(instextensions))
257 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
259 auto layers =
m_window->vulkanInstance()->supportedLayers();
260 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 layer types supported:").arg(layers.size()));
261 for (
const auto& layer : std::as_const(layers))
262 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 Version: %2").arg(layer.name.constData()).arg(layer.version));
268 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
273 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
280 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
294 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
300 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
307 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Starting frame rendering before last is finished");
326 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Spontaneous frame");
340 VkClearColorValue clearColor = {{ 0.0F, 0.0F, 0.0F, 1.0F }};
341 VkClearDepthStencilValue clearDS = { 1.0F, 0 };
342 std::array<VkClearValue,2> clearValues {};
343 clearValues[0].color = clearColor;
344 clearValues[1].depthStencil = clearDS;
347 VkCommandBuffer commandbuffer =
m_window->currentCommandBuffer();
348 QSize size =
m_window->swapChainImageSize();
349 VkRenderPassBeginInfo rpBeginInfo;
350 memset(&rpBeginInfo, 0,
sizeof(rpBeginInfo));
351 rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
352 rpBeginInfo.renderPass =
m_window->defaultRenderPass();
353 rpBeginInfo.framebuffer =
m_window->currentFramebuffer();
354 rpBeginInfo.clearValueCount = 2;
355 rpBeginInfo.pClearValues = clearValues.data();
356 rpBeginInfo.renderArea.extent.width =
static_cast<uint32_t
>(size.width());
357 rpBeginInfo.renderArea.extent.height =
static_cast<uint32_t
>(size.height());
358 m_devFuncs->vkCmdBeginRenderPass(commandbuffer, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
372 VkImageLayout OldLayout,
373 VkImageLayout NewLayout,
374 VkCommandBuffer CommandBuffer)
379 VkImageMemoryBarrier barrier{};
380 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
381 barrier.oldLayout = OldLayout;
382 barrier.newLayout = NewLayout;
383 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
384 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
385 barrier.image = Image;
386 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
387 barrier.subresourceRange.baseMipLevel = 0;
388 barrier.subresourceRange.levelCount = 1;
389 barrier.subresourceRange.baseArrayLayer = 0;
390 barrier.subresourceRange.layerCount = 1;
392 VkPipelineStageFlags sourceStage = 0;
393 VkPipelineStageFlags destinationStage = 0;
394 if (OldLayout == VK_IMAGE_LAYOUT_UNDEFINED && NewLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
396 barrier.srcAccessMask = 0;
397 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
398 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
399 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
401 else if (OldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && NewLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
403 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
404 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
405 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
406 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
410 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unsupported layout transition");
413 m_devFuncs->vkCmdPipelineBarrier(commandbuffer, sourceStage, destinationStage,
414 0, 0,
nullptr, 0,
nullptr, 1, &barrier);
420 uint32_t Width, uint32_t Height,
421 VkCommandBuffer CommandBuffer)
424 VkBufferImageCopy region { };
425 region.bufferOffset = 0;
426 region.bufferRowLength = 0;
427 region.bufferImageHeight = 0;
428 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
429 region.imageSubresource.mipLevel = 0;
430 region.imageSubresource.baseArrayLayer = 0;
431 region.imageSubresource.layerCount = 1;
432 region.imageOffset = { .x=0, .y=0, .z=0 };
433 region.imageExtent = { .width=Width, .height=Height, .depth=1 };
434 m_devFuncs->vkCmdCopyBufferToImage(commandbuffer,
Buffer, Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
441 VkBufferCopy region { };
446 m_devFuncs->vkCmdCopyBuffer(CommandBuffer, Src, Dst, 1, ®ion);
451 m_devFuncs->vkCmdCopyBuffer(cmdbuf, Src, Dst, 1, ®ion);
457 VkBufferUsageFlags Usage,
460 VkDeviceMemory &Memory)
462 VkBufferCreateInfo bufferInfo { };
463 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
464 bufferInfo.size = Size;
465 bufferInfo.usage = Usage;
466 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
470 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create buffer");
474 VkMemoryRequirements requirements;
477 VkMemoryAllocateInfo allocInfo { };
478 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
479 allocInfo.allocationSize = requirements.size;
482 allocInfo.memoryTypeIndex =
type.value();
483 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocInfo,
nullptr, &Memory) == VK_SUCCESS)
488 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate buffer memory");
492 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce buffer memory type");
502 VkSamplerCreateInfo samplerinfo { };
503 memset(&samplerinfo, 0,
sizeof(samplerinfo));
504 samplerinfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
505 samplerinfo.minFilter = Min;
506 samplerinfo.magFilter = Mag;
507 samplerinfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
508 samplerinfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
509 samplerinfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
510 samplerinfo.anisotropyEnable = VK_FALSE;
511 samplerinfo.maxAnisotropy = 1;
512 samplerinfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
513 samplerinfo.unnormalizedCoordinates = VK_FALSE;
514 samplerinfo.compareEnable = VK_FALSE;
515 samplerinfo.compareOp = VK_COMPARE_OP_ALWAYS;
516 samplerinfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
517 if (
m_devFuncs->vkCreateSampler(
m_device, &samplerinfo,
nullptr, &result) != VK_SUCCESS)
518 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create image sampler");
547 VkImageTiling Tiling,
548 VkImageUsageFlags Usage,
551 VkDeviceMemory &ImageMemory)
553 VkImageCreateInfo imageinfo {
554 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
556 .flags =
static_cast<VkImageCreateFlags
>(0),
557 .imageType = VK_IMAGE_TYPE_2D,
560 .width =
static_cast<uint32_t
>(Size.width()),
561 .height =
static_cast<uint32_t
>(Size.height()),
566 .samples = VK_SAMPLE_COUNT_1_BIT,
569 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
570 .queueFamilyIndexCount = 0,
571 .pQueueFamilyIndices =
nullptr,
572 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
577 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Vulkan image");
581 VkMemoryRequirements requirements;
584 VkMemoryAllocateInfo allocinfo { };
585 allocinfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
586 allocinfo.allocationSize = requirements.size;
589 allocinfo.memoryTypeIndex =
type.value();
590 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocinfo,
nullptr, &ImageMemory) == VK_SUCCESS)
595 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate image memory");
599 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce image memory type");
608 std::optional<uint32_t> result;
609 VkPhysicalDeviceMemoryProperties memoryprops;
610 m_funcs->vkGetPhysicalDeviceMemoryProperties(
m_window->physicalDevice(), &memoryprops);
612 for (uint32_t i = 0; i < memoryprops.memoryTypeCount; i++)
614 if ((Filter & (1 << i)) && (memoryprops.memoryTypes[i].propertyFlags &
Properties) ==
Properties)
626 VkCommandBufferAllocateInfo allocinfo { };
627 allocinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
628 allocinfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
629 allocinfo.commandPool =
m_window->graphicsCommandPool();
630 allocinfo.commandBufferCount = 1;
631 VkCommandBuffer commandbuffer =
nullptr;
633 VkCommandBufferBeginInfo begininfo { };
634 begininfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
635 begininfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
636 m_devFuncs->vkBeginCommandBuffer(commandbuffer, &begininfo);
637 return commandbuffer;
643 VkSubmitInfo submitinfo{};
644 submitinfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
645 submitinfo.commandBufferCount = 1;
646 submitinfo.pCommandBuffers = &
Buffer;
653 const QRect Viewport,
654 std::vector<VkDynamicState> Dynamic)
656 if (!(Shader && Viewport.isValid()))
660 const auto & shaderstages = Shader->
Stages();
663 VkPipelineInputAssemblyStateCreateInfo inputassembly { };
664 inputassembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
666 inputassembly.primitiveRestartEnable = VK_FALSE;
669 VkViewport viewport { };
670 viewport.x =
static_cast<float>(Viewport.left());
671 viewport.y =
static_cast<float>(Viewport.left());
672 viewport.width =
static_cast<float>(Viewport.width());
673 viewport.height =
static_cast<float>(Viewport.height());
674 viewport.minDepth = 0.0F;
675 viewport.maxDepth = 1.0F;
677 VkRect2D scissor { };
678 scissor.offset = { .x=Viewport.left(), .y=Viewport.top() };
679 scissor.extent = { .width=
static_cast<uint32_t
>(Viewport.width()),
680 .height=
static_cast<uint32_t
>(Viewport.height()) };
682 VkPipelineViewportStateCreateInfo viewportstate { };
683 viewportstate.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
684 viewportstate.viewportCount = 1;
685 viewportstate.pViewports = &viewport;
686 viewportstate.scissorCount = 1;
687 viewportstate.pScissors = &scissor;
690 VkPipelineVertexInputStateCreateInfo vertexinput { };
692 if (vertexattribs.empty())
694 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
695 vertexinput.vertexBindingDescriptionCount = 0;
696 vertexinput.pVertexBindingDescriptions =
nullptr;
697 vertexinput.vertexAttributeDescriptionCount = 0;
698 vertexinput.pVertexAttributeDescriptions =
nullptr;
702 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
703 vertexinput.vertexBindingDescriptionCount = 1;
705 vertexinput.vertexAttributeDescriptionCount =
static_cast<uint32_t
>(vertexattribs.size());
706 vertexinput.pVertexAttributeDescriptions = vertexattribs.data();
710 VkPipelineMultisampleStateCreateInfo multisampling {
711 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
714 .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
715 .sampleShadingEnable = VK_FALSE,
716 .minSampleShading = 0.0F,
717 .pSampleMask =
nullptr,
718 .alphaToCoverageEnable = VK_FALSE,
719 .alphaToOneEnable = VK_FALSE,
723 VkPipelineColorBlendAttachmentState colorblendattachment { };
724 colorblendattachment.blendEnable = VK_TRUE;
725 colorblendattachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
726 colorblendattachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
727 colorblendattachment.colorBlendOp = VK_BLEND_OP_ADD;
728 colorblendattachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
729 colorblendattachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
730 colorblendattachment.alphaBlendOp = VK_BLEND_OP_ADD;
731 colorblendattachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
732 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
734 VkPipelineColorBlendStateCreateInfo colorBlending{};
735 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
736 colorBlending.logicOpEnable = VK_FALSE;
737 colorBlending.logicOp = VK_LOGIC_OP_COPY;
738 colorBlending.attachmentCount = 1;
739 colorBlending.pAttachments = &colorblendattachment;
740 colorBlending.blendConstants[0] = 0.0F;
741 colorBlending.blendConstants[1] = 0.0F;
742 colorBlending.blendConstants[2] = 0.0F;
743 colorBlending.blendConstants[3] = 0.0F;
746 VkPipelineRasterizationStateCreateInfo rasterizer { };
747 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
748 rasterizer.depthClampEnable = VK_FALSE;
749 rasterizer.rasterizerDiscardEnable = VK_FALSE;
750 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
751 rasterizer.lineWidth = 1.0F;
752 rasterizer.cullMode = VK_CULL_MODE_NONE;
753 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
754 rasterizer.depthBiasEnable = VK_FALSE;
757 VkPipelineDepthStencilStateCreateInfo depthstencil { };
758 depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
759 depthstencil.pNext =
nullptr;
760 depthstencil.flags = 0;
761 depthstencil.depthTestEnable = VK_FALSE;
762 depthstencil.depthWriteEnable = VK_FALSE;
763 depthstencil.depthCompareOp = VK_COMPARE_OP_NEVER;
764 depthstencil.depthBoundsTestEnable = VK_FALSE;
765 depthstencil.stencilTestEnable = VK_FALSE;
766 depthstencil.front = { };
767 depthstencil.back = { };
768 depthstencil.minDepthBounds = 0.0F;
769 depthstencil.maxDepthBounds = 1.0F;
772 VkPipelineDynamicStateCreateInfo dynamic { };
773 dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
774 dynamic.dynamicStateCount = Dynamic.empty() ? 0 :
static_cast<uint32_t
>(Dynamic.size());
775 dynamic.pDynamicStates = Dynamic.empty() ? nullptr : Dynamic.data();
778 VkGraphicsPipelineCreateInfo pipelinecreate { };
779 pipelinecreate.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
780 pipelinecreate.pNext =
nullptr;
781 pipelinecreate.flags = 0;
782 pipelinecreate.stageCount =
static_cast<uint32_t
>(shaderstages.size());
783 pipelinecreate.pStages = shaderstages.data();
784 pipelinecreate.pVertexInputState = &vertexinput;
785 pipelinecreate.pInputAssemblyState = &inputassembly;
786 pipelinecreate.pTessellationState =
nullptr;
787 pipelinecreate.pViewportState = &viewportstate;
788 pipelinecreate.pRasterizationState = &rasterizer;
789 pipelinecreate.pMultisampleState = &multisampling;
790 pipelinecreate.pDepthStencilState = &depthstencil;
791 pipelinecreate.pColorBlendState = &colorBlending;
792 pipelinecreate.pDynamicState = &dynamic;
794 pipelinecreate.renderPass =
m_window->defaultRenderPass();
795 pipelinecreate.subpass = 0;
797 pipelinecreate.basePipelineIndex = 0;
803 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create graphics pipeline");
A device containing images (ie. USB stick, CD, storage group etc)
static MythDebugVulkan * Create(MythVulkanObject *Vulkan)
void EndRegion(VkCommandBuffer CmdBuffer)
void BeginRegion(VkCommandBuffer CmdBuffer, const char *Name, MythVulkan4F Color)
MythRender * GetRenderDevice()
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
QVulkanFunctions * m_funcs
MythWindowVulkan * GetVulkanWindow(void)
bool GetFrameExpected(void) const
QVulkanDeviceFunctions * m_devFuncs
bool CreateImage(QSize Size, VkFormat Format, VkImageTiling Tiling, VkImageUsageFlags Usage, VkMemoryPropertyFlags Properties, VkImage &Image, VkDeviceMemory &ImageMemory)
void physicalDeviceLost(void) override
VkSampler CreateSampler(VkFilter Min, VkFilter Mag)
~MythRenderVulkan() override
void logicalDeviceLost(void) override
void PhysicalDeviceLost(void)
bool CreateBuffer(VkDeviceSize Size, VkBufferUsageFlags Usage, VkMemoryPropertyFlags Properties, VkBuffer &Buffer, VkDeviceMemory &Memory)
static MythRenderVulkan * GetVulkanRender(void)
void FinishSingleUseCommandBuffer(VkCommandBuffer &Buffer)
VkPhysicalDeviceFeatures GetPhysicalDeviceFeatures() const
void TransitionImageLayout(VkImage &Image, VkImageLayout OldLayout, VkImageLayout NewLayout, VkCommandBuffer CommandBuffer=nullptr)
void preInitResources(void) override
VkPhysicalDeviceFeatures m_phyDevFeatures
void releaseSwapChainResources(void) override
void EndDebugRegion(VkCommandBuffer CommandBuffer)
bool GetFrameStarted(void) const
void LogicalDeviceLost(void)
QMap< QString, QString > m_debugInfo
VkPipeline CreatePipeline(MythShaderVulkan *Shader, QRect Viewport, std::vector< VkDynamicState > Dynamic={ })
void CopyBuffer(VkBuffer Src, VkBuffer Dst, VkDeviceSize Size, VkCommandBuffer CommandBuffer=nullptr)
void initSwapChainResources(void) override
QStringList GetDescription(void) override
void SetVulkanWindow(MythWindowVulkan *VulkanWindow)
VkPhysicalDeviceLimits m_phyDevLimits
VkCommandBuffer CreateSingleUseCommandBuffer(void)
MythWindowVulkan * m_window
void CopyBufferToImage(VkBuffer Buffer, VkImage Image, uint32_t Width, uint32_t Height, VkCommandBuffer CommandBuffer=nullptr)
void startNextFrame(void) override
void SetFrameExpected(void)
void DoFreeResources(void)
VkPhysicalDeviceLimits GetPhysicalDeviceLimits() const
void releaseResources(void) override
std::optional< uint32_t > FindMemoryType(uint32_t Filter, VkMemoryPropertyFlags Properties)
MythDebugVulkan * m_debugMarker
void initResources(void) override
void BeginDebugRegion(VkCommandBuffer CommandBuffer, const char *Name, MythVulkan4F Color)
RenderType Type(void) const
Creates shader objects suitable for use with the Vulkan API.
VkPrimitiveTopology GetTopology() const
const std::vector< VkPipelineShaderStageCreateInfo > & Stages(void) const
const VkVertexInputBindingDescription & GetVertexBindingDesc(void) const
const MythVertexAttrs & GetVertexAttributes(void) const
VkPipelineLayout GetPipelineLayout(void) const
MythRenderVulkan * Render()
QVulkanDeviceFunctions * m_vulkanFuncs
MythRenderVulkan * m_vulkanRender
MythWindowVulkan * m_vulkanWindow
bool IsValidVulkan() const
MythWindowVulkan * Window()
QVulkanDeviceFunctions * Funcs()
static MythVulkanObject * Create(MythRenderVulkan *Render)
MythVulkanObject(MythRenderVulkan *Render)
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool HasMythMainWindow(void)
std::array< float, 4 > MythVulkan4F
#define MYTH_NULL_DISPATCH
QMultiMap< QString, Property * > Properties