5#include <qpa/qplatformvulkaninstance.h>
7#define VMA_IMPLEMENTATION
8#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
9#define VMA_STATIC_VULKAN_FUNCTIONS 0
10#define VMA_RECORDING_ENABLED 0
11#define VMA_DEDICATED_ALLOCATION 0
13#define VMA_DEBUG_INITIALIZE_ALLOCATIONS 1
17#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 1100
20#include "vk_mem_alloc.h"
24#include <QVulkanFunctions>
25#include <QtGui/qwindow.h>
289 return (
v + byteAlign - 1) & ~(byteAlign - 1);
306 return reinterpret_cast<VmaAllocation
>(
a);
311 return reinterpret_cast<VmaAllocator
>(
a);
333QByteArrayList QRhiVulkanInitParams::preferredExtensionsForImportedDevice()
349 physDev = importParams->physDev;
350 dev = importParams->dev;
356 if (importParams->vmemAllocator) {
365 QVulkanInstance::DebugMessageTypeFlags
type,
366 const void *callbackData)
370#ifdef VK_EXT_debug_utils
371 const VkDebugUtilsMessengerCallbackDataEXT *
d =
static_cast<const VkDebugUtilsMessengerCallbackDataEXT *
>(callbackData);
375 if (strstr(
d->pMessage,
"Mapping an image with layout")
376 && strstr(
d->pMessage,
"can result in undefined behavior if this memory is used by the device"))
387 if (strstr(
d->pMessage,
"VUID-VkDescriptorSetAllocateInfo-descriptorPool-00307"))
398 case VK_PHYSICAL_DEVICE_TYPE_OTHER:
400 case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
402 case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
404 case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
406 case VK_PHYSICAL_DEVICE_TYPE_CPU:
416 if (!
inst->isValid()) {
417 qWarning(
"Vulkan instance is not valid");
422 qCDebug(QRHI_LOG_INFO,
"Initializing QRhi Vulkan backend %p with flags %d",
this,
int(
rhiFlags));
425 f =
inst->functions();
427 qCDebug(QRHI_LOG_INFO,
"Enabled instance extensions:");
428 for (
const char *
ext :
inst->extensions())
434 auto queryQueueFamilyProps = [
this, &queueFamilyProps] {
435 uint32_t queueCount = 0;
436 f->vkGetPhysicalDeviceQueueFamilyProperties(
physDev, &queueCount,
nullptr);
437 queueFamilyProps.
resize(
int(queueCount));
438 f->vkGetPhysicalDeviceQueueFamilyProperties(
physDev, &queueCount, queueFamilyProps.
data());
443 uint32_t physDevCount = 0;
444 f->vkEnumeratePhysicalDevices(
inst->vkInstance(), &physDevCount,
nullptr);
450 VkResult err =
f->vkEnumeratePhysicalDevices(
inst->vkInstance(), &physDevCount, physDevs.
data());
451 if (err != VK_SUCCESS || !physDevCount) {
452 qWarning(
"Failed to enumerate physical devices: %d", err);
456 int physDevIndex = -1;
457 int requestedPhysDevIndex = -1;
462 for (
int i = 0;
i < int(physDevCount); ++
i) {
465 requestedPhysDevIndex =
i;
471 for (
int i = 0;
i < int(physDevCount); ++
i) {
473 qCDebug(QRHI_LOG_INFO,
"Physical device %d: '%s' %d.%d.%d (api %d.%d.%d vendor 0x%X device 0x%X type %d)",
485 if (physDevIndex < 0 && (requestedPhysDevIndex < 0 || requestedPhysDevIndex ==
int(
i))) {
487 qCDebug(QRHI_LOG_INFO,
" using this physical device");
491 if (physDevIndex < 0) {
492 qWarning(
"No matching physical device");
495 physDev = physDevs[physDevIndex];
499 qCDebug(QRHI_LOG_INFO,
"Using imported physical device '%s' %d.%d.%d (api %d.%d.%d vendor 0x%X device 0x%X type %d)",
512 caps.apiVersion =
inst->apiVersion();
520 if (physDevApiVersion <
caps.apiVersion) {
521 qCDebug(QRHI_LOG_INFO) <<
"Instance has api version" <<
caps.apiVersion
522 <<
"whereas the chosen physical device has" << physDevApiVersion
523 <<
"- restricting to the latter";
524 caps.apiVersion = physDevApiVersion;
533 VkPhysicalDeviceFeatures2 physDevFeaturesChainable = {};
534 physDevFeaturesChainable.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
535 physDevFeatures11 = {};
536 physDevFeatures11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
537 physDevFeatures12 = {};
538 physDevFeatures12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
540 physDevFeatures13 = {};
541 physDevFeatures13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
544 physDevFeaturesChainable.pNext = &physDevFeatures11;
545 physDevFeatures11.pNext = &physDevFeatures12;
548 physDevFeatures12.pNext = &physDevFeatures13;
550 f->vkGetPhysicalDeviceFeatures2(
physDev, &physDevFeaturesChainable);
551 memcpy(&
physDevFeatures, &physDevFeaturesChainable.features,
sizeof(VkPhysicalDeviceFeatures));
563 std::optional<uint32_t> gfxQueueFamilyIdxOpt;
564 std::optional<uint32_t> computelessGfxQueueCandidateIdxOpt;
565 queryQueueFamilyProps();
566 const uint32_t queueFamilyCount = uint32_t(queueFamilyProps.
size());
567 for (uint32_t
i = 0;
i < queueFamilyCount; ++
i) {
568 qCDebug(QRHI_LOG_INFO,
"queue family %u: flags=0x%x count=%u",
569 i, queueFamilyProps[
i].queueFlags, queueFamilyProps[
i].queueCount);
570 if (!gfxQueueFamilyIdxOpt.has_value()
571 && (queueFamilyProps[
i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
574 if (queueFamilyProps[
i].queueFlags & VK_QUEUE_COMPUTE_BIT)
575 gfxQueueFamilyIdxOpt =
i;
576 else if (!computelessGfxQueueCandidateIdxOpt.has_value())
577 computelessGfxQueueCandidateIdxOpt =
i;
580 if (gfxQueueFamilyIdxOpt.has_value()) {
583 if (computelessGfxQueueCandidateIdxOpt.has_value()) {
586 qWarning(
"No graphics (or no graphics+present) queue family found");
591 VkDeviceQueueCreateInfo queueInfo = {};
592 const float prio[] = { 0 };
593 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
595 queueInfo.queueCount = 1;
596 queueInfo.pQueuePriorities = prio;
599 if (
inst->layers().contains(
"VK_LAYER_KHRONOS_validation"))
600 devLayers.
append(
"VK_LAYER_KHRONOS_validation");
603 uint32_t devExtCount = 0;
604 f->vkEnumerateDeviceExtensionProperties(
physDev,
nullptr, &devExtCount,
nullptr);
607 f->vkEnumerateDeviceExtensionProperties(
physDev,
nullptr, &devExtCount, extProps.
data());
608 for (
const VkExtensionProperties &
p : std::as_const(extProps))
609 devExts.append({
p.extensionName,
p.specVersion });
611 qCDebug(QRHI_LOG_INFO,
"%d device extensions available",
int(devExts.size()));
614 requestedDevExts.
append(
"VK_KHR_swapchain");
616 const bool hasPhysDevProp2 =
inst->extensions().contains(
QByteArrayLiteral(
"VK_KHR_get_physical_device_properties2"));
619 if (hasPhysDevProp2) {
620 requestedDevExts.
append(
"VK_KHR_portability_subset");
622 qWarning(
"VK_KHR_portability_subset should be enabled on the device "
623 "but the instance does not have VK_KHR_get_physical_device_properties2 enabled. "
628 caps.vertexAttribDivisor =
false;
629#ifdef VK_EXT_vertex_attribute_divisor
630 if (devExts.contains(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME)) {
631 if (hasPhysDevProp2) {
632 requestedDevExts.
append(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME);
633 caps.vertexAttribDivisor =
true;
640 if (devExts.contains(
ext)) {
643 qWarning(
"Device extension %s requested in QRhiVulkanInitParams is not supported",
652 if (devExts.contains(
ext)) {
655 qWarning(
"Device extension %s requested in QT_VULKAN_DEVICE_EXTENSIONS is not supported",
662 qCDebug(QRHI_LOG_INFO,
"Enabling device extensions:");
663 for (
const char *
ext : requestedDevExts)
667 VkDeviceCreateInfo devInfo = {};
668 devInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
669 devInfo.queueCreateInfoCount = 1;
670 devInfo.pQueueCreateInfos = &queueInfo;
671 devInfo.enabledLayerCount = uint32_t(devLayers.size());
672 devInfo.ppEnabledLayerNames = devLayers.constData();
673 devInfo.enabledExtensionCount = uint32_t(requestedDevExts.
size());
674 devInfo.ppEnabledExtensionNames = requestedDevExts.
constData();
691 physDevFeaturesChainable.features.robustBufferAccess = VK_FALSE;
693 physDevFeatures13.robustImageAccess = VK_FALSE;
695 devInfo.pNext = &physDevFeaturesChainable;
703 VkResult err =
f->vkCreateDevice(
physDev, &devInfo,
nullptr, &
dev);
704 if (err != VK_SUCCESS) {
705 qWarning(
"Failed to create device: %d", err);
709 qCDebug(QRHI_LOG_INFO,
"Using imported device %p", dev);
712 vkGetPhysicalDeviceSurfaceCapabilitiesKHR =
reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
>(
713 inst->getInstanceProcAddr(
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR"));
714 vkGetPhysicalDeviceSurfaceFormatsKHR =
reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR
>(
715 inst->getInstanceProcAddr(
"vkGetPhysicalDeviceSurfaceFormatsKHR"));
716 vkGetPhysicalDeviceSurfacePresentModesKHR =
reinterpret_cast<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
>(
717 inst->getInstanceProcAddr(
"vkGetPhysicalDeviceSurfacePresentModesKHR"));
719 df = inst->deviceFunctions(dev);
721 VkCommandPoolCreateInfo poolInfo = {};
722 poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
723 poolInfo.queueFamilyIndex = gfxQueueFamilyIdx;
725 VkResult err = df->vkCreateCommandPool(dev, &poolInfo,
nullptr, &cmdPool[
i]);
726 if (err != VK_SUCCESS) {
727 qWarning(
"Failed to create command pool: %d", err);
732 qCDebug(QRHI_LOG_INFO,
"Using queue family index %u and queue index %u",
733 gfxQueueFamilyIdx, gfxQueueIdx);
735 df->vkGetDeviceQueue(dev, gfxQueueFamilyIdx, gfxQueueIdx, &gfxQueue);
737 if (queueFamilyProps.isEmpty())
738 queryQueueFamilyProps();
740 caps.compute = (queueFamilyProps[gfxQueueFamilyIdx].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
741 timestampValidBits = queueFamilyProps[gfxQueueFamilyIdx].timestampValidBits;
743 ubufAlign = physDevProperties.limits.minUniformBufferOffsetAlignment;
746 texbufAlign = qMax<VkDeviceSize>(4, physDevProperties.limits.optimalBufferCopyOffsetAlignment);
748 caps.wideLines = physDevFeatures.wideLines;
750 caps.texture3DSliceAs2D = caps.apiVersion >=
QVersionNumber(1, 1);
752 caps.tessellation = physDevFeatures.tessellationShader;
753 caps.geometryShader = physDevFeatures.geometryShader;
755 caps.nonFillPolygonMode = physDevFeatures.fillModeNonSolid;
758 caps.multiView = caps.apiVersion >=
QVersionNumber(1, 1) && physDevFeatures11.multiview;
761 if (!importedAllocator) {
762 VmaVulkanFunctions
funcs = {};
766 VmaAllocatorCreateInfo allocatorInfo = {};
769 allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
770 allocatorInfo.physicalDevice = physDev;
771 allocatorInfo.device = dev;
772 allocatorInfo.pVulkanFunctions = &
funcs;
773 allocatorInfo.instance = inst->vkInstance();
776 allocatorInfo.vulkanApiVersion = VK_MAKE_VERSION(apiVer.
majorVersion(),
780 VmaAllocator vmaallocator;
781 VkResult err = vmaCreateAllocator(&allocatorInfo, &vmaallocator);
782 if (err != VK_SUCCESS) {
783 qWarning(
"Failed to create allocator: %d", err);
786 allocator = vmaallocator;
791 VkDescriptorPool
pool;
792 VkResult err = createDescriptorPool(&
pool);
793 if (err == VK_SUCCESS)
794 descriptorPools.append(
pool);
796 qWarning(
"Failed to create initial descriptor pool: %d", err);
798 VkQueryPoolCreateInfo timestampQueryPoolInfo = {};
799 timestampQueryPoolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
800 timestampQueryPoolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
802 err = df->vkCreateQueryPool(dev, ×tampQueryPoolInfo,
nullptr, ×tampQueryPool);
803 if (err != VK_SUCCESS) {
804 qWarning(
"Failed to create timestamp query pool: %d", err);
808 timestampQueryPoolMap.fill(
false);
810#ifdef VK_EXT_debug_utils
811 if (caps.debugUtils) {
812 vkSetDebugUtilsObjectNameEXT =
reinterpret_cast<PFN_vkSetDebugUtilsObjectNameEXT
>(
f->vkGetDeviceProcAddr(dev,
"vkSetDebugUtilsObjectNameEXT"));
813 vkCmdBeginDebugUtilsLabelEXT =
reinterpret_cast<PFN_vkCmdBeginDebugUtilsLabelEXT
>(
f->vkGetDeviceProcAddr(dev,
"vkCmdBeginDebugUtilsLabelEXT"));
814 vkCmdEndDebugUtilsLabelEXT =
reinterpret_cast<PFN_vkCmdEndDebugUtilsLabelEXT
>(
f->vkGetDeviceProcAddr(dev,
"vkCmdEndDebugUtilsLabelEXT"));
815 vkCmdInsertDebugUtilsLabelEXT =
reinterpret_cast<PFN_vkCmdInsertDebugUtilsLabelEXT
>(
f->vkGetDeviceProcAddr(dev,
"vkCmdInsertDebugUtilsLabelEXT"));
821 nativeHandlesStruct.physDev = physDev;
822 nativeHandlesStruct.dev = dev;
823 nativeHandlesStruct.gfxQueueFamilyIdx = gfxQueueFamilyIdx;
824 nativeHandlesStruct.gfxQueueIdx = gfxQueueIdx;
825 nativeHandlesStruct.gfxQueue = gfxQueue;
826 nativeHandlesStruct.vmemAllocator = allocator;
827 nativeHandlesStruct.inst = inst;
838 df->vkDeviceWaitIdle(
dev);
854 df->vkDestroyDescriptorPool(
dev,
pool.pool,
nullptr);
878 df->vkDestroyDevice(
dev,
nullptr);
879 inst->resetDeviceFunctions(
dev);
880 dev = VK_NULL_HANDLE;
889 VkDescriptorPoolSize descPoolSizes[] = {
896 VkDescriptorPoolCreateInfo descPoolInfo = {};
897 descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
901 descPoolInfo.flags = 0;
903 descPoolInfo.poolSizeCount =
sizeof(descPoolSizes) /
sizeof(descPoolSizes[0]);
904 descPoolInfo.pPoolSizes = descPoolSizes;
905 return df->vkCreateDescriptorPool(
dev, &descPoolInfo,
nullptr,
pool);
910 auto tryAllocate = [
this, allocInfo,
result](
int poolIndex) {
912 VkResult
r =
df->vkAllocateDescriptorSets(
dev, allocInfo,
result);
919 for (
int i = lastPoolIdx;
i >= 0; --
i) {
925 VkResult err = tryAllocate(
i);
926 if (err == VK_SUCCESS) {
928 *resultPoolIndex =
i;
934 VkDescriptorPool newPool;
936 if (poolErr == VK_SUCCESS) {
939 VkResult err = tryAllocate(lastPoolIdx);
940 if (err != VK_SUCCESS) {
941 qWarning(
"Failed to allocate descriptor set from new pool too, giving up: %d", err);
944 descriptorPools[lastPoolIdx].allocedDescSets += allocInfo->descriptorSetCount;
945 *resultPoolIndex = lastPoolIdx;
948 qWarning(
"Failed to allocate new descriptor pool: %d", poolErr);
958 return srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM;
960 return srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM;
962 return srgb ? VK_FORMAT_R8_SRGB : VK_FORMAT_R8_UNORM;
964 return srgb ? VK_FORMAT_R8G8_SRGB : VK_FORMAT_R8G8_UNORM;
966 return VK_FORMAT_R16_UNORM;
968 return VK_FORMAT_R16G16_UNORM;
970 return VK_FORMAT_R8_UNORM;
973 return VK_FORMAT_R16G16B16A16_SFLOAT;
975 return VK_FORMAT_R32G32B32A32_SFLOAT;
977 return VK_FORMAT_R16_SFLOAT;
979 return VK_FORMAT_R32_SFLOAT;
983 return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
986 return VK_FORMAT_D16_UNORM;
988 return VK_FORMAT_X8_D24_UNORM_PACK32;
990 return VK_FORMAT_D24_UNORM_S8_UINT;
992 return VK_FORMAT_D32_SFLOAT;
995 return srgb ? VK_FORMAT_BC1_RGB_SRGB_BLOCK : VK_FORMAT_BC1_RGB_UNORM_BLOCK;
997 return srgb ? VK_FORMAT_BC2_SRGB_BLOCK : VK_FORMAT_BC2_UNORM_BLOCK;
999 return srgb ? VK_FORMAT_BC3_SRGB_BLOCK : VK_FORMAT_BC3_UNORM_BLOCK;
1001 return VK_FORMAT_BC4_UNORM_BLOCK;
1003 return VK_FORMAT_BC5_UNORM_BLOCK;
1005 return VK_FORMAT_BC6H_UFLOAT_BLOCK;
1007 return srgb ? VK_FORMAT_BC7_SRGB_BLOCK : VK_FORMAT_BC7_UNORM_BLOCK;
1010 return srgb ? VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
1012 return srgb ? VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
1014 return srgb ? VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
1017 return srgb ? VK_FORMAT_ASTC_4x4_SRGB_BLOCK : VK_FORMAT_ASTC_4x4_UNORM_BLOCK;
1019 return srgb ? VK_FORMAT_ASTC_5x4_SRGB_BLOCK : VK_FORMAT_ASTC_5x4_UNORM_BLOCK;
1021 return srgb ? VK_FORMAT_ASTC_5x5_SRGB_BLOCK : VK_FORMAT_ASTC_5x5_UNORM_BLOCK;
1023 return srgb ? VK_FORMAT_ASTC_6x5_SRGB_BLOCK : VK_FORMAT_ASTC_6x5_UNORM_BLOCK;
1025 return srgb ? VK_FORMAT_ASTC_6x6_SRGB_BLOCK : VK_FORMAT_ASTC_6x6_UNORM_BLOCK;
1027 return srgb ? VK_FORMAT_ASTC_8x5_SRGB_BLOCK : VK_FORMAT_ASTC_8x5_UNORM_BLOCK;
1029 return srgb ? VK_FORMAT_ASTC_8x6_SRGB_BLOCK : VK_FORMAT_ASTC_8x6_UNORM_BLOCK;
1031 return srgb ? VK_FORMAT_ASTC_8x8_SRGB_BLOCK : VK_FORMAT_ASTC_8x8_UNORM_BLOCK;
1033 return srgb ? VK_FORMAT_ASTC_10x5_SRGB_BLOCK : VK_FORMAT_ASTC_10x5_UNORM_BLOCK;
1035 return srgb ? VK_FORMAT_ASTC_10x6_SRGB_BLOCK : VK_FORMAT_ASTC_10x6_UNORM_BLOCK;
1037 return srgb ? VK_FORMAT_ASTC_10x8_SRGB_BLOCK : VK_FORMAT_ASTC_10x8_UNORM_BLOCK;
1039 return srgb ? VK_FORMAT_ASTC_10x10_SRGB_BLOCK : VK_FORMAT_ASTC_10x10_UNORM_BLOCK;
1041 return srgb ? VK_FORMAT_ASTC_12x10_SRGB_BLOCK : VK_FORMAT_ASTC_12x10_UNORM_BLOCK;
1043 return srgb ? VK_FORMAT_ASTC_12x12_SRGB_BLOCK : VK_FORMAT_ASTC_12x12_UNORM_BLOCK;
1046 Q_UNREACHABLE_RETURN(VK_FORMAT_R8G8B8A8_UNORM);
1053 case VK_FORMAT_R8G8B8A8_UNORM:
1055 case VK_FORMAT_R8G8B8A8_SRGB:
1059 case VK_FORMAT_B8G8R8A8_UNORM:
1061 case VK_FORMAT_B8G8R8A8_SRGB:
1065 case VK_FORMAT_R16G16B16A16_SFLOAT:
1067 case VK_FORMAT_R32G32B32A32_SFLOAT:
1069 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1104 VkPhysicalDeviceMemoryProperties physDevMemProps;
1105 f->vkGetPhysicalDeviceMemoryProperties(
physDev, &physDevMemProps);
1107 VkMemoryRequirements memReq;
1108 df->vkGetImageMemoryRequirements(
dev,
img, &memReq);
1109 uint32_t memTypeIndex = uint32_t(-1);
1111 if (memReq.memoryTypeBits) {
1113 const VkMemoryType *memType = physDevMemProps.memoryTypes;
1114 bool foundDevLocal =
false;
1115 for (uint32_t
i = startIndex;
i < physDevMemProps.memoryTypeCount; ++
i) {
1116 if (memReq.memoryTypeBits & (1 <<
i)) {
1117 if (memType[
i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
1118 if (!foundDevLocal) {
1119 foundDevLocal =
true;
1122 if (memType[
i].propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) {
1131 return memTypeIndex;
1135 const QSize &pixelSize,
1136 VkImageUsageFlags
usage,
1137 VkImageAspectFlags aspectMask,
1138 VkSampleCountFlagBits
samples,
1139 VkDeviceMemory *mem,
1144 VkMemoryRequirements memReq;
1148 VkImageCreateInfo imgInfo = {};
1149 imgInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1150 imgInfo.imageType = VK_IMAGE_TYPE_2D;
1152 imgInfo.extent.width = uint32_t(pixelSize.
width());
1153 imgInfo.extent.height = uint32_t(pixelSize.
height());
1154 imgInfo.extent.depth = 1;
1155 imgInfo.mipLevels = imgInfo.arrayLayers = 1;
1157 imgInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
1158 imgInfo.usage =
usage | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1159 imgInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1161 err =
df->vkCreateImage(
dev, &imgInfo,
nullptr,
images +
i);
1162 if (err != VK_SUCCESS) {
1163 qWarning(
"Failed to create image: %d", err);
1170 df->vkGetImageMemoryRequirements(
dev,
images[
i], &memReq);
1173 VkMemoryAllocateInfo memInfo = {};
1174 memInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
1175 memInfo.allocationSize =
aligned(memReq.size, memReq.alignment) * VkDeviceSize(
count);
1177 uint32_t startIndex = 0;
1180 if (memInfo.memoryTypeIndex == uint32_t(-1)) {
1181 qWarning(
"No suitable memory type found");
1184 startIndex = memInfo.memoryTypeIndex + 1;
1185 err =
df->vkAllocateMemory(
dev, &memInfo,
nullptr, mem);
1186 if (err != VK_SUCCESS && err != VK_ERROR_OUT_OF_DEVICE_MEMORY) {
1187 qWarning(
"Failed to allocate image memory: %d", err);
1190 }
while (err != VK_SUCCESS);
1192 VkDeviceSize ofs = 0;
1194 err =
df->vkBindImageMemory(
dev,
images[
i], *mem, ofs);
1195 if (err != VK_SUCCESS) {
1196 qWarning(
"Failed to bind image memory: %d", err);
1199 ofs +=
aligned(memReq.size, memReq.alignment);
1201 VkImageViewCreateInfo imgViewInfo = {};
1202 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1203 imgViewInfo.image =
images[
i];
1204 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1205 imgViewInfo.format =
format;
1206 imgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
1207 imgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
1208 imgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
1209 imgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
1210 imgViewInfo.subresourceRange.aspectMask = aspectMask;
1211 imgViewInfo.subresourceRange.levelCount = imgViewInfo.subresourceRange.layerCount = 1;
1213 err =
df->vkCreateImageView(
dev, &imgViewInfo,
nullptr, views +
i);
1214 if (err != VK_SUCCESS) {
1215 qWarning(
"Failed to create image view: %d", err);
1228 const VkFormat dsFormatCandidates[] = {
1229 VK_FORMAT_D24_UNORM_S8_UINT,
1230 VK_FORMAT_D32_SFLOAT_S8_UINT,
1231 VK_FORMAT_D16_UNORM_S8_UINT
1233 const int dsFormatCandidateCount =
sizeof(dsFormatCandidates) /
sizeof(VkFormat);
1234 int dsFormatIdx = 0;
1235 while (dsFormatIdx < dsFormatCandidateCount) {
1237 VkFormatProperties fmtProp;
1239 if (fmtProp.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
1243 if (dsFormatIdx == dsFormatCandidateCount)
1244 qWarning(
"Failed to find an optimal depth-stencil format");
1250 VkSubpassDescription *subpassDesc,
1253 memset(subpassDesc, 0,
sizeof(VkSubpassDescription));
1254 subpassDesc->pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1255 subpassDesc->colorAttachmentCount = uint32_t(rpD->
colorRefs.
size());
1260 memset(rpInfo, 0,
sizeof(VkRenderPassCreateInfo));
1261 rpInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1262 rpInfo->attachmentCount = uint32_t(rpD->
attDescs.
size());
1264 rpInfo->subpassCount = 1;
1265 rpInfo->pSubpasses = subpassDesc;
1274 VkAttachmentDescription attDesc = {};
1277 attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1278 attDesc.storeOp =
samples > VK_SAMPLE_COUNT_1_BIT ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
1279 attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1280 attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1281 attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1282 attDesc.finalLayout =
samples > VK_SAMPLE_COUNT_1_BIT ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1285 rpD->
colorRefs.
append({ 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL });
1290 if (hasDepthStencil) {
1293 memset(&attDesc, 0,
sizeof(attDesc));
1296 attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1297 attDesc.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1298 attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1299 attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1300 attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1301 attDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1304 rpD->
dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
1307 if (
samples > VK_SAMPLE_COUNT_1_BIT) {
1308 memset(&attDesc, 0,
sizeof(attDesc));
1310 attDesc.samples = VK_SAMPLE_COUNT_1_BIT;
1311 attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
1312 attDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1313 attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1314 attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1315 attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1316 attDesc.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1323 VkSubpassDependency subpassDep = {};
1324 subpassDep.srcSubpass = VK_SUBPASS_EXTERNAL;
1325 subpassDep.dstSubpass = 0;
1326 subpassDep.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1327 subpassDep.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1328 subpassDep.srcAccessMask = 0;
1329 subpassDep.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1331 if (hasDepthStencil) {
1332 memset(&subpassDep, 0,
sizeof(subpassDep));
1333 subpassDep.srcSubpass = VK_SUBPASS_EXTERNAL;
1334 subpassDep.dstSubpass = 0;
1335 subpassDep.srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
1336 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
1337 subpassDep.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
1338 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
1339 subpassDep.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1340 subpassDep.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
1341 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1345 VkRenderPassCreateInfo rpInfo;
1346 VkSubpassDescription subpassDesc;
1349 VkResult err =
df->vkCreateRenderPass(
dev, &rpInfo,
nullptr, &rpD->
rp);
1350 if (err != VK_SUCCESS) {
1351 qWarning(
"Failed to create renderpass: %d", err);
1360 bool prepare(VkRenderPassCreateInfo *rpInfo,
int multiViewCount,
bool multiViewCap)
1362 if (multiViewCount < 2)
1364 if (!multiViewCap) {
1365 qWarning(
"Cannot create multiview render pass without support for the Vulkan 1.1 multiview feature");
1368#ifdef VK_VERSION_1_1
1369 uint32_t allViewsMask = 0;
1370 for (uint32_t
i = 0;
i < uint32_t(multiViewCount); ++
i)
1371 allViewsMask |= (1 <<
i);
1372 multiViewMask = allViewsMask;
1373 multiViewCorrelationMask = allViewsMask;
1374 multiViewInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
1375 multiViewInfo.subpassCount = 1;
1376 multiViewInfo.pViewMasks = &multiViewMask;
1377 multiViewInfo.correlationMaskCount = 1;
1378 multiViewInfo.pCorrelationMasks = &multiViewCorrelationMask;
1379 rpInfo->pNext = &multiViewInfo;
1384#ifdef VK_VERSION_1_1
1385 VkRenderPassMultiviewCreateInfo multiViewInfo = {};
1386 uint32_t multiViewMask = 0;
1387 uint32_t multiViewCorrelationMask = 0;
1401 int multiViewCount = 0;
1402 for (
auto it = firstColorAttachment;
it != lastColorAttachment; ++
it) {
1409 VkAttachmentDescription attDesc = {};
1410 attDesc.format = vkformat;
1412 attDesc.loadOp = preserveColor ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
1413 attDesc.storeOp =
it->resolveTexture() ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE;
1414 attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1415 attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1417 attDesc.initialLayout = preserveColor ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
1418 attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1421 const VkAttachmentReference
ref = { uint32_t(rpD->
attDescs.
size() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
1424 if (
it->multiViewCount() >= 2) {
1425 if (multiViewCount > 0 && multiViewCount !=
it->multiViewCount())
1426 qWarning(
"Inconsistent multiViewCount in color attachment set");
1428 multiViewCount =
it->multiViewCount();
1429 }
else if (multiViewCount > 0) {
1430 qWarning(
"Mixing non-multiview color attachments within a multiview render pass");
1433 Q_ASSERT(multiViewCount == 0 || multiViewCount >= 2);
1438 const VkFormat dsFormat = depthTexture ?
QRHI_RES(
QVkTexture, depthTexture)->vkformat
1442 const VkAttachmentLoadOp loadOp = preserveDs ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
1443 const VkAttachmentStoreOp storeOp = depthTexture ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE;
1444 VkAttachmentDescription attDesc = {};
1445 attDesc.
format = dsFormat;
1447 attDesc.loadOp = loadOp;
1448 attDesc.storeOp = storeOp;
1449 attDesc.stencilLoadOp = loadOp;
1450 attDesc.stencilStoreOp = storeOp;
1451 attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1452 attDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1455 rpD->
dsRef = { uint32_t(rpD->
attDescs.
size() - 1), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
1457 for (
auto it = firstColorAttachment;
it != lastColorAttachment; ++
it) {
1458 if (
it->resolveTexture()) {
1460 const VkFormat dstFormat = rtexD->
vkformat;
1461 if (rtexD->
samples > VK_SAMPLE_COUNT_1_BIT)
1462 qWarning(
"Resolving into a multisample texture is not supported");
1467 if (srcFormat != dstFormat) {
1471 qWarning(
"Multisample resolve between different formats (%d and %d) is not supported.",
1472 int(srcFormat),
int(dstFormat));
1475 VkAttachmentDescription attDesc = {};
1476 attDesc.format = dstFormat;
1477 attDesc.samples = VK_SAMPLE_COUNT_1_BIT;
1478 attDesc.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1479 attDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1480 attDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
1481 attDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
1482 attDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1483 attDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1486 const VkAttachmentReference
ref = { uint32_t(rpD->
attDescs.
size() - 1), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
1489 const VkAttachmentReference
ref = { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
1500 VkRenderPassCreateInfo rpInfo;
1501 VkSubpassDescription subpassDesc;
1505 if (!multiViewHelper.
prepare(&rpInfo, multiViewCount,
caps.multiView))
1508 VkResult err =
df->vkCreateRenderPass(
dev, &rpInfo,
nullptr, &rpD->
rp);
1509 if (err != VK_SUCCESS) {
1510 qWarning(
"Failed to create renderpass: %d", err);
1521 qWarning(
"Surface size is 0, cannot create swapchain");
1525 df->vkDeviceWaitIdle(
dev);
1528 vkCreateSwapchainKHR =
reinterpret_cast<PFN_vkCreateSwapchainKHR
>(
f->vkGetDeviceProcAddr(
dev,
"vkCreateSwapchainKHR"));
1529 vkDestroySwapchainKHR =
reinterpret_cast<PFN_vkDestroySwapchainKHR
>(
f->vkGetDeviceProcAddr(
dev,
"vkDestroySwapchainKHR"));
1531 vkAcquireNextImageKHR =
reinterpret_cast<PFN_vkAcquireNextImageKHR
>(
f->vkGetDeviceProcAddr(
dev,
"vkAcquireNextImageKHR"));
1532 vkQueuePresentKHR =
reinterpret_cast<PFN_vkQueuePresentKHR
>(
f->vkGetDeviceProcAddr(
dev,
"vkQueuePresentKHR"));
1534 qWarning(
"Swapchain functions not available");
1539 VkSurfaceCapabilitiesKHR surfaceCaps;
1543 reqBufferCount = qMax<quint32>(2, surfaceCaps.minImageCount);
1545 reqBufferCount =
qMax(qMin<quint32>(surfaceCaps.maxImageCount, 3), surfaceCaps.minImageCount);
1547 VkSurfaceTransformFlagBitsKHR preTransform =
1548 (surfaceCaps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
1549 ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
1550 : surfaceCaps.currentTransform;
1576 VkCompositeAlphaFlagBitsKHR compositeAlpha =
1577 (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR)
1578 ? VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
1579 : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
1582 if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
1583 compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
1584 else if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
1585 compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
1587 if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR)
1588 compositeAlpha = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
1589 else if (surfaceCaps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR)
1590 compositeAlpha = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
1593 VkImageUsageFlags
usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1594 swapChainD->
supportsReadback = (surfaceCaps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1596 usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1598 VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
1601 presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
1603 presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
1613 qCDebug(QRHI_LOG_INFO,
"Creating %s swapchain of %u buffers, size %dx%d, presentation mode %d",
1614 reuseExisting ?
"recycled" :
"new",
1617 VkSwapchainCreateInfoKHR swapChainInfo = {};
1618 swapChainInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
1619 swapChainInfo.surface = swapChainD->
surface;
1620 swapChainInfo.minImageCount = reqBufferCount;
1621 swapChainInfo.imageFormat = swapChainD->
colorFormat;
1622 swapChainInfo.imageColorSpace = swapChainD->
colorSpace;
1624 swapChainInfo.imageArrayLayers = 1;
1625 swapChainInfo.imageUsage =
usage;
1626 swapChainInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1627 swapChainInfo.preTransform = preTransform;
1628 swapChainInfo.compositeAlpha = compositeAlpha;
1629 swapChainInfo.presentMode = presentMode;
1630 swapChainInfo.clipped =
true;
1631 swapChainInfo.oldSwapchain = reuseExisting ? swapChainD->
sc : VK_NULL_HANDLE;
1633 VkSwapchainKHR newSwapChain;
1635 if (err != VK_SUCCESS) {
1636 qWarning(
"Failed to create swapchain: %d", err);
1643 swapChainD->
sc = newSwapChain;
1646 quint32 actualSwapChainBufferCount = 0;
1648 if (err != VK_SUCCESS || actualSwapChainBufferCount == 0) {
1649 qWarning(
"Failed to get swapchain images: %d", err);
1653 if (actualSwapChainBufferCount != reqBufferCount)
1654 qCDebug(QRHI_LOG_INFO,
"Actual swapchain buffer count is %u", actualSwapChainBufferCount);
1655 swapChainD->
bufferCount = int(actualSwapChainBufferCount);
1659 if (err != VK_SUCCESS) {
1660 qWarning(
"Failed to get swapchain images: %d", err);
1666 if (swapChainD->
samples > VK_SAMPLE_COUNT_1_BIT) {
1669 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1670 VK_IMAGE_ASPECT_COLOR_BIT,
1677 qWarning(
"Failed to create transient image for MSAA color buffer");
1682 VkFenceCreateInfo fenceInfo = {};
1683 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
1684 fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
1689 image.image = swapChainImages[
i];
1690 if (swapChainD->
samples > VK_SAMPLE_COUNT_1_BIT) {
1691 image.msaaImage = msaaImages[
i];
1692 image.msaaImageView = msaaViews[
i];
1695 VkImageViewCreateInfo imgViewInfo = {};
1696 imgViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1697 imgViewInfo.image = swapChainImages[
i];
1698 imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
1700 imgViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
1701 imgViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
1702 imgViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
1703 imgViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
1704 imgViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1705 imgViewInfo.subresourceRange.levelCount = imgViewInfo.subresourceRange.layerCount = 1;
1706 err =
df->vkCreateImageView(
dev, &imgViewInfo,
nullptr, &
image.imageView);
1707 if (err != VK_SUCCESS) {
1708 qWarning(
"Failed to create swapchain image view %d: %d",
i, err);
1717 VkSemaphoreCreateInfo semInfo = {};
1718 semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1723 frame.imageAcquired =
false;
1724 frame.imageSemWaitable =
false;
1726 df->vkCreateFence(
dev, &fenceInfo,
nullptr, &
frame.imageFence);
1727 frame.imageFenceWaitable =
true;
1729 df->vkCreateSemaphore(
dev, &semInfo,
nullptr, &
frame.imageSem);
1730 df->vkCreateSemaphore(
dev, &semInfo,
nullptr, &
frame.drawSem);
1732 err =
df->vkCreateFence(
dev, &fenceInfo,
nullptr, &
frame.cmdFence);
1733 if (err != VK_SUCCESS) {
1734 qWarning(
"Failed to create command buffer fence: %d", err);
1737 frame.cmdFenceWaitable =
true;
1749 if (swapChainD->
sc == VK_NULL_HANDLE)
1753 df->vkDeviceWaitIdle(
dev);
1757 if (
frame.cmdFence) {
1758 if (
frame.cmdFenceWaitable)
1759 df->vkWaitForFences(
dev, 1, &
frame.cmdFence, VK_TRUE, UINT64_MAX);
1760 df->vkDestroyFence(
dev,
frame.cmdFence,
nullptr);
1761 frame.cmdFence = VK_NULL_HANDLE;
1762 frame.cmdFenceWaitable =
false;
1764 if (
frame.imageFence) {
1765 if (
frame.imageFenceWaitable)
1766 df->vkWaitForFences(
dev, 1, &
frame.imageFence, VK_TRUE, UINT64_MAX);
1767 df->vkDestroyFence(
dev,
frame.imageFence,
nullptr);
1768 frame.imageFence = VK_NULL_HANDLE;
1769 frame.imageFenceWaitable =
false;
1771 if (
frame.imageSem) {
1772 df->vkDestroySemaphore(
dev,
frame.imageSem,
nullptr);
1773 frame.imageSem = VK_NULL_HANDLE;
1775 if (
frame.drawSem) {
1776 df->vkDestroySemaphore(
dev,
frame.drawSem,
nullptr);
1777 frame.drawSem = VK_NULL_HANDLE;
1784 df->vkDestroyFramebuffer(
dev,
image.fb,
nullptr);
1785 image.fb = VK_NULL_HANDLE;
1787 if (
image.imageView) {
1788 df->vkDestroyImageView(
dev,
image.imageView,
nullptr);
1789 image.imageView = VK_NULL_HANDLE;
1791 if (
image.msaaImageView) {
1792 df->vkDestroyImageView(
dev,
image.msaaImageView,
nullptr);
1793 image.msaaImageView = VK_NULL_HANDLE;
1795 if (
image.msaaImage) {
1796 df->vkDestroyImage(
dev,
image.msaaImage,
nullptr);
1797 image.msaaImage = VK_NULL_HANDLE;
1807 swapChainD->
sc = VK_NULL_HANDLE;
1814 VkCommandPoolResetFlags
flags = 0;
1820 flags |= VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT;
1830 mask |= 0xFFULL <<
i;
1835 const float elapsedMs = float(ts1 - ts0) * nsecsPerTick / 1000000.0f;
1836 const double elapsedSec = elapsedMs / 1000.0;
1850 inst->handle()->beginFrame(swapChainD->
window);
1852 if (!
frame.imageAcquired) {
1855 if (
frame.imageFenceWaitable) {
1856 df->vkWaitForFences(
dev, 1, &
frame.imageFence, VK_TRUE, UINT64_MAX);
1857 df->vkResetFences(
dev, 1, &
frame.imageFence);
1858 frame.imageFenceWaitable =
false;
1862 uint32_t imageIndex = 0;
1864 frame.imageSem,
frame.imageFence, &imageIndex);
1865 if (err == VK_SUCCESS || err == VK_SUBOPTIMAL_KHR) {
1867 frame.imageSemWaitable =
true;
1868 frame.imageAcquired =
true;
1869 frame.imageFenceWaitable =
true;
1870 }
else if (err == VK_ERROR_OUT_OF_DATE_KHR) {
1873 if (err == VK_ERROR_DEVICE_LOST) {
1874 qWarning(
"Device loss detected in vkAcquireNextImageKHR()");
1878 qWarning(
"Failed to acquire next swapchain image: %d", err);
1916 if (
frame.timestampQueryIndex >= 0) {
1917 quint64 timestamp[2] = { 0, 0 };
1920 VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
1922 frame.timestampQueryIndex = -1;
1923 if (err == VK_SUCCESS) {
1929 qWarning(
"Failed to query timestamp: %d", err);
1935 int timestampQueryIdx = -1;
1939 timestampQueryIdx =
i * 2;
1943 if (timestampQueryIdx >= 0) {
1946 df->vkCmdWriteTimestamp(
frame.cmdBuf, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1948 frame.timestampQueryIndex = timestampQueryIdx;
1971 VkImageMemoryBarrier presTrans = {};
1972 presTrans.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1973 presTrans.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1974 presTrans.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
1975 presTrans.image =
image.image;
1976 presTrans.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1977 presTrans.subresourceRange.levelCount = presTrans.subresourceRange.layerCount = 1;
1981 presTrans.srcAccessMask = 0;
1982 presTrans.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1983 df->vkCmdPipelineBarrier(
frame.cmdBuf,
1984 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1985 0, 0,
nullptr, 0,
nullptr,
1989 presTrans.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1990 presTrans.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1991 df->vkCmdPipelineBarrier(
frame.cmdBuf,
1992 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1993 0, 0,
nullptr, 0,
nullptr,
2000 if (
frame.timestampQueryIndex >= 0) {
2001 df->vkCmdWriteTimestamp(
frame.cmdBuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2010 frame.imageSemWaitable ? &
frame.imageSem :
nullptr,
2011 needsPresent ? &
frame.drawSem :
nullptr);
2015 frame.imageSemWaitable =
false;
2016 frame.cmdFenceWaitable =
true;
2020 VkPresentInfoKHR presInfo = {};
2021 presInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
2022 presInfo.swapchainCount = 1;
2023 presInfo.pSwapchains = &swapChainD->
sc;
2025 presInfo.waitSemaphoreCount = 1;
2026 presInfo.pWaitSemaphores = &
frame.drawSem;
2030 inst->presentAboutToBeQueued(swapChainD->
window);
2033 if (err != VK_SUCCESS) {
2034 if (err == VK_ERROR_OUT_OF_DATE_KHR) {
2036 }
else if (err != VK_SUBOPTIMAL_KHR) {
2037 if (err == VK_ERROR_DEVICE_LOST) {
2038 qWarning(
"Device loss detected in vkQueuePresentKHR()");
2042 qWarning(
"Failed to present: %d", err);
2052 frame.imageAcquired =
false;
2088 VkCommandBufferAllocateInfo cmdBufInfo = {};
2089 cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2091 cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2092 cmdBufInfo.commandBufferCount = 1;
2094 VkResult err =
df->vkAllocateCommandBuffers(
dev, &cmdBufInfo,
cb);
2095 if (err != VK_SUCCESS) {
2096 if (err == VK_ERROR_DEVICE_LOST) {
2097 qWarning(
"Device loss detected in vkAllocateCommandBuffers()");
2101 qWarning(
"Failed to allocate frame command buffer: %d", err);
2106 VkCommandBufferBeginInfo cmdBufBeginInfo = {};
2107 cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2109 VkResult err =
df->vkBeginCommandBuffer(*
cb, &cmdBufBeginInfo);
2110 if (err != VK_SUCCESS) {
2111 if (err == VK_ERROR_DEVICE_LOST) {
2112 qWarning(
"Device loss detected in vkBeginCommandBuffer()");
2116 qWarning(
"Failed to begin frame command buffer: %d", err);
2124 VkSemaphore *waitSem, VkSemaphore *signalSem)
2126 VkResult err =
df->vkEndCommandBuffer(
cb);
2127 if (err != VK_SUCCESS) {
2128 if (err == VK_ERROR_DEVICE_LOST) {
2129 qWarning(
"Device loss detected in vkEndCommandBuffer()");
2133 qWarning(
"Failed to end frame command buffer: %d", err);
2137 VkSubmitInfo submitInfo = {};
2138 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2139 submitInfo.commandBufferCount = 1;
2140 submitInfo.pCommandBuffers = &
cb;
2142 submitInfo.waitSemaphoreCount = 1;
2143 submitInfo.pWaitSemaphores = waitSem;
2146 submitInfo.signalSemaphoreCount = 1;
2147 submitInfo.pSignalSemaphores = signalSem;
2149 VkPipelineStageFlags psf = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
2150 submitInfo.pWaitDstStageMask = &psf;
2152 err =
df->vkQueueSubmit(
gfxQueue, 1, &submitInfo, cmdFence);
2153 if (err != VK_SUCCESS) {
2154 if (err == VK_ERROR_DEVICE_LOST) {
2155 qWarning(
"Device loss detected in vkQueueSubmit()");
2159 qWarning(
"Failed to submit to graphics queue: %d", err);
2169 const int frameResIndex = sc->bufferCount > 1 ? frameSlot : 0;
2171 if (
frame.cmdFenceWaitable) {
2172 df->vkWaitForFences(
dev, 1, &
frame.cmdFence, VK_TRUE, UINT64_MAX);
2174 frame.cmdFenceWaitable =
false;
2205 int timestampQueryIdx = -1;
2209 timestampQueryIdx =
i * 2;
2213 if (timestampQueryIdx >= 0) {
2216 df->vkCmdWriteTimestamp(cbWrapper->
cb, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2237 df->vkCmdWriteTimestamp(cbWrapper->
cb, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
2242 VkFenceCreateInfo fenceInfo = {};
2243 fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2245 if (err != VK_SUCCESS) {
2246 qWarning(
"Failed to create command buffer fence: %d", err);
2265 quint64 timestamp[2] = { 0, 0 };
2268 VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2271 if (err == VK_SUCCESS) {
2277 qWarning(
"Failed to query timestamp: %d", err);
2410 VkCommandBuffer secondaryCb;
2416 VkCommandBufferAllocateInfo cmdBufInfo = {};
2417 cmdBufInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2419 cmdBufInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
2420 cmdBufInfo.commandBufferCount = 1;
2422 VkResult err =
df->vkAllocateCommandBuffers(
dev, &cmdBufInfo, &secondaryCb);
2423 if (err != VK_SUCCESS) {
2424 qWarning(
"Failed to create secondary command buffer: %d", err);
2425 return VK_NULL_HANDLE;
2429 VkCommandBufferBeginInfo cmdBufBeginInfo = {};
2430 cmdBufBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2431 cmdBufBeginInfo.flags = rtD ? VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT : 0;
2432 VkCommandBufferInheritanceInfo cmdBufInheritInfo = {};
2433 cmdBufInheritInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
2434 cmdBufInheritInfo.subpass = 0;
2436 cmdBufInheritInfo.renderPass = rtD->
rp->
rp;
2437 cmdBufInheritInfo.framebuffer = rtD->
fb;
2439 cmdBufBeginInfo.pInheritanceInfo = &cmdBufInheritInfo;
2441 VkResult err =
df->vkBeginCommandBuffer(secondaryCb, &cmdBufBeginInfo);
2442 if (err != VK_SUCCESS) {
2443 qWarning(
"Failed to begin secondary command buffer: %d", err);
2444 return VK_NULL_HANDLE;
2452 VkResult err =
df->vkEndCommandBuffer(
cb);
2453 if (err != VK_SUCCESS)
2454 qWarning(
"Failed to end secondary command buffer: %d", err);
2463 e.secondaryCommandBuffer.cb =
cb;
2469 const QColor &colorClearValue,
2472 QRhiCommandBuffer::BeginPassFlags
flags)
2477 if (resourceUpdates)
2514 VkRenderPassBeginInfo rpBeginInfo = {};
2515 rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
2516 rpBeginInfo.renderPass = rtD->
rp->
rp;
2517 rpBeginInfo.framebuffer = rtD->
fb;
2518 rpBeginInfo.renderArea.extent.width = uint32_t(rtD->
pixelSize.
width());
2519 rpBeginInfo.renderArea.extent.height = uint32_t(rtD->
pixelSize.
height());
2524 cv.color = { { float(colorClearValue.
redF()), float(colorClearValue.
greenF()), float(colorClearValue.
blueF()),
2525 float(colorClearValue.
alphaF()) } };
2535 cv.color = { { float(colorClearValue.
redF()), float(colorClearValue.
greenF()), float(colorClearValue.
blueF()),
2536 float(colorClearValue.
alphaF()) } };
2539 rpBeginInfo.clearValueCount = uint32_t(cvs.
size());
2571 if (resourceUpdates)
2577 QRhiCommandBuffer::BeginPassFlags
flags)
2582 if (resourceUpdates)
2611 if (resourceUpdates)
2643 int loadTypeVal,
int storeTypeVal,
int loadStoreTypeVal)
2645 VkAccessFlags
access = 0;
2646 if (bindingType == loadTypeVal) {
2647 access = VK_ACCESS_SHADER_READ_BIT;
2649 access = VK_ACCESS_SHADER_WRITE_BIT;
2650 if (bindingType == loadStoreTypeVal)
2651 access |= VK_ACCESS_SHADER_READ_BIT;
2653 auto it = writtenResources->
find(resource);
2654 if (
it != writtenResources->
end())
2656 else if (bindingType == storeTypeVal || bindingType == loadStoreTypeVal)
2657 writtenResources->insert(resource, {
access,
true });
2674 accessAndIsNewFlag = { 0,
false };
2678 for (
int i = 0;
i < bindingCount; ++
i) {
2707 const int accessInThisDispatch =
it->first;
2708 const bool isNewInThisDispatch =
it->second;
2709 if (accessInThisDispatch && !isNewInThisDispatch) {
2712 VkImageMemoryBarrier barrier = {};
2713 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2714 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2716 barrier.subresourceRange.baseMipLevel = 0;
2717 barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
2718 barrier.subresourceRange.baseArrayLayer = 0;
2719 barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
2722 barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2723 barrier.dstAccessMask = accessInThisDispatch;
2724 barrier.image = texD->
image;
2725 imageBarriers.
append(barrier);
2728 VkBufferMemoryBarrier barrier = {};
2729 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
2730 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2731 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2732 barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
2733 barrier.dstAccessMask = accessInThisDispatch;
2735 barrier.size = VK_WHOLE_SIZE;
2736 bufferBarriers.
append(barrier);
2742 if (accessInThisDispatch == VK_ACCESS_SHADER_READ_BIT)
2751 if (!imageBarriers.
isEmpty()) {
2752 df->vkCmdPipelineBarrier(secondaryCb, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
2757 if (!bufferBarriers.
isEmpty()) {
2758 df->vkCmdPipelineBarrier(secondaryCb, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
2763 df->vkCmdDispatch(secondaryCb, uint32_t(
x), uint32_t(
y), uint32_t(
z));
2765 if (!imageBarriers.
isEmpty()) {
2774 if (!bufferBarriers.
isEmpty()) {
2793 VkShaderModuleCreateInfo shaderInfo = {};
2794 shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
2795 shaderInfo.codeSize = size_t(spirv.
size());
2797 VkShaderModule shaderModule;
2798 VkResult err =
df->vkCreateShaderModule(
dev, &shaderInfo,
nullptr, &shaderModule);
2799 if (err != VK_SUCCESS) {
2800 qWarning(
"Failed to create shader module: %d", err);
2801 return VK_NULL_HANDLE;
2803 return shaderModule;
2811 VkPipelineCacheCreateInfo pipelineCacheInfo = {};
2812 pipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
2813 pipelineCacheInfo.initialDataSize = initialDataSize;
2814 pipelineCacheInfo.pInitialData = initialData;
2815 VkResult err =
df->vkCreatePipelineCache(
dev, &pipelineCacheInfo,
nullptr, &
pipelineCache);
2816 if (err != VK_SUCCESS) {
2817 qWarning(
"Failed to create pipeline cache: %d", err);
2833 const bool updateAll = descSetIdx < 0;
2834 int frameSlot = updateAll ? 0 : descSetIdx;
2840 VkWriteDescriptorSet writeInfo = {};
2841 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2842 writeInfo.dstSet = srbD->
descSets[frameSlot];
2843 writeInfo.dstBinding = uint32_t(
b->binding);
2844 writeInfo.descriptorCount = 1;
2846 int bufferInfoIndex = -1;
2847 int imageInfoIndex = -1;
2852 writeInfo.descriptorType =
b->u.ubuf.hasDynamicOffset ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
2853 : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2858 VkDescriptorBufferInfo bufInfo;
2860 bufInfo.offset =
b->u.ubuf.offset;
2861 bufInfo.range =
b->u.ubuf.maybeSize ?
b->u.ubuf.maybeSize : bufD->
m_size;
2864 bufferInfoIndex = bufferInfos.
size();
2865 bufferInfos.
append(bufInfo);
2871 writeInfo.descriptorCount =
data->
count;
2872 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
2873 ArrayOfImageDesc imageInfo(
data->count);
2874 for (
int elem = 0; elem <
data->count; ++elem) {
2881 imageInfo[elem].sampler = samplerD->
sampler;
2882 imageInfo[elem].imageView = texD->
imageView;
2883 imageInfo[elem].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2886 imageInfoIndex = imageInfos.
size();
2887 imageInfos.
append(imageInfo);
2893 writeInfo.descriptorCount =
data->
count;
2894 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
2895 ArrayOfImageDesc imageInfo(
data->count);
2896 for (
int elem = 0; elem <
data->count; ++elem) {
2902 imageInfo[elem].sampler = VK_NULL_HANDLE;
2903 imageInfo[elem].imageView = texD->
imageView;
2904 imageInfo[elem].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2907 imageInfoIndex = imageInfos.
size();
2908 imageInfos.
append(imageInfo);
2914 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
2919 ArrayOfImageDesc imageInfo(1);
2920 imageInfo[0].sampler = samplerD->
sampler;
2921 imageInfo[0].imageView = VK_NULL_HANDLE;
2922 imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2923 imageInfoIndex = imageInfos.
size();
2924 imageInfos.
append(imageInfo);
2934 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
2937 ArrayOfImageDesc imageInfo(1);
2938 imageInfo[0].sampler = VK_NULL_HANDLE;
2939 imageInfo[0].imageView =
view;
2940 imageInfo[0].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2941 imageInfoIndex = imageInfos.
size();
2942 imageInfos.
append(imageInfo);
2951 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2954 VkDescriptorBufferInfo bufInfo;
2956 bufInfo.offset =
b->u.ubuf.offset;
2957 bufInfo.range =
b->u.ubuf.maybeSize ?
b->u.ubuf.maybeSize : bufD->
m_size;
2958 bufferInfoIndex = bufferInfos.
size();
2959 bufferInfos.
append(bufInfo);
2966 writeInfos.
append(writeInfo);
2967 infoIndices.
append({ bufferInfoIndex, imageInfoIndex });
2972 for (
int i = 0, writeInfoCount = writeInfos.
size();
i < writeInfoCount; ++
i) {
2973 const int bufferInfoIndex = infoIndices[
i].
first;
2974 const int imageInfoIndex = infoIndices[
i].second;
2975 if (bufferInfoIndex >= 0)
2976 writeInfos[
i].pBufferInfo = &bufferInfos[bufferInfoIndex];
2977 else if (imageInfoIndex >= 0)
2978 writeInfos[
i].pImageInfo = imageInfos[imageInfoIndex].
constData();
2981 df->vkUpdateDescriptorSets(
dev, uint32_t(writeInfos.
size()), writeInfos.
constData(), 0,
nullptr);
2986 return (
access & VK_ACCESS_SHADER_WRITE_BIT) != 0
2987 || (
access & VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) != 0
2988 || (
access & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) != 0
2989 || (
access & VK_ACCESS_TRANSFER_WRITE_BIT) != 0
2990 || (
access & VK_ACCESS_HOST_WRITE_BIT) != 0
2991 || (
access & VK_ACCESS_MEMORY_WRITE_BIT) != 0;
2995 VkAccessFlags
access, VkPipelineStageFlags stage)
3006 if (
s.access ==
access &&
s.stage == stage) {
3013 VkBufferMemoryBarrier bufMemBarrier = {};
3014 bufMemBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
3015 bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3016 bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3017 bufMemBarrier.srcAccessMask =
s.access;
3018 bufMemBarrier.dstAccessMask =
access;
3019 bufMemBarrier.buffer = bufD->
buffers[slot];
3020 bufMemBarrier.size = VK_WHOLE_SIZE;
3035 VkImageLayout
layout, VkAccessFlags
access, VkPipelineStageFlags stage)
3045 VkImageMemoryBarrier barrier = {};
3046 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
3048 barrier.subresourceRange.baseMipLevel = 0;
3049 barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
3050 barrier.subresourceRange.baseArrayLayer = 0;
3051 barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
3052 barrier.oldLayout =
s.layout;
3053 barrier.newLayout =
layout;
3054 barrier.srcAccessMask =
s.access;
3055 barrier.dstAccessMask =
access;
3056 barrier.image = texD->
image;
3058 VkPipelineStageFlags srcStage =
s.stage;
3061 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3080 VkImageMemoryBarrier barrier = {};
3081 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
3082 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
3083 barrier.subresourceRange.baseMipLevel = 0;
3084 barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
3085 barrier.subresourceRange.baseArrayLayer = 0;
3086 barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
3087 barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3088 barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
3089 barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3090 barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
3091 | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3092 barrier.image = rbD->
image;
3094 const VkPipelineStageFlags
stages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
3095 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
3107 VkImageLayout oldLayout, VkImageLayout newLayout,
3108 VkAccessFlags srcAccess, VkAccessFlags dstAccess,
3109 VkPipelineStageFlags srcStage, VkPipelineStageFlags dstStage,
3110 int startLayer,
int layerCount,
3111 int startLevel,
int levelCount)
3114 VkImageMemoryBarrier barrier = {};
3115 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
3116 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3117 barrier.subresourceRange.baseMipLevel = uint32_t(startLevel);
3118 barrier.subresourceRange.levelCount = uint32_t(levelCount);
3119 barrier.subresourceRange.baseArrayLayer = uint32_t(startLayer);
3120 barrier.subresourceRange.layerCount = uint32_t(layerCount);
3121 barrier.oldLayout = oldLayout;
3122 barrier.newLayout = newLayout;
3123 barrier.srcAccessMask = srcAccess;
3124 barrier.dstAccessMask = dstAccess;
3125 barrier.image =
image;
3138 VkDeviceSize
size = 0;
3141 if (imageSizeBytes > 0)
3148 size_t *curOfs,
void *mp,
3153 const void *
src =
nullptr;
3157 VkBufferImageCopy copyInfo = {};
3158 copyInfo.bufferOffset = *curOfs;
3159 copyInfo.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3160 copyInfo.imageSubresource.mipLevel = uint32_t(
level);
3161 copyInfo.imageSubresource.baseArrayLayer = is3D ? 0 : uint32_t(
layer);
3162 copyInfo.imageSubresource.layerCount = 1;
3163 copyInfo.imageExtent.depth = 1;
3165 copyInfo.imageOffset.z = uint32_t(
layer);
3167 copyInfo.imageOffset.y = uint32_t(
layer);
3172 if (!
image.isNull()) {
3173 copySizeBytes = imageSizeBytes =
image.sizeInBytes();
3180 copyInfo.bufferRowLength = uint32_t(
image.bytesPerLine() / bpc);
3186 if (
image.depth() == 32) {
3190 copyInfo.bufferOffset += VkDeviceSize(sy *
image.bytesPerLine() + sx * 4);
3197 copySizeBytes =
image.sizeInBytes();
3199 copyInfo.bufferRowLength = uint32_t(
image.bytesPerLine() / bpc);
3202 copyInfo.imageOffset.x = dp.
x();
3203 copyInfo.imageOffset.y = dp.
y();
3204 copyInfo.imageExtent.width = uint32_t(
size.width());
3205 copyInfo.imageExtent.height = uint32_t(
size.height());
3206 copyInfos->
append(copyInfo);
3208 copySizeBytes = imageSizeBytes = rawData.
size();
3212 const int subresh =
size.height();
3216 const int h =
size.height();
3224 copyInfo.imageExtent.width = uint32_t(dp.
x() +
w == subresw ?
w :
aligned(
w, blockDim.
width()));
3225 copyInfo.imageExtent.height = uint32_t(dp.
y() +
h == subresh ?
h :
aligned(
h, blockDim.
height()));
3226 copyInfos->
append(copyInfo);
3227 }
else if (!rawData.
isEmpty()) {
3228 copySizeBytes = imageSizeBytes = rawData.
size();
3235 copyInfo.bufferRowLength = subresDesc.
dataStride() / bytesPerPixel;
3239 copyInfo.imageOffset.x = dp.
x();
3240 copyInfo.imageOffset.y = dp.
y();
3241 copyInfo.imageExtent.width = uint32_t(
size.width());
3242 copyInfo.imageExtent.height = uint32_t(
size.height());
3243 copyInfos->
append(copyInfo);
3249 memcpy(
reinterpret_cast<char *
>(mp) + *curOfs,
src,
size_t(copySizeBytes));
3274 VkBufferCreateInfo bufferInfo = {};
3275 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3278 bufferInfo.size = bufD->
m_size;
3279 bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
3281 VmaAllocationCreateInfo allocInfo = {};
3282 allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
3287 if (err == VK_SUCCESS) {
3290 qWarning(
"Failed to create staging buffer of size %u: %d", bufD->
m_size, err);
3298 if (err != VK_SUCCESS) {
3299 qWarning(
"Failed to map buffer: %d", err);
3307 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3309 VkBufferCopy copyInfo = {};
3310 copyInfo.srcOffset = u.
offset;
3311 copyInfo.dstOffset = u.
offset;
3346 if (err == VK_SUCCESS) {
3365 VkBufferCreateInfo bufferInfo = {};
3366 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3367 bufferInfo.size = readback.
byteSize;
3368 bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3370 VmaAllocationCreateInfo allocInfo = {};
3371 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
3375 if (err == VK_SUCCESS) {
3378 qWarning(
"Failed to create readback buffer of size %u: %d", readback.
byteSize, err);
3382 trackedBufferBarrier(cbD, bufD, 0, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3384 VkBufferCopy copyInfo = {};
3385 copyInfo.srcOffset = u.
offset;
3406 VkDeviceSize stagingSize = 0;
3415 VkBufferCreateInfo bufferInfo = {};
3416 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3417 bufferInfo.size = stagingSize;
3418 bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
3420 VmaAllocationCreateInfo allocInfo = {};
3421 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
3426 if (err != VK_SUCCESS) {
3427 qWarning(
"Failed to create image staging buffer of size %d: %d",
int(stagingSize), err);
3437 if (err != VK_SUCCESS) {
3438 qWarning(
"Failed to map image data: %d", err);
3449 subresDesc, &curOfs, mp, ©Infos);
3457 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3485 qWarning(
"Texture copy with matching source and destination is not supported");
3493 VkImageCopy region = {};
3494 region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3496 region.srcSubresource.baseArrayLayer = srcIs3D ? 0 : uint32_t(u.
desc.
sourceLayer());
3497 region.srcSubresource.layerCount = 1;
3504 region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3507 region.dstSubresource.layerCount = 1;
3516 region.extent.
width = uint32_t(copySize.
width());
3517 region.extent.height = uint32_t(copySize.
height());
3518 region.extent.depth = 1;
3521 VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3523 VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3544 if (texD->
samples > VK_SAMPLE_COUNT_1_BIT) {
3545 qWarning(
"Multisample texture cannot be read back");
3556 qWarning(
"Swapchain does not support readback");
3570 VkBufferCreateInfo bufferInfo = {};
3571 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3572 bufferInfo.size = readback.
byteSize;
3573 bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3575 VmaAllocationCreateInfo allocInfo = {};
3576 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
3580 if (err == VK_SUCCESS) {
3583 qWarning(
"Failed to create readback buffer of size %u: %d", readback.
byteSize, err);
3588 VkBufferImageCopy copyDesc = {};
3589 copyDesc.bufferOffset = 0;
3590 copyDesc.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3591 copyDesc.imageSubresource.mipLevel = uint32_t(u.
rb.
level());
3592 copyDesc.imageSubresource.baseArrayLayer = is3D ? 0 : uint32_t(u.
rb.
layer());
3593 copyDesc.imageSubresource.layerCount = 1;
3595 copyDesc.imageOffset.z = u.
rb.
layer();
3596 copyDesc.imageExtent.width = uint32_t(readback.
pixelSize.
width());
3598 copyDesc.imageExtent.depth = 1;
3602 VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3615 qWarning(
"Attempted to read back undefined swapchain image content, "
3616 "results are undefined. (do a render pass first)");
3619 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3620 VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3621 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3647 origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
3656 origLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3657 origAccess, VK_ACCESS_TRANSFER_READ_BIT,
3658 origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
3663 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3664 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3665 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3671 origLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3672 origAccess, VK_ACCESS_TRANSFER_WRITE_BIT,
3673 origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
3677 VkImageBlit region = {};
3678 region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3679 region.srcSubresource.mipLevel = uint32_t(
level) - 1;
3680 region.srcSubresource.baseArrayLayer = uint32_t(
layer);
3681 region.srcSubresource.layerCount = 1;
3683 region.srcOffsets[1].x =
qMax(1,
w);
3684 region.srcOffsets[1].y =
qMax(1,
h);
3685 region.srcOffsets[1].z =
qMax(1,
depth);
3687 region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3688 region.dstSubresource.mipLevel = uint32_t(
level);
3689 region.dstSubresource.baseArrayLayer = uint32_t(
layer);
3690 region.dstSubresource.layerCount = 1;
3692 region.dstOffsets[1].x =
qMax(1,
w >> 1);
3693 region.dstOffsets[1].y =
qMax(1,
h >> 1);
3694 region.dstOffsets[1].z =
qMax(1,
depth >> 1);
3712 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, origLayout,
3713 VK_ACCESS_TRANSFER_READ_BIT, origAccess,
3714 VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
3718 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, origLayout,
3719 VK_ACCESS_TRANSFER_WRITE_BIT, origAccess,
3720 VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
3744 if (err != VK_SUCCESS) {
3745 qWarning(
"Failed to map buffer: %d", err);
3748 quint32 changeBegin = UINT32_MAX;
3751 memcpy(
static_cast<char *
>(
p) + u.offset, u.data.constData(), u.data.size());
3752 if (u.offset < changeBegin)
3753 changeBegin = u.offset;
3754 if (u.offset + u.data.size() > changeEnd)
3755 changeEnd = u.offset + u.data.size();
3757 if (changeBegin < UINT32_MAX && changeBegin < changeEnd)
3774 df->vkDestroyImageView(dev,
e.renderBuffer.imageView,
nullptr);
3775 df->vkDestroyImage(dev,
e.renderBuffer.image,
nullptr);
3776 df->vkFreeMemory(dev,
e.renderBuffer.memory,
nullptr);
3781 df->vkDestroyImageView(dev,
e.texture.imageView,
nullptr);
3786 if (
e.texture.extraImageViews[
i])
3787 df->vkDestroyImageView(dev,
e.texture.extraImageViews[
i],
nullptr);
3793 df->vkDestroySampler(dev,
e.sampler.sampler,
nullptr);
3800 if (forced ||
currentFrameSlot ==
e.lastActiveFrameSlot ||
e.lastActiveFrameSlot < 0) {
3803 df->vkDestroyPipeline(
dev,
e.pipelineState.pipeline,
nullptr);
3804 df->vkDestroyPipelineLayout(
dev,
e.pipelineState.layout,
nullptr);
3807 df->vkDestroyDescriptorSetLayout(
dev,
e.shaderResourceBindings.layout,
nullptr);
3808 if (
e.shaderResourceBindings.poolIndex >= 0) {
3826 df->vkDestroyFramebuffer(
dev,
e.textureRenderTarget.fb,
nullptr);
3828 df->vkDestroyImageView(
dev,
e.textureRenderTarget.rtv[att],
nullptr);
3829 df->vkDestroyImageView(
dev,
e.textureRenderTarget.resrtv[att],
nullptr);
3833 df->vkDestroyRenderPass(
dev,
e.renderPass.rp,
nullptr);
3862 if (err == VK_SUCCESS &&
p) {
3867 qWarning(
"Failed to map texture readback buffer of size %u: %d", readback.
byteSize, err);
3885 if (err == VK_SUCCESS &&
p) {
3890 qWarning(
"Failed to map buffer readback buffer of size %d: %d", readback.
byteSize, err);
3902 for (
auto f : completedCallbacks)
3911 { VK_SAMPLE_COUNT_1_BIT, 1 },
3912 { VK_SAMPLE_COUNT_2_BIT, 2 },
3913 { VK_SAMPLE_COUNT_4_BIT, 4 },
3914 { VK_SAMPLE_COUNT_8_BIT, 8 },
3915 { VK_SAMPLE_COUNT_16_BIT, 16 },
3916 { VK_SAMPLE_COUNT_32_BIT, 32 },
3917 { VK_SAMPLE_COUNT_64_BIT, 64 }
3923 VkSampleCountFlags
color = limits->framebufferColorSampleCounts;
3924 VkSampleCountFlags
depth = limits->framebufferDepthSampleCounts;
3925 VkSampleCountFlags
stencil = limits->framebufferStencilSampleCounts;
3929 if ((
color & qvk_sampleCount.mask)
3930 && (
depth & qvk_sampleCount.mask)
3931 && (
stencil & qvk_sampleCount.mask))
3933 result.append(qvk_sampleCount.count);
3943 sampleCount =
qBound(1, sampleCount, 64);
3946 qWarning(
"Attempted to set unsupported sample count %d", sampleCount);
3947 return VK_SAMPLE_COUNT_1_BIT;
3951 if (qvk_sampleCount.count == sampleCount)
3952 return qvk_sampleCount.mask;
3955 Q_UNREACHABLE_RETURN(VK_SAMPLE_COUNT_1_BIT);
3997 0, 0,
nullptr, 0,
nullptr,
4016 : VK_SUBPASS_CONTENTS_INLINE);
4019 df->vkCmdEndRenderPass(cbD->
cb);
4026 const uint32_t *
offsets =
nullptr;
4068#ifdef VK_EXT_debug_utils
4075#ifdef VK_EXT_debug_utils
4076 vkCmdEndDebugUtilsLabelEXT(cbD->
cb);
4080#ifdef VK_EXT_debug_utils
4105 return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
4107 return VK_ACCESS_INDEX_READ_BIT;
4109 return VK_ACCESS_UNIFORM_READ_BIT;
4111 return VK_ACCESS_SHADER_READ_BIT;
4113 return VK_ACCESS_SHADER_WRITE_BIT;
4115 return VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
4127 return VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
4129 return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
4131 return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
4133 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
4135 return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
4137 return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
4139 return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
4159 return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4161 return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4163 return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
4167 return VK_IMAGE_LAYOUT_GENERAL;
4172 return VK_IMAGE_LAYOUT_GENERAL;
4179 return VK_ACCESS_SHADER_READ_BIT;
4181 return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
4183 return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
4185 return VK_ACCESS_SHADER_READ_BIT;
4187 return VK_ACCESS_SHADER_WRITE_BIT;
4189 return VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
4201 return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
4203 return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
4205 return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
4207 return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
4209 return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
4211 return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
4213 return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
4215 return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
4241 if (u.
access == newAccess && u.
stage == newStage) {
4281 if (
s.access ==
access &&
s.stage == stage) {
4285 VkBufferMemoryBarrier bufMemBarrier = {};
4286 bufMemBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
4287 bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4288 bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4289 bufMemBarrier.srcAccessMask =
s.access;
4290 bufMemBarrier.dstAccessMask =
access;
4291 bufMemBarrier.buffer = bufD->
buffers[
it->slot];
4292 bufMemBarrier.size = VK_WHOLE_SIZE;
4293 df->vkCmdPipelineBarrier(cbD->
cb,
s.stage, stage, 0,
4309 VkImageMemoryBarrier barrier = {};
4310 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4312 barrier.subresourceRange.baseMipLevel = 0;
4313 barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
4314 barrier.subresourceRange.baseArrayLayer = 0;
4315 barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
4316 barrier.oldLayout =
s.layout;
4317 barrier.newLayout =
layout;
4318 barrier.srcAccessMask =
s.access;
4319 barrier.dstAccessMask =
access;
4320 barrier.image = texD->
image;
4321 VkPipelineStageFlags srcStage =
s.stage;
4324 srcStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
4325 df->vkCmdPipelineBarrier(cbD->
cb, srcStage, stage, 0,
4338 qWarning(
"Physical device surface queries not available");
4375 if (
m.isIdentity()) {
4378 0.0f, -1.0f, 0.0f, 0.0f,
4379 0.0f, 0.0f, 0.5f, 0.5f,
4380 0.0f, 0.0f, 0.0f, 1.0f);
4406 VkFormatProperties
props;
4407 f->vkGetPhysicalDeviceFormatProperties(
physDev, vkformat, &
props);
4408 return (
props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0;
4419 return caps.debugUtils;
4425 return caps.vertexAttribDivisor;
4439 return caps.compute;
4441 return caps.wideLines;
4473 return caps.texture3DSliceAs2D;
4477 return caps.tessellation;
4479 return caps.geometryShader;
4483 return caps.nonFillPolygonMode;
4495 return caps.multiView;
4497 Q_UNREACHABLE_RETURN(
false);
4529 return int(qMin<uint32_t>(INT_MAX,
physDevProperties.limits.maxUniformBufferRange));
4535 Q_UNREACHABLE_RETURN(0);
4554 VmaBudget budgets[VK_MAX_MEMORY_HEAPS];
4558 for (uint32_t
i = 0;
i <
count; ++
i) {
4559 const VmaStatistics &stats(budgets[
i].
statistics);
4560 result.blockCount += stats.blockCount;
4561 result.allocCount += stats.allocationCount;
4562 result.usedBytes += stats.allocationBytes;
4563 result.unusedBytes += stats.blockBytes - stats.allocationBytes;
4607 if (err != VK_SUCCESS) {
4608 qCDebug(QRHI_LOG_INFO,
"Failed to get pipeline cache data size: %d", err);
4612 const size_t dataOffset =
headerSize + VK_UUID_SIZE;
4615 if (err != VK_SUCCESS) {
4616 qCDebug(QRHI_LOG_INFO,
"Failed to get pipeline cache data of %d bytes: %d",
int(
dataSize), err);
4627 header.uuidSize = VK_UUID_SIZE;
4641 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Invalid blob size");
4648 if (
header.rhiId != rhiId) {
4649 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: The data is for a different QRhi version or backend (%u, %u)",
4654 if (
header.arch != arch) {
4655 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Architecture does not match (%u, %u)",
4660 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: driverVersion does not match (%u, %u)",
4665 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: vendorID does not match (%u, %u)",
4670 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: deviceID does not match (%u, %u)",
4674 if (
header.uuidSize != VK_UUID_SIZE) {
4675 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: VK_UUID_SIZE does not match (%u, %u)",
4681 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Invalid blob, no uuid");
4685 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: pipelineCacheUUID does not match");
4689 const size_t dataOffset =
headerSize + VK_UUID_SIZE;
4691 qCDebug(QRHI_LOG_INFO,
"setPipelineCacheData: Invalid blob, data missing");
4701 qCDebug(QRHI_LOG_INFO,
"Created pipeline cache with initial data of %d bytes",
4704 qCDebug(QRHI_LOG_INFO,
"Failed to create pipeline cache with initial data specified");
4709 int sampleCount, QRhiRenderBuffer::Flags
flags,
4716 const QSize &pixelSize,
int depth,
int arraySize,
4717 int sampleCount, QRhiTexture::Flags
flags)
4726 return new QVkSampler(
this, magFilter, minFilter, mipmapMode, u,
v,
w);
4730 QRhiTextureRenderTarget::Flags
flags)
4776 int dynamicOffsetCount,
4795 bool rewriteDescSet =
false;
4821 rewriteDescSet =
true;
4834 rewriteDescSet =
true;
4836 for (
int elem = 0; elem <
data->count; ++elem) {
4853 const quint64 samplerId = samplerD ? samplerD->
m_id : 0;
4860 rewriteDescSet =
true;
4888 rewriteDescSet =
true;
4917 rewriteDescSet =
true;
4950 for (
int i = 0;
i < dynamicOffsetCount; ++
i) {
4952 if (bindingOffsetPair.first ==
b->binding) {
4953 offset = bindingOffsetPair.second;
4964 gfxPsD ? VK_PIPELINE_BIND_POINT_GRAPHICS : VK_PIPELINE_BIND_POINT_COMPUTE,
4967 uint32_t(dynOfs.
size()),
4973 : VK_PIPELINE_BIND_POINT_COMPUTE;
5003 bool needsBindVBuf =
false;
5004 for (
int i = 0;
i < bindingCount; ++
i) {
5005 const int inputSlot = startBinding +
i;
5016 needsBindVBuf =
true;
5022 if (needsBindVBuf) {
5025 for (
int i = 0;
i < bindingCount; ++
i) {
5029 ofs.
append(bindings[
i].second);
5058 const VkBuffer vkindexbuf = ibufD->
buffers[slot];
5060 : VK_INDEX_TYPE_UINT32;
5095 if (!qrhi_toTopLeftRenderTargetRect<UnBounded>(outputSize,
viewport.viewport(), &
x, &
y, &
w, &
h))
5104 vp->minDepth =
viewport.minDepth();
5105 vp->maxDepth =
viewport.maxDepth();
5119 qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize,
viewport.viewport(), &
x, &
y, &
w, &
h);
5120 s->offset.x = int32_t(
x);
5121 s->offset.y = int32_t(
y);
5122 s->extent.width = uint32_t(
w);
5123 s->extent.height = uint32_t(
h);
5142 if (!qrhi_toTopLeftRenderTargetRect<Bounded>(outputSize, scissor.
scissor(), &
x, &
y, &
w, &
h))
5149 s->extent.width = uint32_t(
w);
5150 s->extent.height = uint32_t(
h);
5166 float constants[] = { float(
c.redF()), float(
c.greenF()), float(
c.blueF()), float(
c.alphaF()) };
5218 firstIndex, vertexOffset, firstInstance);
5232#ifdef VK_EXT_debug_utils
5236 VkDebugUtilsLabelEXT
label = {};
5237 label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
5258#ifdef VK_EXT_debug_utils
5276#ifdef VK_EXT_debug_utils
5280 VkDebugUtilsLabelEXT
label = {};
5281 label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
5346 qWarning(
"beginExternal() within a pass is only supported with secondary command buffers. "
5347 "This can be enabled by passing QRhiCommandBuffer::ExternalContent to beginPass().");
5386#ifdef VK_EXT_debug_utils
5390 VkDebugUtilsObjectNameInfoEXT nameInfo = {};
5391 nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
5392 nameInfo.objectType =
type;
5393 nameInfo.objectHandle =
object;
5396 decoratedName +=
'/';
5399 nameInfo.pObjectName = decoratedName.
constData();
5400 vkSetDebugUtilsObjectNameEXT(
dev, &nameInfo);
5413 u |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
5415 u |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
5417 u |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
5419 u |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
5420 return VkBufferUsageFlagBits(u);
5427 return VK_FILTER_NEAREST;
5429 return VK_FILTER_LINEAR;
5431 Q_UNREACHABLE_RETURN(VK_FILTER_NEAREST);
5439 return VK_SAMPLER_MIPMAP_MODE_NEAREST;
5441 return VK_SAMPLER_MIPMAP_MODE_NEAREST;
5443 return VK_SAMPLER_MIPMAP_MODE_LINEAR;
5445 Q_UNREACHABLE_RETURN(VK_SAMPLER_MIPMAP_MODE_NEAREST);
5453 return VK_SAMPLER_ADDRESS_MODE_REPEAT;
5455 return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
5457 return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
5459 Q_UNREACHABLE_RETURN(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
5467 return VK_SHADER_STAGE_VERTEX_BIT;
5469 return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
5471 return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
5473 return VK_SHADER_STAGE_FRAGMENT_BIT;
5475 return VK_SHADER_STAGE_COMPUTE_BIT;
5477 return VK_SHADER_STAGE_GEOMETRY_BIT;
5479 Q_UNREACHABLE_RETURN(VK_SHADER_STAGE_VERTEX_BIT);
5487 return VK_FORMAT_R32G32B32A32_SFLOAT;
5489 return VK_FORMAT_R32G32B32_SFLOAT;
5491 return VK_FORMAT_R32G32_SFLOAT;
5493 return VK_FORMAT_R32_SFLOAT;
5495 return VK_FORMAT_R8G8B8A8_UNORM;
5497 return VK_FORMAT_R8G8_UNORM;
5499 return VK_FORMAT_R8_UNORM;
5501 return VK_FORMAT_R32G32B32A32_UINT;
5503 return VK_FORMAT_R32G32B32_UINT;
5505 return VK_FORMAT_R32G32_UINT;
5507 return VK_FORMAT_R32_UINT;
5509 return VK_FORMAT_R32G32B32A32_SINT;
5511 return VK_FORMAT_R32G32B32_SINT;
5513 return VK_FORMAT_R32G32_SINT;
5515 return VK_FORMAT_R32_SINT;
5517 return VK_FORMAT_R16G16B16A16_SFLOAT;
5519 return VK_FORMAT_R16G16B16_SFLOAT;
5521 return VK_FORMAT_R16G16_SFLOAT;
5523 return VK_FORMAT_R16_SFLOAT;
5525 Q_UNREACHABLE_RETURN(VK_FORMAT_R32G32B32A32_SFLOAT);
5533 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
5535 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
5537 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
5539 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
5541 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
5543 return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
5545 return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
5547 Q_UNREACHABLE_RETURN(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
5555 return VK_CULL_MODE_NONE;
5557 return VK_CULL_MODE_FRONT_BIT;
5559 return VK_CULL_MODE_BACK_BIT;
5561 Q_UNREACHABLE_RETURN(VK_CULL_MODE_NONE);
5569 return VK_FRONT_FACE_COUNTER_CLOCKWISE;
5571 return VK_FRONT_FACE_CLOCKWISE;
5573 Q_UNREACHABLE_RETURN(VK_FRONT_FACE_COUNTER_CLOCKWISE);
5581 f |= VK_COLOR_COMPONENT_R_BIT;
5583 f |= VK_COLOR_COMPONENT_G_BIT;
5585 f |= VK_COLOR_COMPONENT_B_BIT;
5587 f |= VK_COLOR_COMPONENT_A_BIT;
5588 return VkColorComponentFlags(
f);
5595 return VK_BLEND_FACTOR_ZERO;
5597 return VK_BLEND_FACTOR_ONE;
5599 return VK_BLEND_FACTOR_SRC_COLOR;
5601 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
5603 return VK_BLEND_FACTOR_DST_COLOR;
5605 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
5607 return VK_BLEND_FACTOR_SRC_ALPHA;
5609 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
5611 return VK_BLEND_FACTOR_DST_ALPHA;
5613 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
5615 return VK_BLEND_FACTOR_CONSTANT_COLOR;
5617 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
5619 return VK_BLEND_FACTOR_CONSTANT_ALPHA;
5621 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
5623 return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
5625 return VK_BLEND_FACTOR_SRC1_COLOR;
5627 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
5629 return VK_BLEND_FACTOR_SRC1_ALPHA;
5631 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
5633 Q_UNREACHABLE_RETURN(VK_BLEND_FACTOR_ZERO);
5641 return VK_BLEND_OP_ADD;
5643 return VK_BLEND_OP_SUBTRACT;
5645 return VK_BLEND_OP_REVERSE_SUBTRACT;
5647 return VK_BLEND_OP_MIN;
5649 return VK_BLEND_OP_MAX;
5651 Q_UNREACHABLE_RETURN(VK_BLEND_OP_ADD);
5659 return VK_COMPARE_OP_NEVER;
5661 return VK_COMPARE_OP_LESS;
5663 return VK_COMPARE_OP_EQUAL;
5665 return VK_COMPARE_OP_LESS_OR_EQUAL;
5667 return VK_COMPARE_OP_GREATER;
5669 return VK_COMPARE_OP_NOT_EQUAL;
5671 return VK_COMPARE_OP_GREATER_OR_EQUAL;
5673 return VK_COMPARE_OP_ALWAYS;
5675 Q_UNREACHABLE_RETURN(VK_COMPARE_OP_ALWAYS);
5683 return VK_STENCIL_OP_ZERO;
5685 return VK_STENCIL_OP_KEEP;
5687 return VK_STENCIL_OP_REPLACE;
5689 return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
5691 return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
5693 return VK_STENCIL_OP_INVERT;
5695 return VK_STENCIL_OP_INCREMENT_AND_WRAP;
5697 return VK_STENCIL_OP_DECREMENT_AND_WRAP;
5699 Q_UNREACHABLE_RETURN(VK_STENCIL_OP_KEEP);
5707 return VK_POLYGON_MODE_FILL;
5709 return VK_POLYGON_MODE_LINE;
5711 Q_UNREACHABLE_RETURN(VK_POLYGON_MODE_FILL);
5727 return b->u.ubuf.hasDynamicOffset ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
5728 : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
5731 return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
5734 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
5737 return VK_DESCRIPTOR_TYPE_SAMPLER;
5742 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
5747 return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
5750 Q_UNREACHABLE_RETURN(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
5758 s |= VK_SHADER_STAGE_VERTEX_BIT;
5760 s |= VK_SHADER_STAGE_FRAGMENT_BIT;
5762 s |= VK_SHADER_STAGE_COMPUTE_BIT;
5764 s |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
5766 s |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
5768 s |= VK_SHADER_STAGE_GEOMETRY_BIT;
5769 return VkShaderStageFlags(
s);
5776 return VK_COMPARE_OP_NEVER;
5778 return VK_COMPARE_OP_LESS;
5780 return VK_COMPARE_OP_EQUAL;
5782 return VK_COMPARE_OP_LESS_OR_EQUAL;
5784 return VK_COMPARE_OP_GREATER;
5786 return VK_COMPARE_OP_NOT_EQUAL;
5788 return VK_COMPARE_OP_GREATER_OR_EQUAL;
5790 return VK_COMPARE_OP_ALWAYS;
5792 Q_UNREACHABLE_RETURN(VK_COMPARE_OP_NEVER);
5837 rhiD->releaseQueue.append(
e);
5838 rhiD->unregisterResource(
this);
5848 qWarning(
"StorageBuffer cannot be combined with Dynamic");
5854 VkBufferCreateInfo bufferInfo = {};
5855 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5856 bufferInfo.size = nonZeroSize;
5859 VmaAllocationCreateInfo allocInfo = {};
5866 allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
5869 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
5871 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
5872 bufferInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
5876 VkResult err = VK_SUCCESS;
5884 if (err != VK_SUCCESS)
5892 if (err != VK_SUCCESS) {
5893 qWarning(
"Failed to create buffer: %d", err);
5899 rhiD->registerResource(
this);
5910 rhiD->executeBufferHostWritesForSlot(
this,
i);
5916 return { { &
buffers[0] }, 1 };
5929 const int slot = rhiD->currentFrameSlot;
5933 if (err != VK_SUCCESS) {
5934 qWarning(
"Failed to map buffer: %d", err);
5937 return static_cast<char *
>(
p);
5943 const int slot = rhiD->currentFrameSlot;
5971 e.renderBuffer.memory =
memory;
5972 e.renderBuffer.image =
image;
5976 image = VK_NULL_HANDLE;
5987 rhiD->releaseQueue.append(
e);
5988 rhiD->unregisterResource(
this);
6024 vkformat = rhiD->optimalDepthStencilFormat();
6025 if (!rhiD->createTransientImage(
vkformat,
6027 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
6028 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
6046 rhiD->registerResource(
this);
6084 e.texture.image =
owns ?
image : VK_NULL_HANDLE;
6101 image = VK_NULL_HANDLE;
6107 rhiD->releaseQueue.append(
e);
6108 rhiD->unregisterResource(
this);
6119 VkFormatProperties
props;
6120 rhiD->f->vkGetPhysicalDeviceFormatProperties(rhiD->physDev,
vkformat, &
props);
6121 const bool canSampleOptimal = (
props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
6122 if (!canSampleOptimal) {
6123 qWarning(
"Texture sampling with optimal tiling for format %d not supported",
vkformat);
6143 if (
samples > VK_SAMPLE_COUNT_1_BIT) {
6145 qWarning(
"Cubemap texture cannot be multisample");
6149 qWarning(
"3D texture cannot be multisample");
6153 qWarning(
"Multisample texture cannot have mipmaps");
6157 if (isCube && is3D) {
6158 qWarning(
"Texture cannot be both cube and 3D");
6161 if (isArray && is3D) {
6162 qWarning(
"Texture cannot be both array and 3D");
6165 if (isCube && is1D) {
6166 qWarning(
"Texture cannot be both cube and 1D");
6170 qWarning(
"Texture cannot be both 1D and 3D");
6174 qWarning(
"Texture cannot have a depth of %d when it is not 3D",
m_depth);
6191 *adjustedSize =
size;
6206 VkImageViewCreateInfo viewInfo = {};
6207 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6208 viewInfo.image =
image;
6209 viewInfo.viewType = isCube
6210 ? VK_IMAGE_VIEW_TYPE_CUBE
6211 : (is3D ? VK_IMAGE_VIEW_TYPE_3D
6212 : (is1D ? (isArray ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D)
6213 : (isArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D)));
6215 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
6216 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
6217 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
6218 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
6219 viewInfo.subresourceRange.aspectMask = aspectMask;
6225 viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ?
qMax(0,
m_arraySize) : 1);
6228 VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo,
nullptr, &
imageView);
6229 if (err != VK_SUCCESS) {
6230 qWarning(
"Failed to create image view: %d", err);
6254 VkImageCreateInfo imageInfo = {};
6255 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
6256 imageInfo.flags = 0;
6258 imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
6260 if (is3D && isRenderTarget) {
6266 if (!rhiD->caps.texture3DSliceAs2D)
6267 qWarning(
"QRhiVulkan: Rendering to 3D texture slice may not be functional without API 1.1 on the VkInstance");
6268#ifdef VK_VERSION_1_1
6269 imageInfo.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
6271 imageInfo.flags |= 0x00000020;
6275 imageInfo.imageType = is1D ? VK_IMAGE_TYPE_1D : is3D ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
6277 imageInfo.extent.width = uint32_t(
size.width());
6278 imageInfo.extent.height = uint32_t(
size.height());
6279 imageInfo.extent.depth = is3D ?
qMax(1,
m_depth) : 1;
6281 imageInfo.arrayLayers = isCube ? 6 : (isArray ?
qMax(0,
m_arraySize) : 1);
6283 imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
6284 imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
6286 imageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
6287 if (isRenderTarget) {
6289 imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
6291 imageInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
6294 imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
6296 imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
6298 imageInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
6300 VmaAllocationCreateInfo allocInfo = {};
6301 allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
6305 if (err != VK_SUCCESS) {
6306 qWarning(
"Failed to create image: %d", err);
6317 rhiD->registerResource(
this);
6323 VkImage
img = VkImage(
src.object);
6339 rhiD->registerResource(
this);
6365 VkImageViewCreateInfo viewInfo = {};
6366 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6367 viewInfo.image =
image;
6368 viewInfo.viewType = isCube
6369 ? VK_IMAGE_VIEW_TYPE_CUBE
6370 : (is3D ? VK_IMAGE_VIEW_TYPE_3D
6371 : (is1D ? (isArray ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D)
6372 : (isArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D)));
6374 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
6375 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
6376 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
6377 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
6378 viewInfo.subresourceRange.aspectMask = aspectMask;
6379 viewInfo.subresourceRange.baseMipLevel = uint32_t(
level);
6380 viewInfo.subresourceRange.levelCount = 1;
6381 viewInfo.subresourceRange.baseArrayLayer = 0;
6382 viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ?
qMax(0,
m_arraySize) : 1);
6384 VkImageView
v = VK_NULL_HANDLE;
6386 VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo,
nullptr, &
v);
6387 if (err != VK_SUCCESS) {
6388 qWarning(
"Failed to create image view: %d", err);
6389 return VK_NULL_HANDLE;
6398 :
QRhiSampler(rhi, magFilter, minFilter, mipmapMode, u,
v,
w)
6421 rhiD->releaseQueue.append(
e);
6422 rhiD->unregisterResource(
this);
6431 VkSamplerCreateInfo samplerInfo = {};
6432 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
6439 samplerInfo.maxAnisotropy = 1.0f;
6445 VkResult err = rhiD->df->vkCreateSampler(rhiD->dev, &samplerInfo,
nullptr, &
sampler);
6446 if (err != VK_SUCCESS) {
6447 qWarning(
"Failed to create sampler: %d", err);
6453 rhiD->registerResource(
this);
6474 rp = VK_NULL_HANDLE;
6482 e.renderPass.rp =
rp;
6484 rp = VK_NULL_HANDLE;
6488 rhiD->releaseQueue.append(
e);
6489 rhiD->unregisterResource(
this);
6495 return a.format ==
b.format
6496 &&
a.samples ==
b.samples
6497 &&
a.loadOp ==
b.loadOp
6498 &&
a.storeOp ==
b.storeOp
6499 &&
a.stencilLoadOp ==
b.stencilLoadOp
6500 &&
a.stencilStoreOp ==
b.stencilStoreOp
6501 &&
a.initialLayout ==
b.initialLayout
6502 &&
a.finalLayout ==
b.finalLayout;
6527 const uint32_t attIdx =
colorRefs[
i].attachment;
6528 if (attIdx !=
o->colorRefs[
i].attachment)
6535 const uint32_t attIdx =
dsRef.attachment;
6536 if (attIdx !=
o->dsRef.attachment)
6544 if (attIdx !=
o->resolveRefs[
i].attachment)
6566 auto serializeAttachmentData = [
this, &
p](uint32_t attIdx) {
6567 const bool used = attIdx != VK_ATTACHMENT_UNUSED;
6568 const VkAttachmentDescription *
a = used ? &
attDescs[attIdx] :
nullptr;
6569 *
p++ = used ?
a->format : 0;
6570 *
p++ = used ?
a->samples : 0;
6571 *
p++ = used ?
a->loadOp : 0;
6572 *
p++ = used ?
a->storeOp : 0;
6573 *
p++ = used ?
a->stencilLoadOp : 0;
6574 *
p++ = used ?
a->stencilStoreOp : 0;
6575 *
p++ = used ?
a->initialLayout : 0;
6576 *
p++ = used ?
a->finalLayout : 0;
6580 const uint32_t attIdx =
colorRefs[
i].attachment;
6582 serializeAttachmentData(attIdx);
6586 const uint32_t attIdx =
dsRef.attachment;
6588 serializeAttachmentData(attIdx);
6594 serializeAttachmentData(attIdx);
6611 VkRenderPassCreateInfo rpInfo;
6612 VkSubpassDescription subpassDesc;
6622 VkResult err = rhiD->df->vkCreateRenderPass(rhiD->dev, &rpInfo,
nullptr, &rpD->
rp);
6623 if (err != VK_SUCCESS) {
6624 qWarning(
"Failed to create renderpass: %d", err);
6630 rhiD->registerResource(rpD);
6681 rtv[att] = VK_NULL_HANDLE;
6682 resrtv[att] = VK_NULL_HANDLE;
6700 e.textureRenderTarget.fb =
d.
fb;
6701 d.
fb = VK_NULL_HANDLE;
6704 e.textureRenderTarget.rtv[att] =
rtv[att];
6705 e.textureRenderTarget.resrtv[att] =
resrtv[att];
6706 rtv[att] = VK_NULL_HANDLE;
6707 resrtv[att] = VK_NULL_HANDLE;
6712 rhiD->releaseQueue.append(
e);
6713 rhiD->unregisterResource(
this);
6723 if (!rhiD->createOffscreenRenderPass(rp,
6737 rhiD->registerResource(rp);
6764 const bool isMultiView =
it->multiViewCount() >= 2;
6767 VkImageViewCreateInfo viewInfo = {};
6768 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6769 viewInfo.image = texD->
image;
6770 viewInfo.viewType = is1D ? VK_IMAGE_VIEW_TYPE_1D
6771 : (isMultiView ? VK_IMAGE_VIEW_TYPE_2D_ARRAY
6772 : VK_IMAGE_VIEW_TYPE_2D);
6774 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
6775 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
6776 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
6777 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
6778 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
6779 viewInfo.subresourceRange.baseMipLevel = uint32_t(
it->level());
6780 viewInfo.subresourceRange.levelCount = 1;
6781 viewInfo.subresourceRange.baseArrayLayer = uint32_t(
it->layer());
6782 viewInfo.subresourceRange.layerCount = uint32_t(isMultiView ?
it->multiViewCount() : 1);
6783 VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo,
nullptr, &
rtv[attIndex]);
6784 if (err != VK_SUCCESS) {
6785 qWarning(
"Failed to create render target image view: %d", err);
6789 if (attIndex == 0) {
6796 if (attIndex == 0) {
6804 if (hasDepthStencil) {
6829 if (
it->resolveTexture()) {
6834 VkImageViewCreateInfo viewInfo = {};
6835 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
6836 viewInfo.image = resTexD->
image;
6838 : VK_IMAGE_VIEW_TYPE_2D;
6839 viewInfo.format = resTexD->
vkformat;
6840 viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
6841 viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
6842 viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
6843 viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
6844 viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
6845 viewInfo.subresourceRange.baseMipLevel = uint32_t(
it->resolveLevel());
6846 viewInfo.subresourceRange.levelCount = 1;
6847 viewInfo.subresourceRange.baseArrayLayer = uint32_t(
it->resolveLayer());
6848 viewInfo.subresourceRange.layerCount = qMax<uint32_t>(1,
d.
multiViewCount);
6849 VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo,
nullptr, &
resrtv[attIndex]);
6850 if (err != VK_SUCCESS) {
6851 qWarning(
"Failed to create render target resolve image view: %d", err);
6859 qWarning(
"QVkTextureRenderTarget: No renderpass descriptor set. See newCompatibleRenderPassDescriptor() and setRenderPassDescriptor().");
6864 VkFramebufferCreateInfo fbInfo = {};
6865 fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
6866 fbInfo.renderPass =
d.
rp->
rp;
6868 fbInfo.pAttachments = views.
constData();
6873 VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo,
nullptr, &
d.
fb);
6874 if (err != VK_SUCCESS) {
6875 qWarning(
"Failed to create framebuffer: %d", err);
6882 rhiD->registerResource(
this);
6925 e.shaderResourceBindings.poolIndex =
poolIndex;
6926 e.shaderResourceBindings.layout =
layout;
6935 rhiD->releaseQueue.append(
e);
6936 rhiD->unregisterResource(
this);
6946 if (!rhiD->sanityCheckShaderResourceBindings(
this))
6949 rhiD->updateLayoutDesc(
this);
6965 if (
b->u.ubuf.hasDynamicOffset)
6973 VkDescriptorSetLayoutBinding vkbinding = {};
6974 vkbinding.binding = uint32_t(
b->binding);
6977 vkbinding.descriptorCount =
b->u.stex.count;
6979 vkbinding.descriptorCount = 1;
6981 vkbindings.
append(vkbinding);
6984 VkDescriptorSetLayoutCreateInfo layoutInfo = {};
6985 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
6986 layoutInfo.bindingCount = uint32_t(vkbindings.
size());
6987 layoutInfo.pBindings = vkbindings.
constData();
6989 VkResult err = rhiD->df->vkCreateDescriptorSetLayout(rhiD->dev, &layoutInfo,
nullptr, &
layout);
6990 if (err != VK_SUCCESS) {
6991 qWarning(
"Failed to create descriptor set layout: %d", err);
6995 VkDescriptorSetAllocateInfo allocInfo = {};
6996 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
7001 allocInfo.pSetLayouts = layouts;
7013 rhiD->registerResource(
this);
7062 e.pipelineState.layout =
layout;
7069 rhiD->releaseQueue.append(
e);
7070 rhiD->unregisterResource(
this);
7080 rhiD->pipelineCreationStart();
7081 if (!rhiD->sanityCheckGraphicsPipeline(
this))
7084 if (!rhiD->ensurePipelineCache())
7087 VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
7088 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7089 pipelineLayoutInfo.setLayoutCount = 1;
7092 pipelineLayoutInfo.pSetLayouts = &srbD->
layout;
7093 VkResult err = rhiD->df->vkCreatePipelineLayout(rhiD->dev, &pipelineLayoutInfo,
nullptr, &
layout);
7094 if (err != VK_SUCCESS) {
7095 qWarning(
"Failed to create pipeline layout: %d", err);
7099 VkGraphicsPipelineCreateInfo pipelineInfo = {};
7100 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
7108 qWarning() <<
"No SPIR-V 1.0 shader code found in baked shader" << bakedShader;
7111 VkShaderModule
shader = rhiD->createShader(spirv.
shader());
7114 VkPipelineShaderStageCreateInfo shaderInfo = {};
7115 shaderInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
7117 shaderInfo.module =
shader;
7119 shaderStageCreateInfos.
append(shaderInfo);
7122 pipelineInfo.stageCount = uint32_t(shaderStageCreateInfos.
size());
7123 pipelineInfo.pStages = shaderStageCreateInfos.
constData();
7126#ifdef VK_EXT_vertex_attribute_divisor
7133 VkVertexInputBindingDescription bindingInfo = {
7137 ? VK_VERTEX_INPUT_RATE_VERTEX : VK_VERTEX_INPUT_RATE_INSTANCE
7140#ifdef VK_EXT_vertex_attribute_divisor
7141 if (rhiD->caps.vertexAttribDivisor) {
7146 qWarning(
"QRhiVulkan: Instance step rates other than 1 not supported without "
7147 "VK_EXT_vertex_attribute_divisor on the device and "
7148 "VK_KHR_get_physical_device_properties2 on the instance");
7151 vertexBindings.
append(bindingInfo);
7157 VkVertexInputAttributeDescription attributeInfo = {
7158 uint32_t(
it->location()),
7159 uint32_t(
it->binding()),
7163 vertexAttributes.
append(attributeInfo);
7165 VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
7166 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
7167 vertexInputInfo.vertexBindingDescriptionCount = uint32_t(vertexBindings.
size());
7168 vertexInputInfo.pVertexBindingDescriptions = vertexBindings.
constData();
7169 vertexInputInfo.vertexAttributeDescriptionCount = uint32_t(vertexAttributes.
size());
7170 vertexInputInfo.pVertexAttributeDescriptions = vertexAttributes.
constData();
7171#ifdef VK_EXT_vertex_attribute_divisor
7172 VkPipelineVertexInputDivisorStateCreateInfoEXT divisorInfo = {};
7173 if (!nonOneStepRates.
isEmpty()) {
7174 divisorInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
7175 divisorInfo.vertexBindingDivisorCount = uint32_t(nonOneStepRates.
size());
7176 divisorInfo.pVertexBindingDivisors = nonOneStepRates.
constData();
7177 vertexInputInfo.pNext = &divisorInfo;
7180 pipelineInfo.pVertexInputState = &vertexInputInfo;
7183 dynEnable << VK_DYNAMIC_STATE_VIEWPORT;
7184 dynEnable << VK_DYNAMIC_STATE_SCISSOR;
7186 dynEnable << VK_DYNAMIC_STATE_BLEND_CONSTANTS;
7188 dynEnable << VK_DYNAMIC_STATE_STENCIL_REFERENCE;
7190 VkPipelineDynamicStateCreateInfo dynamicInfo = {};
7191 dynamicInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
7192 dynamicInfo.dynamicStateCount = uint32_t(dynEnable.
size());
7193 dynamicInfo.pDynamicStates = dynEnable.
constData();
7194 pipelineInfo.pDynamicState = &dynamicInfo;
7196 VkPipelineViewportStateCreateInfo viewportInfo = {};
7197 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
7198 viewportInfo.viewportCount = viewportInfo.scissorCount = 1;
7199 pipelineInfo.pViewportState = &viewportInfo;
7201 VkPipelineInputAssemblyStateCreateInfo inputAsmInfo = {};
7202 inputAsmInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
7205 pipelineInfo.pInputAssemblyState = &inputAsmInfo;
7207 VkPipelineTessellationStateCreateInfo tessInfo = {};
7208#ifdef VK_VERSION_1_1
7209 VkPipelineTessellationDomainOriginStateCreateInfo originInfo = {};
7212 tessInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
7220#ifdef VK_VERSION_1_1
7222 originInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
7223 originInfo.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
7224 tessInfo.pNext = &originInfo;
7226 qWarning(
"Proper tessellation support requires Vulkan 1.1 or newer, leaving domain origin unset");
7229 qWarning(
"QRhi was built without Vulkan 1.1 headers, this is not sufficient for proper tessellation support");
7232 pipelineInfo.pTessellationState = &tessInfo;
7235 VkPipelineRasterizationStateCreateInfo rastInfo = {};
7236 rastInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
7240 rastInfo.depthBiasEnable =
true;
7241 rastInfo.depthBiasConstantFactor = float(
m_depthBias);
7244 rastInfo.lineWidth = rhiD->caps.wideLines ?
m_lineWidth : 1.0f;
7246 pipelineInfo.pRasterizationState = &rastInfo;
7248 VkPipelineMultisampleStateCreateInfo msInfo = {};
7249 msInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
7250 msInfo.rasterizationSamples = rhiD->effectiveSampleCount(
m_sampleCount);
7251 pipelineInfo.pMultisampleState = &msInfo;
7253 VkPipelineDepthStencilStateCreateInfo dsInfo = {};
7254 dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
7267 pipelineInfo.pDepthStencilState = &dsInfo;
7269 VkPipelineColorBlendStateCreateInfo blendInfo = {};
7270 blendInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
7273 VkPipelineColorBlendAttachmentState blend = {};
7274 blend.blendEnable =
b.enable;
7282 vktargetBlends.
append(blend);
7284 if (vktargetBlends.
isEmpty()) {
7285 VkPipelineColorBlendAttachmentState blend = {};
7286 blend.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
7287 | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
7288 vktargetBlends.
append(blend);
7290 blendInfo.attachmentCount = uint32_t(vktargetBlends.
size());
7291 blendInfo.pAttachments = vktargetBlends.
constData();
7292 pipelineInfo.pColorBlendState = &blendInfo;
7294 pipelineInfo.layout =
layout;
7299 err = rhiD->df->vkCreateGraphicsPipelines(rhiD->dev, rhiD->pipelineCache, 1, &pipelineInfo,
nullptr, &
pipeline);
7302 rhiD->df->vkDestroyShaderModule(rhiD->dev,
shader,
nullptr);
7304 if (err != VK_SUCCESS) {
7305 qWarning(
"Failed to create graphics pipeline: %d", err);
7309 rhiD->pipelineCreationEnd();
7312 rhiD->registerResource(
this);
7336 e.pipelineState.layout =
layout;
7343 rhiD->releaseQueue.append(
e);
7344 rhiD->unregisterResource(
this);
7354 rhiD->pipelineCreationStart();
7355 if (!rhiD->ensurePipelineCache())
7358 VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
7359 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
7360 pipelineLayoutInfo.setLayoutCount = 1;
7363 pipelineLayoutInfo.pSetLayouts = &srbD->
layout;
7364 VkResult err = rhiD->df->vkCreatePipelineLayout(rhiD->dev, &pipelineLayoutInfo,
nullptr, &
layout);
7365 if (err != VK_SUCCESS) {
7366 qWarning(
"Failed to create pipeline layout: %d", err);
7370 VkComputePipelineCreateInfo pipelineInfo = {};
7371 pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
7372 pipelineInfo.layout =
layout;
7375 qWarning(
"Compute pipeline requires a compute shader stage");
7381 qWarning() <<
"No SPIR-V 1.0 shader code found in baked shader" << bakedShader;
7385 qWarning() << bakedShader <<
"is not a compute shader";
7388 VkShaderModule
shader = rhiD->createShader(spirv.
shader());
7389 VkPipelineShaderStageCreateInfo shaderInfo = {};
7390 shaderInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
7391 shaderInfo.
stage = VK_SHADER_STAGE_COMPUTE_BIT;
7392 shaderInfo.module =
shader;
7394 pipelineInfo.stage = shaderInfo;
7396 err = rhiD->df->vkCreateComputePipelines(rhiD->dev, rhiD->pipelineCache, 1, &pipelineInfo,
nullptr, &
pipeline);
7397 rhiD->df->vkDestroyShaderModule(rhiD->dev,
shader,
nullptr);
7398 if (err != VK_SUCCESS) {
7399 qWarning(
"Failed to create graphics pipeline: %d", err);
7403 rhiD->pipelineCreationEnd();
7406 rhiD->registerResource(
this);
7448 rtWrapper(rhi,
this),
7460 if (
sc == VK_NULL_HANDLE)
7465 rhiD->swapchains.remove(
this);
7466 rhiD->releaseSwapChainResources(
this);
7471 frame.cmdBuf = VK_NULL_HANDLE;
7472 frame.timestampQueryIndex = -1;
7478 rhiD->unregisterResource(
this);
7498 VkSurfaceCapabilitiesKHR surfaceCaps = {};
7500 rhiD->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(rhiD->physDev,
surface, &surfaceCaps);
7501 VkExtent2D bufferSize = surfaceCaps.currentExtent;
7502 if (bufferSize.width == uint32_t(-1)) {
7503 Q_ASSERT(bufferSize.height == uint32_t(-1));
7506 return QSize(
int(bufferSize.width),
int(bufferSize.height));
7513 return s.format == VK_FORMAT_R16G16B16A16_SFLOAT
7514 &&
s.colorSpace == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT;
7516 return (
s.format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
s.format == VK_FORMAT_A2R10G10B10_UNORM_PACK32)
7517 &&
s.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT;
7530 qWarning(
"Attempted to call isFormatSupported() without a window set");
7535 VkSurfaceKHR surf = QVulkanInstance::surfaceForWindow(
m_window);
7538 uint32_t formatCount = 0;
7539 rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev, surf, &formatCount,
nullptr);
7542 rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev, surf, &formatCount,
formats.data());
7543 for (uint32_t
i = 0;
i < formatCount; ++
i) {
7561 if (!rhiD->createDefaultRenderPass(rp,
7572 rhiD->registerResource(rp);
7579 case VK_FORMAT_R8_SRGB:
7580 case VK_FORMAT_R8G8_SRGB:
7581 case VK_FORMAT_R8G8B8_SRGB:
7582 case VK_FORMAT_B8G8R8_SRGB:
7583 case VK_FORMAT_R8G8B8A8_SRGB:
7584 case VK_FORMAT_B8G8R8A8_SRGB:
7585 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
7600 VkSurfaceKHR surf = QVulkanInstance::surfaceForWindow(
m_window);
7602 qWarning(
"Failed to get surface for window");
7611 if (!rhiD->inst->supportsPresent(rhiD->physDev, rhiD->gfxQueueFamilyIdx,
m_window)) {
7612 qWarning(
"Presenting not supported on this window");
7617 rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev,
surface, &formatCount,
nullptr);
7620 rhiD->vkGetPhysicalDeviceSurfaceFormatsKHR(rhiD->physDev,
surface, &formatCount,
formats.data());
7624 const bool srgbRequested =
m_flags.testFlag(
sRGB);
7625 for (
int i = 0;
i < int(formatCount); ++
i) {
7641 rhiD->vkGetPhysicalDeviceSurfacePresentModesKHR(rhiD->physDev,
surface, &presModeCount,
nullptr);
7643 rhiD->vkGetPhysicalDeviceSurfacePresentModesKHR(rhiD->physDev,
surface, &presModeCount,
7666 if (!rhiD->recreateSwapChain(
this)) {
7667 qWarning(
"Failed to create new swapchain");
7671 if (needsRegistration)
7672 rhiD->swapchains.insert(
this);
7675 qWarning(
"Depth-stencil buffer's sampleCount (%d) does not match color buffers' sample count (%d). Expect problems.",
7682 qWarning(
"Failed to rebuild swapchain's associated depth-stencil buffer for size %dx%d",
7685 qWarning(
"Depth-stencil buffer's size (%dx%d) does not match the surface size (%dx%d). Expect problems.",
7692 qWarning(
"QVkSwapChain: No renderpass descriptor set. See newCompatibleRenderPassDescriptor() and setRenderPassDescriptor().");
7709 if (
samples > VK_SAMPLE_COUNT_1_BIT)
7716 VkImageView views[3] = {
7719 samples > VK_SAMPLE_COUNT_1_BIT ?
image.imageView : VK_NULL_HANDLE
7722 VkFramebufferCreateInfo fbInfo = {};
7723 fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
7726 fbInfo.pAttachments = views;
7731 VkResult err = rhiD->df->vkCreateFramebuffer(rhiD->dev, &fbInfo,
nullptr, &
image.fb);
7732 if (err != VK_SUCCESS) {
7733 qWarning(
"Failed to create framebuffer: %d", err);
7740 if (needsRegistration)
7741 rhiD->registerResource(
this);
IOBluetoothDevice * device
bool testBit(qsizetype i) const
Returns true if the bit at index position i is 1; otherwise returns false.
void setBit(qsizetype i)
Sets the bit at index position i to 1.
void clearBit(qsizetype i)
Sets the bit at index position i to 0.
qsizetype size() const
Returns the number of bits stored in the bit array.
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
The QColor class provides colors based on RGB, HSV or CMYK values.
float greenF() const noexcept
Returns the green color component of this color.
float redF() const noexcept
Returns the red color component of this color.
float alphaF() const noexcept
Returns the alpha color component of this color.
float blueF() const noexcept
Returns the blue color component of this color.
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
iterator erase(const_iterator it)
iterator end() noexcept
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the last ...
qsizetype sizeInBytes() const
bool isNull() const
Returns true if it is a null image, otherwise returns false.
qsizetype size() const noexcept
const_pointer constData() const noexcept
bool isEmpty() const noexcept
void resize(qsizetype size)
void append(parameter_type t)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
\inmodule QtCore\reentrant
constexpr bool isNull() const noexcept
Returns true if both the x and y coordinates are set to 0, otherwise returns false.
constexpr int x() const noexcept
Returns the x coordinate of this point.
constexpr int y() const noexcept
Returns the y coordinate of this point.
const char * constData() const
Type
Specifies storage type of buffer resource.
QPair< QRhiBuffer *, quint32 > VertexInput
Synonym for QPair<QRhiBuffer *, quint32>.
QPair< int, quint32 > DynamicOffset
Synonym for QPair<int, quint32>.
IndexFormat
Specifies the index data type.
QRhiShaderStage m_shaderStage
QRhiShaderResourceBindings * m_shaderResourceBindings
float depthClearValue() const
quint32 stencilClearValue() const
QRhiRenderPassDescriptor * m_renderPassDesc
quint32 m_stencilReadMask
BlendOp
Specifies the blend operation.
PolygonMode
Specifies the polygon rasterization mode.
FrontFace
Specifies the front face winding order.
BlendFactor
Specifies the blend factor.
StencilOpState m_stencilFront
quint32 m_stencilWriteMask
CompareOp
Specifies the depth or stencil comparison function.
CullMode
Specifies the culling mode.
QVarLengthArray< QRhiShaderStage, 4 > m_shaderStages
QRhiVertexInputLayout m_vertexInputLayout
QVarLengthArray< TargetBlend, 8 > m_targetBlends
QRhiShaderResourceBindings * m_shaderResourceBindings
PolygonMode m_polygonMode
float m_slopeScaledDepthBias
Topology
Specifies the primitive topology.
StencilOpState m_stencilBack
StencilOp
Specifies the stencil operation.
int m_patchControlPointCount
bool isCompressedFormat(QRhiTexture::Format format) const
static const QRhiShaderResourceBinding::Data * shaderResourceBindingData(const QRhiShaderResourceBinding &binding)
quint32 pipelineCacheRhiId() const
void compressedFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, QSize *blockDim) const
static bool sortedBindingLessThan(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
qint64 totalPipelineCreationTime() const
void textureFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, quint32 *bytesPerPixel) const
static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages)
TextureIterator cendTextures() const
static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages)
BufferIterator cbeginBuffers() const
BufferIterator cendBuffers() const
TextureIterator cbeginTextures() const
void registerBuffer(QRhiBuffer *buf, int slot, BufferAccess *access, BufferStage *stage, const UsageState &state)
void registerTexture(QRhiTexture *tex, TextureAccess *access, TextureStage *stage, const UsageState &state)
QRhiTexture * texture() const
void setPixelSize(const QSize &sz)
Sets the size (in pixels) to sz.
QRhiTexture::Format m_backingFormatHint
Type
Specifies the type of the renderbuffer.
virtual bool create()=0
Creates the corresponding native graphics resources.
void setRenderPassDescriptor(QRhiRenderPassDescriptor *desc)
Sets the QRhiRenderPassDescriptor desc for use with this render target.
virtual QSize pixelSize() const =0
QRhiRenderPassDescriptor * m_renderPassDesc
QVarLengthArray< BufferOp, BUFFER_OPS_STATIC_ALLOC > bufferOps
QVarLengthArray< TextureOp, TEXTURE_OPS_STATIC_ALLOC > textureOps
static QRhiResourceUpdateBatchPrivate * get(QRhiResourceUpdateBatch *b)
virtual Type resourceType() const =0
void setName(const QByteArray &name)
Sets a name for the object.
QRhiImplementation * m_rhi
Filter
Specifies the minification, magnification, or mipmap filtering.
AddressMode
Specifies the addressing mode.
CompareOp
Specifies the texture comparison function.
std::array< int, 4 > scissor() const
Type
Specifies type of the shader resource bound to a binding point.
@ TessellationEvaluationStage
@ TessellationControlStage
QVarLengthArray< QRhiShaderResourceBinding, BINDING_PREALLOC > m_bindings
QShader::Variant shaderVariant() const
Type
Specifies the type of the shader stage.
@ SurfaceHasNonPreMulAlpha
QRhiRenderPassDescriptor * m_renderPassDesc
Format
Describes the swapchain format.
QRhiRenderBuffer * m_depthStencil
QPoint destinationTopLeft() const
QPoint sourceTopLeft() const
int destinationLevel() const
int destinationLayer() const
const QRhiColorAttachment * cbeginColorAttachments() const
QRhiTexture * depthTexture() const
const QRhiColorAttachment * cendColorAttachments() const
QRhiRenderBuffer * depthStencilBuffer() const
qsizetype colorAttachmentCount() const
QRhiTextureRenderTargetDescription m_desc
@ PreserveDepthStencilContents
QRhiTextureRenderTargetDescription description() const
quint32 dataStride() const
QPoint sourceTopLeft() const
QPoint destinationTopLeft() const
Format
Specifies the texture format.
void setSampleCount(int s)
Sets the sample count to s.
void setPixelSize(const QSize &sz)
Sets the texture size, specified in pixels, to sz.
\variable QRhiVulkanInitParams::inst
QVarLengthArray< DescriptorPoolData, 8 > descriptorPools
void recordTransitionPassResources(QVkCommandBuffer *cbD, const QRhiPassResourceTracker &tracker)
quint32 gfxQueueFamilyIdx
VkCommandBuffer startSecondaryCommandBuffer(QVkRenderTargetData *rtD=nullptr)
QRhiSwapChain * createSwapChain() override
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR
void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override
int resourceLimit(QRhi::ResourceLimit limit) const override
bool isDeviceLost() const override
void prepareUploadSubres(QVkTexture *texD, int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc, size_t *curOfs, void *mp, BufferImageCopyList *copyInfos)
VkPhysicalDeviceProperties physDevProperties
void executeDeferredReleases(bool forced=false)
uint32_t chooseTransientImageMemType(VkImage img, uint32_t startIndex)
QRhi::FrameOpResult finish() override
quint32 timestampValidBits
QRhiTextureRenderTarget * createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags) override
bool createTransientImage(VkFormat format, const QSize &pixelSize, VkImageUsageFlags usage, VkImageAspectFlags aspectMask, VkSampleCountFlagBits samples, VkDeviceMemory *mem, VkImage *images, VkImageView *views, int count)
void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override
void releaseCachedResources() override
VkSampleCountFlagBits effectiveSampleCount(int sampleCount)
QVkSwapChain * currentSwapChain
QByteArrayList requestedDeviceExtensions
bool createDefaultRenderPass(QVkRenderPassDescriptor *rpD, bool hasDepthStencil, VkSampleCountFlagBits samples, VkFormat colorFormat)
QRhiVulkan(QRhiVulkanInitParams *params, QRhiVulkanNativeHandles *importParams=nullptr)
void draw(QRhiCommandBuffer *cb, quint32 vertexCount, quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override
void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override
void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
QList< int > supportedSampleCounts() const override
QRhiRenderBuffer * createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize, int sampleCount, QRhiRenderBuffer::Flags flags, QRhiTexture::Format backingFormatHint) override
QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override
QBitArray timestampQueryPoolMap
double elapsedSecondsFromTimestamp(quint64 timestamp[2], bool *ok)
QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override
void trackedBufferBarrier(QVkCommandBuffer *cbD, QVkBuffer *bufD, int slot, VkAccessFlags access, VkPipelineStageFlags stage)
void endExternal(QRhiCommandBuffer *cb) override
void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override
VkPhysicalDeviceFeatures physDevFeatures
QRhiVulkanNativeHandles nativeHandlesStruct
bool allocateDescriptorSet(VkDescriptorSetAllocateInfo *allocInfo, VkDescriptorSet *result, int *resultPoolIndex)
void updateShaderResourceBindings(QRhiShaderResourceBindings *srb, int descSetIdx=-1)
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override
VkResult createDescriptorPool(VkDescriptorPool *pool)
void prepareNewFrame(QRhiCommandBuffer *cb)
void subresourceBarrier(QVkCommandBuffer *cbD, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccess, VkAccessFlags dstAccess, VkPipelineStageFlags srcStage, VkPipelineStageFlags dstStage, int startLayer, int layerCount, int startLevel, int levelCount)
void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override
QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override
QRhi::FrameOpResult startPrimaryCommandBuffer(VkCommandBuffer *cb)
double lastCompletedGpuTime(QRhiCommandBuffer *cb) override
void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker, QVkTexture *texD, QRhiPassResourceTracker::TextureAccess access, QRhiPassResourceTracker::TextureStage stage)
bool releaseCachedResourcesCalledBeforeFrameStart
PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR
QRhiGraphicsPipeline * createGraphicsPipeline() override
QRhiComputePipeline * createComputePipeline() override
bool createOffscreenRenderPass(QVkRenderPassDescriptor *rpD, const QRhiColorAttachment *firstColorAttachment, const QRhiColorAttachment *lastColorAttachment, bool preserveColor, bool preserveDs, QRhiRenderBuffer *depthStencilBuffer, QRhiTexture *depthTexture)
QRhiTexture * createTexture(QRhiTexture::Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags) override
void waitCommandCompletion(int frameSlot)
void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR
bool recreateSwapChain(QRhiSwapChain *swapChain)
PFN_vkQueuePresentKHR vkQueuePresentKHR
bool ensurePipelineCache(const void *initialData=nullptr, size_t initialDataSize=0)
QRhiDriverInfo driverInfoStruct
void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
QVarLengthArray< TextureReadback, 2 > activeTextureReadbacks
void depthStencilExplicitBarrier(QVkCommandBuffer *cbD, QVkRenderBuffer *rbD)
void trackedImageBarrier(QVkCommandBuffer *cbD, QVkTexture *texD, VkImageLayout layout, VkAccessFlags access, VkPipelineStageFlags stage)
VkCommandPool cmdPool[QVK_FRAMES_IN_FLIGHT]
VkShaderModule createShader(const QByteArray &spirv)
void enqueueTransitionPassResources(QVkCommandBuffer *cbD)
void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
bool create(QRhi::Flags flags) override
QVulkanDeviceFunctions * df
void setObjectName(uint64_t object, VkObjectType type, const QByteArray &name, int slot=-1)
bool isFeatureSupported(QRhi::Feature feature) const override
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR
QVarLengthArray< BufferReadback, 2 > activeBufferReadbacks
void recordPrimaryCommandBuffer(QVkCommandBuffer *cbD)
bool isYUpInFramebuffer() const override
void debugMarkEnd(QRhiCommandBuffer *cb) override
QRhiSampler * createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w) override
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR
void releaseSwapChainResources(QRhiSwapChain *swapChain)
void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, quint32 instanceCount, quint32 firstIndex, qint32 vertexOffset, quint32 firstInstance) override
VkDeviceSize subresUploadByteSize(const QRhiTextureSubresourceUploadDescription &subresDesc) const
void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override
VkQueryPool timestampQueryPool
void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker, QVkBuffer *bufD, int slot, QRhiPassResourceTracker::BufferAccess access, QRhiPassResourceTracker::BufferStage stage)
VkFormat optimalDepthStencilFormat()
QRhiStats statistics() override
void setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline *ps) override
void activateTextureRenderTarget(QVkCommandBuffer *cbD, QVkTextureRenderTarget *rtD)
PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR
void executeBufferHostWritesForSlot(QVkBuffer *bufD, int slot)
bool isYUpInNDC() const override
const QRhiNativeHandles * nativeHandles() override
void setPipelineCacheData(const QByteArray &data) override
void setVertexInput(QRhiCommandBuffer *cb, int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, QRhiBuffer *indexBuf, quint32 indexOffset, QRhiCommandBuffer::IndexFormat indexFormat) override
QRhiShaderResourceBindings * createShaderResourceBindings() override
VkPipelineCache pipelineCache
void finishActiveReadbacks(bool forced=false)
void ensureCommandPoolForNewFrame()
struct QRhiVulkan::@355 caps
QByteArray pipelineCacheData() override
QList< DeferredReleaseEntry > releaseQueue
void endAndEnqueueSecondaryCommandBuffer(VkCommandBuffer cb, QVkCommandBuffer *cbD)
void beginPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, const QColor &colorClearValue, const QRhiDepthStencilClearValue &depthStencilClearValue, QRhiResourceUpdateBatch *resourceUpdates, QRhiCommandBuffer::BeginPassFlags flags) override
void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override
QRhiBuffer * createBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, quint32 size) override
bool isClipDepthZeroToOne() const override
void enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdateBatch *resourceUpdates)
QVarLengthArray< VkCommandBuffer, 4 > freeSecondaryCbs[QVK_FRAMES_IN_FLIGHT]
void setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR
QMatrix4x4 clipSpaceCorrMatrix() const override
struct QRhiVulkan::OffscreenFrame ofr
QSet< QVkSwapChain * > swapchains
int ubufAlignment() const override
QRhiDriverInfo driverInfo() const override
void beginExternal(QRhiCommandBuffer *cb) override
void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override
QRhi::FrameOpResult endAndSubmitPrimaryCommandBuffer(VkCommandBuffer cb, VkFence cmdFence, VkSemaphore *waitSem, VkSemaphore *signalSem)
QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override
bool makeThreadLocalNativeContextCurrent() override
ResourceLimit
Describes the resource limit to query.
@ MaxThreadsPerThreadGroup
@ MaxThreadGroupsPerDimension
Feature
Flag values to indicate what features are supported by the backend currently in use.
@ NonDynamicUniformBuffers
@ RenderToNonBaseMipLevel
@ MultisampleRenderBuffer
@ PipelineCacheDataLoadSave
@ ReadBackNonUniformBuffer
@ RenderToOneDimensionalTexture
@ OneDimensionalTextureMipmaps
@ ReadBackNonBaseMipLevel
@ ThreeDimensionalTextureMipmaps
@ NonFourAlignedEffectiveIndexBufferOffset
@ ThreeDimensionalTextures
@ ReadBackAnyTextureFormat
static const int MAX_MIP_LEVELS
FrameOpResult
Describes the result of operations that can have a soft failure.
@ FrameOpSwapChainOutOfDate
@ EnablePipelineCacheDataSave
iterator find(const T &value)
QByteArray shader() const
QByteArray entryPoint() const
QShaderCode shader(const QShaderKey &key) const
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
constexpr size_type size() const noexcept
const T & at(qsizetype idx) const
void resize(qsizetype sz)
const_iterator cbegin() const noexcept
const_iterator cend() const noexcept
bool contains(const AT &t) const
const T * constData() const
iterator begin() noexcept
bool isNull() const noexcept
Returns true if there are zero numerical segments, otherwise returns false.
int minorVersion() const noexcept
Returns the minor version number, that is, the second segment.
int majorVersion() const noexcept
Returns the major version number, that is, the first segment.
int microVersion() const noexcept
Returns the micro version number, that is, the third segment.
The QVulkanDeviceFunctions class provides cross-platform access to the device level core Vulkan 1....
The QVulkanInstance class represents a native Vulkan instance, enabling Vulkan rendering onto a QSurf...
QSize size() const override
Returns the size of the window excluding any window frame.
static VulkanServerBufferGlFunctions * funcs
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_STATIC_ASSERT(Condition)
#define QByteArrayLiteral(str)
#define QT_WARNING_DISABLE_GCC(text)
#define QT_WARNING_DISABLE_CLANG(text)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static QString header(const QString &name)
static const qint64 headerSize
bool qFuzzyIsNull(qfloat16 f) noexcept
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLuint const GLuint * buffers
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLuint GLsizei const GLchar * label
[43]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint GLsizei const GLenum * props
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLsizei GLenum GLsizei GLsizei GLuint memory
GLfloat GLfloat GLfloat GLfloat h
GLuint GLsizei const GLuint const GLintptr * offsets
GLdouble GLdouble GLdouble GLdouble q
GLsizei GLsizei GLuint * shaders
GLint GLfloat GLint stencil
GLenum GLenum colorFormat
GLsizeiptr const void GLenum usage
Int aligned(Int v, Int byteAlign)
static bool isDepthTextureFormat(QRhiTexture::Format format)
static QRhiTexture::Format swapchainReadbackTextureFormat(DXGI_FORMAT format, QRhiTexture::Flags *flags)
static QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Buffer::UsageState &bufUsage)
static VkPolygonMode toVkPolygonMode(QRhiGraphicsPipeline::PolygonMode mode)
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetInstanceProcAddr(VkInstance, const char *pName)
static VkCullModeFlags toVkCullMode(QRhiGraphicsPipeline::CullMode c)
static bool accessIsWrite(VkAccessFlags access)
static VkCompareOp toVkTextureCompareOp(QRhiSampler::CompareOp op)
static VkBufferUsageFlagBits toVkBufferUsage(QRhiBuffer::UsageFlags usage)
static QRhiTexture::Format swapchainReadbackTextureFormat(VkFormat format, QRhiTexture::Flags *flags)
static VkStencilOp toVkStencilOp(QRhiGraphicsPipeline::StencilOp op)
static bool qvk_debug_filter(QVulkanInstance::DebugMessageSeverityFlags severity, QVulkanInstance::DebugMessageTypeFlags type, const void *callbackData)
static QVkBuffer::UsageState toVkBufferUsageState(QRhiPassResourceTracker::UsageState usage)
static bool attachmentDescriptionEquals(const VkAttachmentDescription &a, const VkAttachmentDescription &b)
static bool isSrgbFormat(VkFormat format)
static VkAccessFlags toVkAccess(QRhiPassResourceTracker::BufferAccess access)
static VkImageLayout toVkLayout(QRhiPassResourceTracker::TextureAccess access)
static VkFormat toVkAttributeFormat(QRhiVertexInputAttribute::Format format)
static QVkTexture::UsageState toVkTextureUsageState(QRhiPassResourceTracker::UsageState usage)
static VkPipelineStageFlags toVkPipelineStage(QRhiPassResourceTracker::BufferStage stage)
Int aligned(Int v, Int byteAlign)
\variable QRhiVulkanRenderPassNativeHandles::renderPass
static QRhiDriverInfo::DeviceType toRhiDeviceType(VkPhysicalDeviceType type)
static QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QVkBuffer::UsageState &bufUsage)
static VkColorComponentFlags toVkColorComponents(QRhiGraphicsPipeline::ColorMask c)
static VkFilter toVkFilter(QRhiSampler::Filter f)
static VkPrimitiveTopology toVkTopology(QRhiGraphicsPipeline::Topology t)
static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetDeviceProcAddr(VkDevice device, const char *pName)
static void qrhivk_releaseTexture(const QRhiVulkan::DeferredReleaseEntry &e, VkDevice dev, QVulkanDeviceFunctions *df, void *allocator)
static void qrhivk_releaseBuffer(const QRhiVulkan::DeferredReleaseEntry &e, void *allocator)
static struct @283 qvk_sampleCounts[]
static VmaAllocator toVmaAllocator(QVkAllocator a)
static QVulkanInstance * globalVulkanInstance
static VkSamplerAddressMode toVkAddressMode(QRhiSampler::AddressMode m)
static constexpr bool isDepthTextureFormat(QRhiTexture::Format format)
static void fillVkStencilOpState(VkStencilOpState *dst, const QRhiGraphicsPipeline::StencilOpState &src)
VkSampleCountFlagBits mask
static VkShaderStageFlags toVkShaderStageFlags(QRhiShaderResourceBinding::StageFlags stage)
static constexpr VkImageAspectFlags aspectMaskForTextureFormat(QRhiTexture::Format format)
static VkDescriptorType toVkDescriptorType(const QRhiShaderResourceBinding::Data *b)
static VkBlendFactor toVkBlendFactor(QRhiGraphicsPipeline::BlendFactor f)
static VkBlendOp toVkBlendOp(QRhiGraphicsPipeline::BlendOp op)
static void qrhivk_releaseRenderBuffer(const QRhiVulkan::DeferredReleaseEntry &e, VkDevice dev, QVulkanDeviceFunctions *df)
static VkFrontFace toVkFrontFace(QRhiGraphicsPipeline::FrontFace f)
void qrhivk_accumulateComputeResource(T *writtenResources, QRhiResource *resource, QRhiShaderResourceBinding::Type bindingType, int loadTypeVal, int storeTypeVal, int loadStoreTypeVal)
static VkFormat toVkTextureFormat(QRhiTexture::Format format, QRhiTexture::Flags flags)
static VkCompareOp toVkCompareOp(QRhiGraphicsPipeline::CompareOp op)
static void fillRenderPassCreateInfo(VkRenderPassCreateInfo *rpInfo, VkSubpassDescription *subpassDesc, QVkRenderPassDescriptor *rpD)
static VkSamplerMipmapMode toVkMipmapMode(QRhiSampler::Filter f)
static bool hdrFormatMatchesVkSurfaceFormat(QRhiSwapChain::Format f, const VkSurfaceFormatKHR &s)
static void qrhivk_releaseSampler(const QRhiVulkan::DeferredReleaseEntry &e, VkDevice dev, QVulkanDeviceFunctions *df)
static QVkRenderTargetData * maybeRenderTargetData(QVkCommandBuffer *cbD)
static VmaAllocation toVmaAllocation(QVkAlloc a)
static VkShaderStageFlagBits toVkShaderStage(QRhiShaderStage::Type type)
static const int QVK_UNIFORM_BUFFERS_PER_POOL
static const int QVK_COMBINED_IMAGE_SAMPLERS_PER_POOL
static const int QVK_STORAGE_BUFFERS_PER_POOL
static const int QVK_STORAGE_IMAGES_PER_POOL
static const int QVK_MAX_ACTIVE_TIMESTAMP_PAIRS
static const int QVK_DESC_SETS_PER_POOL
static const int QVK_FRAMES_IN_FLIGHT
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
std::unique_ptr< ThunkPool::ThunkAllocation > allocation
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
unsigned long long quint64
QList< QImage > images
[6]
view viewport() -> scroll(dx, dy, deviceRect)
bool prepare(VkRenderPassCreateInfo *rpInfo, int multiViewCount, bool multiViewCap)
bool contains(const AT &t) const noexcept
DeviceType
Specifies the graphics device's type, when the information is available.
\variable QRhiGraphicsPipeline::TargetBlend::colorWrite
\variable QRhiReadbackResult::completed
QRhiTexture::Format format
std::function< void()> completed
QRhiReadbackResult * result
QRhiTextureCopyDescription desc
QRhiReadbackDescription rb
QVarLengthArray< MipLevelUploadList, 6 > subresDesc
QRhiReadbackResult * result
QRhiReadbackResult * result
QVkCommandBuffer * cbWrapper[QVK_FRAMES_IN_FLIGHT]
QRhiTexture::Format format
QRhiReadbackDescription desc
QRhiReadbackResult * result
VkPipelineStageFlags stage
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
VkBuffer buffers[QVK_FRAMES_IN_FLIGHT]
QVkBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, quint32 size)
UsageState usageState[QVK_FRAMES_IN_FLIGHT]
VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT]
QVkAlloc allocations[QVK_FRAMES_IN_FLIGHT]
QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT]
void endFullDynamicBufferUpdateForCurrentFrame() override
To be called when the entire contents of the buffer data has been updated in the memory block returne...
QRhiBuffer::NativeBuffer nativeBuffer() override
bool create() override
Creates the corresponding native graphics resources.
QVarLengthArray< DynamicUpdate, 16 > pendingDynamicUpdates[QVK_FRAMES_IN_FLIGHT]
char * beginFullDynamicBufferUpdateForCurrentFrame() override
union QVkCommandBuffer::Command::Args args
@ TransitionPassResources
struct QVkCommandBuffer::@247 pools
VkBuffer currentVertexBuffers[VERTEX_INPUT_RESOURCE_SLOT_COUNT]
struct QVkCommandBuffer::@245 computePassState
QVkCommandBuffer(QRhiImplementation *rhi)
QVarLengthArray< VkCommandBuffer, 4 > activeSecondaryCbStack
QRhiBackendCommandList< Command > commands
QRhiRenderTarget * currentTarget
QVarLengthArray< VkBufferImageCopy, 16 > bufferImageCopy
QRhiVulkanCommandBufferNativeHandles nativeHandlesStruct
QVarLengthArray< VkImageMemoryBarrier, 8 > imageBarrier
QVarLengthArray< VkBufferMemoryBarrier, 8 > bufferBarrier
quint32 currentVertexOffsets[VERTEX_INPUT_RESOURCE_SLOT_COUNT]
QHash< QRhiResource *, QPair< VkAccessFlags, bool > > writtenResources
QRhiComputePipeline * currentComputePipeline
const QRhiNativeHandles * nativeHandles()
QRhiShaderResourceBindings * currentComputeSrb
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QRhiShaderResourceBindings * currentGraphicsSrb
QVarLengthArray< VkDeviceSize, 4 > vertexBufferOffset
VkBuffer currentIndexBuffer
uint currentSrbGeneration
QVarLengthArray< VkBuffer, 4 > vertexBuffer
QRhiGraphicsPipeline * currentGraphicsPipeline
int currentPassResTrackerIndex
QVarLengthArray< VkClearValue, 4 > clearValue
uint currentPipelineGeneration
quint32 currentIndexOffset
QVarLengthArray< uint32_t, 4 > dynamicOffset
QVarLengthArray< QByteArray, 4 > debugMarkerData
QVarLengthArray< QRhiPassResourceTracker, 8 > passResTrackers
VkIndexType currentIndexFormat
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QVkComputePipeline(QRhiImplementation *rhi)
QVkGraphicsPipeline(QRhiImplementation *rhi)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
bool create() override
Creates the corresponding native graphics resources.
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QVkRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, int sampleCount, Flags flags, QRhiTexture::Format backingFormatHint)
VkSampleCountFlagBits samples
QRhiTexture::Format backingFormat() const override
bool create() override
Creates the corresponding native graphics resources.
QVkTexture * backingTexture
QVarLengthArray< VkSubpassDependency, 2 > subpassDeps
const QRhiNativeHandles * nativeHandles() override
void updateSerializedFormat()
QVector< quint32 > serializedFormatData
QVarLengthArray< VkAttachmentReference, 8 > colorRefs
~QVkRenderPassDescriptor()
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() const override
VkAttachmentReference dsRef
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QVarLengthArray< VkAttachmentReference, 8 > resolveRefs
QVarLengthArray< VkAttachmentDescription, 8 > attDescs
QRhiVulkanRenderPassNativeHandles nativeHandlesStruct
QVector< quint32 > serializedFormat() const override
QVkRenderPassDescriptor(QRhiImplementation *rhi)
bool isCompatible(const QRhiRenderPassDescriptor *other) const override
QVkRenderPassDescriptor * rp
QRhiRenderTargetAttachmentTracker::ResIdList currentResIdList
static const int MAX_COLOR_ATTACHMENTS
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QVkSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode, AddressMode u, AddressMode v, AddressMode w)
BoundStorageImageData simage
BoundStorageBufferData sbuf
BoundSampledTextureData stex
BoundUniformBufferData ubuf
struct QVkShaderResourceBindings::BoundSampledTextureData::@239 d[QRhiShaderResourceBinding::Data::MAX_TEX_SAMPLER_ARRAY_SIZE]
VkDescriptorSetLayout layout
void updateResources(UpdateFlags flags) override
QVkShaderResourceBindings(QRhiImplementation *rhi)
QVarLengthArray< QRhiShaderResourceBinding, 8 > sortedBindings
QVarLengthArray< BoundResourceData, 8 > boundResourceData[QVK_FRAMES_IN_FLIGHT]
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]
~QVkShaderResourceBindings()
QSize pixelSize() const override
int sampleCount() const override
float devicePixelRatio() const override
~QVkSwapChainRenderTarget()
QVkSwapChainRenderTarget(QRhiImplementation *rhi, QRhiSwapChain *swapchain)
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
@ ScImageUseTransferSource
VkColorSpaceKHR colorSpace
VkSurfaceKHR lastConnectedSurface
bool createOrResize() override
Creates the swapchain if not already done and resizes the swapchain buffers to match the current size...
bool isFormatSupported(Format f) override
QVkCommandBuffer cbWrapper
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
VkSampleCountFlagBits samples
struct QVkSwapChain::FrameResources frameRes[QVK_FRAMES_IN_FLIGHT]
QVkSwapChain(QRhiImplementation *rhi)
QSize surfacePixelSize() override
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
VkDeviceMemory msaaImageMem
QRhiRenderTarget * currentFrameRenderTarget() override
quint32 currentImageIndex
QVarLengthArray< ImageResources, EXPECTED_MAX_BUFFER_COUNT > imageRes
QVarLengthArray< VkPresentModeKHR, 8 > supportedPresentationModes
QVkSwapChainRenderTarget rtWrapper
QRhiCommandBuffer * currentFrameCommandBuffer() override
QVkTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags)
~QVkTextureRenderTarget()
float devicePixelRatio() const override
VkImageView rtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS]
bool create() override
Creates the corresponding native graphics resources.
int sampleCount() const override
QSize pixelSize() const override
VkImageView resrtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS]
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
QRhiRenderPassDescriptor * newCompatibleRenderPassDescriptor() override
VkPipelineStageFlags stage
bool create() override
Creates the corresponding native graphics resources.
void destroy() override
Releases (or requests deferred releasing of) the underlying native graphics resources.
VkBuffer stagingBuffers[QVK_FRAMES_IN_FLIGHT]
VkSampleCountFlagBits samples
VkImageView imageViewForLevel(int level)
QVkAlloc stagingAllocations[QVK_FRAMES_IN_FLIGHT]
bool createFrom(NativeTexture src) override
Similar to create(), except that no new native textures are created.
void setNativeLayout(int layout) override
With some graphics APIs, such as Vulkan, integrating custom rendering code that uses the graphics API...
QVkTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth, int arraySize, int sampleCount, Flags flags)
VkImageView perLevelImageViews[QRhi::MAX_MIP_LEVELS]
NativeTexture nativeTexture() override
bool prepareCreate(QSize *adjustedSize=nullptr)
int vertexBufferOffsetIndex
struct QVkCommandBuffer::Command::Args::@272 copyImageToBuffer
struct QVkCommandBuffer::Command::Args::@289 bindIndexBuffer
struct QVkCommandBuffer::Command::Args::@307 debugMarkerInsert
struct QVkCommandBuffer::Command::Args::@301 drawIndexed
struct QVkCommandBuffer::Command::Args::@277 bufferBarrier
struct QVkCommandBuffer::Command::Args::@280 beginRenderPass
struct QVkCommandBuffer::Command::Args::@308 transitionResources
struct QVkCommandBuffer::Command::Args::@284 bindPipeline
struct QVkCommandBuffer::Command::Args::@291 setViewport
struct QVkCommandBuffer::Command::Args::@309 dispatch
VkPipelineLayout pipelineLayout
VkPipelineStageFlags srcStageMask
struct QVkCommandBuffer::Command::Args::@286 bindDescriptorSet
struct QVkCommandBuffer::Command::Args::@269 copyBufferToImage
VkPipelineStageFlags dstStageMask
struct QVkCommandBuffer::Command::Args::@299 draw
struct QVkCommandBuffer::Command::Args::@278 blitImage
struct QVkCommandBuffer::Command::Args::@295 setBlendConstants
struct QVkCommandBuffer::Command::Args::@274 imageBarrier
struct QVkCommandBuffer::Command::Args::@293 setScissor
struct QVkCommandBuffer::Command::Args::@297 setStencilRef
VkPipelineBindPoint bindPoint
struct QVkCommandBuffer::Command::Args::@287 bindVertexBuffer
struct QVkCommandBuffer::Command::Args::@310 executeSecondary
struct QVkCommandBuffer::Command::Args::@267 copyBuffer
struct QVkCommandBuffer::Command::Args::@303 debugMarkerBegin
struct QVkCommandBuffer::Command::Args::@271 copyImage