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 driverprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
213 driverprops.pNext =
nullptr;
215 VkPhysicalDeviceProperties2 devprops { };
216 devprops.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
217 devprops.pNext = &driverprops;
219 proc(
m_window->physicalDevice(), &devprops);
220 m_debugInfo.insert(
"drivername", driverprops.driverName);
221 m_debugInfo.insert(
"driverinfo", driverprops.driverInfo);
222 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver name : %1").arg(driverprops.driverName));
223 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver info : %1").arg(driverprops.driverInfo));
227 m_debugInfo.insert(
"devicename", props->deviceName);
228 m_debugInfo.insert(
"devicetype", deviceType(props->deviceType));
231 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt platform : %1").arg(QGuiApplication::platformName()));
232 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device name : %1").arg(props->deviceName));
233 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device type : %1").arg(deviceType(props->deviceType)));
234 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"API version : %1").arg(
version(props->apiVersion)));
235 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Device ID : 0x%1").arg(props->deviceID, 0, 16));
236 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Driver version : %1").arg(
version(props->driverVersion)));
237 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max image size : %1x%1").arg(limits.maxImageDimension2D));
238 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max framebuffer : %1x%2")
239 .arg(limits.maxFramebufferWidth).arg(limits.maxFramebufferHeight));
240 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max allocations : %1").arg(limits.maxMemoryAllocationCount));
241 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Max samplers : %1").arg(limits.maxSamplerAllocationCount));
242 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Min alignment : %1").arg(limits.minMemoryMapAlignment));
246 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 device extensions supported:").arg(devextensions.size()));
247 for (
const auto& extension : std::as_const(devextensions))
248 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
250 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 instance extensions supported:").arg(instextensions.size()));
251 for (
const auto& extension : std::as_const(instextensions))
252 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 Version: %2").arg(extension.name.constData()).arg(extension.version));
254 auto layers =
m_window->vulkanInstance()->supportedLayers();
255 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 layer types supported:").arg(layers.size()));
256 for (
const auto& layer : std::as_const(layers))
257 LOG(VB_GENERAL, LOG_INFO, QString(
"%1 Version: %2").arg(layer.name.constData()).arg(layer.version));
263 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
268 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
275 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
289 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
295 LOG(VB_GENERAL, LOG_INFO,
LOC + __FUNCTION__);
302 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Starting frame rendering before last is finished");
321 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Spontaneous frame");
335 VkClearColorValue clearColor = {{ 0.0F, 0.0F, 0.0F, 1.0F }};
336 VkClearDepthStencilValue clearDS = { 1.0F, 0 };
337 std::array<VkClearValue,2> clearValues {};
338 clearValues[0].color = clearColor;
339 clearValues[1].depthStencil = clearDS;
342 VkCommandBuffer commandbuffer =
m_window->currentCommandBuffer();
343 QSize size =
m_window->swapChainImageSize();
344 VkRenderPassBeginInfo rpBeginInfo;
345 memset(&rpBeginInfo, 0,
sizeof(rpBeginInfo));
346 rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
347 rpBeginInfo.renderPass =
m_window->defaultRenderPass();
348 rpBeginInfo.framebuffer =
m_window->currentFramebuffer();
349 rpBeginInfo.clearValueCount = 2;
350 rpBeginInfo.pClearValues = clearValues.data();
351 rpBeginInfo.renderArea.extent.width =
static_cast<uint32_t
>(size.width());
352 rpBeginInfo.renderArea.extent.height =
static_cast<uint32_t
>(size.height());
353 m_devFuncs->vkCmdBeginRenderPass(commandbuffer, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
367 VkImageLayout OldLayout,
368 VkImageLayout NewLayout,
369 VkCommandBuffer CommandBuffer)
374 VkImageMemoryBarrier barrier{};
375 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
376 barrier.oldLayout = OldLayout;
377 barrier.newLayout = NewLayout;
378 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
379 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
380 barrier.image = Image;
381 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
382 barrier.subresourceRange.baseMipLevel = 0;
383 barrier.subresourceRange.levelCount = 1;
384 barrier.subresourceRange.baseArrayLayer = 0;
385 barrier.subresourceRange.layerCount = 1;
387 VkPipelineStageFlags sourceStage = 0;
388 VkPipelineStageFlags destinationStage = 0;
389 if (OldLayout == VK_IMAGE_LAYOUT_UNDEFINED && NewLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
391 barrier.srcAccessMask = 0;
392 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
393 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
394 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
396 else if (OldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && NewLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
398 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
399 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
400 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
401 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
405 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Unsupported layout transition");
408 m_devFuncs->vkCmdPipelineBarrier(commandbuffer, sourceStage, destinationStage,
409 0, 0,
nullptr, 0,
nullptr, 1, &barrier);
415 uint32_t Width, uint32_t Height,
416 VkCommandBuffer CommandBuffer)
419 VkBufferImageCopy region { };
420 region.bufferOffset = 0;
421 region.bufferRowLength = 0;
422 region.bufferImageHeight = 0;
423 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
424 region.imageSubresource.mipLevel = 0;
425 region.imageSubresource.baseArrayLayer = 0;
426 region.imageSubresource.layerCount = 1;
427 region.imageOffset = { 0, 0, 0 };
428 region.imageExtent = { Width, Height, 1 };
429 m_devFuncs->vkCmdCopyBufferToImage(commandbuffer,
Buffer, Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
436 VkBufferCopy region { };
441 m_devFuncs->vkCmdCopyBuffer(CommandBuffer, Src, Dst, 1, ®ion);
446 m_devFuncs->vkCmdCopyBuffer(cmdbuf, Src, Dst, 1, ®ion);
452 VkBufferUsageFlags Usage,
455 VkDeviceMemory &Memory)
457 VkBufferCreateInfo bufferInfo { };
458 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
459 bufferInfo.size = Size;
460 bufferInfo.usage = Usage;
461 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
465 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create buffer");
469 VkMemoryRequirements requirements;
472 VkMemoryAllocateInfo allocInfo { };
473 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
474 allocInfo.allocationSize = requirements.size;
477 allocInfo.memoryTypeIndex =
type.value();
478 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocInfo,
nullptr, &Memory) == VK_SUCCESS)
483 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate buffer memory");
487 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce buffer memory type");
497 VkSamplerCreateInfo samplerinfo { };
498 memset(&samplerinfo, 0,
sizeof(samplerinfo));
499 samplerinfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
500 samplerinfo.minFilter = Min;
501 samplerinfo.magFilter = Mag;
502 samplerinfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
503 samplerinfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
504 samplerinfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
505 samplerinfo.anisotropyEnable = VK_FALSE;
506 samplerinfo.maxAnisotropy = 1;
507 samplerinfo.borderColor = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
508 samplerinfo.unnormalizedCoordinates = VK_FALSE;
509 samplerinfo.compareEnable = VK_FALSE;
510 samplerinfo.compareOp = VK_COMPARE_OP_ALWAYS;
511 samplerinfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
512 if (
m_devFuncs->vkCreateSampler(
m_device, &samplerinfo,
nullptr, &result) != VK_SUCCESS)
513 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create image sampler");
542 VkImageTiling Tiling,
543 VkImageUsageFlags Usage,
546 VkDeviceMemory &ImageMemory)
548 VkImageCreateInfo imageinfo { };
549 imageinfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
550 imageinfo.imageType = VK_IMAGE_TYPE_2D;
551 imageinfo.extent.width =
static_cast<uint32_t
>(Size.width());
552 imageinfo.extent.height =
static_cast<uint32_t
>(Size.height());
553 imageinfo.extent.depth = 1;
554 imageinfo.mipLevels = 1;
555 imageinfo.arrayLayers = 1;
556 imageinfo.format =
Format;
557 imageinfo.tiling = Tiling;
558 imageinfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
559 imageinfo.usage = Usage;
560 imageinfo.samples = VK_SAMPLE_COUNT_1_BIT;
561 imageinfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
565 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create Vulkan image");
569 VkMemoryRequirements requirements;
572 VkMemoryAllocateInfo allocinfo { };
573 allocinfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
574 allocinfo.allocationSize = requirements.size;
577 allocinfo.memoryTypeIndex =
type.value();
578 if (
m_devFuncs->vkAllocateMemory(
m_device, &allocinfo,
nullptr, &ImageMemory) == VK_SUCCESS)
583 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to allocate image memory");
587 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to deduce image memory type");
596 std::optional<uint32_t> result;
597 VkPhysicalDeviceMemoryProperties memoryprops;
598 m_funcs->vkGetPhysicalDeviceMemoryProperties(
m_window->physicalDevice(), &memoryprops);
600 for (uint32_t i = 0; i < memoryprops.memoryTypeCount; i++)
602 if ((Filter & (1 << i)) && (memoryprops.memoryTypes[i].propertyFlags &
Properties) ==
Properties)
614 VkCommandBufferAllocateInfo allocinfo { };
615 allocinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
616 allocinfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
617 allocinfo.commandPool =
m_window->graphicsCommandPool();
618 allocinfo.commandBufferCount = 1;
619 VkCommandBuffer commandbuffer =
nullptr;
621 VkCommandBufferBeginInfo begininfo { };
622 begininfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
623 begininfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
624 m_devFuncs->vkBeginCommandBuffer(commandbuffer, &begininfo);
625 return commandbuffer;
631 VkSubmitInfo submitinfo{};
632 submitinfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
633 submitinfo.commandBufferCount = 1;
634 submitinfo.pCommandBuffers = &
Buffer;
641 const QRect Viewport,
642 std::vector<VkDynamicState> Dynamic)
644 if (!(Shader && Viewport.isValid()))
648 const auto & shaderstages = Shader->
Stages();
651 VkPipelineInputAssemblyStateCreateInfo inputassembly { };
652 inputassembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
654 inputassembly.primitiveRestartEnable = VK_FALSE;
657 VkViewport viewport { };
658 viewport.x =
static_cast<float>(Viewport.left());
659 viewport.y =
static_cast<float>(Viewport.left());
660 viewport.width =
static_cast<float>(Viewport.width());
661 viewport.height =
static_cast<float>(Viewport.height());
662 viewport.minDepth = 0.0F;
663 viewport.maxDepth = 1.0F;
665 VkRect2D scissor { };
666 scissor.offset = { Viewport.left(), Viewport.top() };
667 scissor.extent = {
static_cast<uint32_t
>(Viewport.width()),
static_cast<uint32_t
>(Viewport.height()) };
669 VkPipelineViewportStateCreateInfo viewportstate { };
670 viewportstate.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
671 viewportstate.viewportCount = 1;
672 viewportstate.pViewports = &viewport;
673 viewportstate.scissorCount = 1;
674 viewportstate.pScissors = &scissor;
677 VkPipelineVertexInputStateCreateInfo vertexinput { };
679 if (vertexattribs.empty())
681 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
682 vertexinput.vertexBindingDescriptionCount = 0;
683 vertexinput.pVertexBindingDescriptions =
nullptr;
684 vertexinput.vertexAttributeDescriptionCount = 0;
685 vertexinput.pVertexAttributeDescriptions =
nullptr;
689 vertexinput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
690 vertexinput.vertexBindingDescriptionCount = 1;
692 vertexinput.vertexAttributeDescriptionCount =
static_cast<uint32_t
>(vertexattribs.size());
693 vertexinput.pVertexAttributeDescriptions = vertexattribs.data();
697 VkPipelineMultisampleStateCreateInfo multisampling { };
698 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
699 multisampling.sampleShadingEnable = VK_FALSE;
700 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
703 VkPipelineColorBlendAttachmentState colorblendattachment { };
704 colorblendattachment.blendEnable = VK_TRUE;
705 colorblendattachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
706 colorblendattachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
707 colorblendattachment.colorBlendOp = VK_BLEND_OP_ADD;
708 colorblendattachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
709 colorblendattachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
710 colorblendattachment.alphaBlendOp = VK_BLEND_OP_ADD;
711 colorblendattachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
712 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
714 VkPipelineColorBlendStateCreateInfo colorBlending{};
715 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
716 colorBlending.logicOpEnable = VK_FALSE;
717 colorBlending.logicOp = VK_LOGIC_OP_COPY;
718 colorBlending.attachmentCount = 1;
719 colorBlending.pAttachments = &colorblendattachment;
720 colorBlending.blendConstants[0] = 0.0F;
721 colorBlending.blendConstants[1] = 0.0F;
722 colorBlending.blendConstants[2] = 0.0F;
723 colorBlending.blendConstants[3] = 0.0F;
726 VkPipelineRasterizationStateCreateInfo rasterizer { };
727 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
728 rasterizer.depthClampEnable = VK_FALSE;
729 rasterizer.rasterizerDiscardEnable = VK_FALSE;
730 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
731 rasterizer.lineWidth = 1.0F;
732 rasterizer.cullMode = VK_CULL_MODE_NONE;
733 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
734 rasterizer.depthBiasEnable = VK_FALSE;
737 VkPipelineDepthStencilStateCreateInfo depthstencil { };
738 depthstencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
739 depthstencil.pNext =
nullptr;
740 depthstencil.flags = 0;
741 depthstencil.depthTestEnable = VK_FALSE;
742 depthstencil.depthWriteEnable = VK_FALSE;
743 depthstencil.depthCompareOp = VK_COMPARE_OP_NEVER;
744 depthstencil.depthBoundsTestEnable = VK_FALSE;
745 depthstencil.stencilTestEnable = VK_FALSE;
746 depthstencil.front = { };
747 depthstencil.back = { };
748 depthstencil.minDepthBounds = 0.0F;
749 depthstencil.maxDepthBounds = 1.0F;
752 VkPipelineDynamicStateCreateInfo dynamic { };
753 dynamic.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
754 dynamic.dynamicStateCount = Dynamic.empty() ? 0 :
static_cast<uint32_t
>(Dynamic.size());
755 dynamic.pDynamicStates = Dynamic.empty() ? nullptr : Dynamic.data();
758 VkGraphicsPipelineCreateInfo pipelinecreate { };
759 pipelinecreate.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
760 pipelinecreate.pNext =
nullptr;
761 pipelinecreate.flags = 0;
762 pipelinecreate.stageCount =
static_cast<uint32_t
>(shaderstages.size());
763 pipelinecreate.pStages = shaderstages.data();
764 pipelinecreate.pVertexInputState = &vertexinput;
765 pipelinecreate.pInputAssemblyState = &inputassembly;
766 pipelinecreate.pTessellationState =
nullptr;
767 pipelinecreate.pViewportState = &viewportstate;
768 pipelinecreate.pRasterizationState = &rasterizer;
769 pipelinecreate.pMultisampleState = &multisampling;
770 pipelinecreate.pDepthStencilState = &depthstencil;
771 pipelinecreate.pColorBlendState = &colorBlending;
772 pipelinecreate.pDynamicState = &dynamic;
774 pipelinecreate.renderPass =
m_window->defaultRenderPass();
775 pipelinecreate.subpass = 0;
777 pipelinecreate.basePipelineIndex = 0;
783 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