25 #define PNG_SWAPCHAIN_IMAGES 3    27 #ifdef FORCE_NO_VALIDATION    28 #define ENABLE_VALIDATION_LAYERS 0    30 #define ENABLE_VALIDATION_LAYERS 1    38 static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT type,
    39                                                     uint64_t 
object, 
size_t location, int32_t messageCode,
    40                                                     const char *pLayerPrefix, 
const char *pMessage, 
void *pUserData)
    42         auto *platform = 
static_cast<PNGPlatform *
>(pUserData);
    43         auto callback = platform->getExternalDebugCallback();
    47                 return callback(flags, type, 
object, location, messageCode, pLayerPrefix, pMessage,
    48                                 platform->getExternalDebugCallbackUserData());
    52                 if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
    54                         LOGE(
"Validation Layer: Error: %s: %s\n", pLayerPrefix, pMessage);
    56                 else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
    58                         LOGE(
"Validation Layer: Warning: %s: %s\n", pLayerPrefix, pMessage);
    60                 else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
    62                         LOGI(
"Validation Layer: Performance warning: %s: %s\n", pLayerPrefix, pMessage);
    66                         LOGI(
"Validation Layer: Information: %s: %s\n", pLayerPrefix, pMessage);
    72 uint32_t PNGPlatform::findMemoryTypeFromRequirements(uint32_t deviceRequirements, uint32_t hostRequirements)
    74         const VkPhysicalDeviceMemoryProperties &props = memoryProperties;
    75         for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++)
    77                 if (deviceRequirements & (1u << i))
    79                         if ((props.memoryTypes[i].propertyFlags & hostRequirements) == hostRequirements)
    86         LOGE(
"Failed to obtain suitable memory type.\n");
    90 uint32_t PNGPlatform::findMemoryTypeFromRequirementsFallback(uint32_t deviceRequirements, uint32_t hostRequirements,
    91                                                              uint32_t hostRequirementsFallback)
    93         const VkPhysicalDeviceMemoryProperties &props = memoryProperties;
    94         for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++)
    96                 if (deviceRequirements & (1u << i))
    98                         if ((props.memoryTypes[i].propertyFlags & hostRequirements) == hostRequirements)
   105         return findMemoryTypeFromRequirements(deviceRequirements, hostRequirementsFallback);
   108 Platform &Platform::get()
   112         static PNGPlatform singleton;
   118         return STATUS_RUNNING;
   121 Result PNGPlatform::initialize()
   123         const char *path = getenv(
"MALI_PNG_PATH");
   126                 LOGI(
"MALI_PNG_PATH environment variable not defined, falling back to "   128                 path = 
"Mali-SDK-Frames";
   130         LOGI(
"Dumping PNG files to: %s.xxxxxxxx.png.\n", path);
   134                 return RESULT_ERROR_OUT_OF_MEMORY;
   137         if (FAILED(pngSwapchain->init(path, PNG_SWAPCHAIN_IMAGES)))
   138                 return RESULT_ERROR_GENERIC;
   142                 return RESULT_ERROR_OUT_OF_MEMORY;
   144         return RESULT_SUCCESS;
   147 void PNGPlatform::terminate()
   151                 vkDeviceWaitIdle(device);
   155         pngSwapchain = 
nullptr;
   157         for (
auto &image : swapchainImages)
   158                 if (image != VK_NULL_HANDLE)
   159                         vkDestroyImage(device, image, 
nullptr);
   161         for (
auto &memory : swapchainMemory)
   162                 if (memory != VK_NULL_HANDLE)
   163                         vkFreeMemory(device, memory, 
nullptr);
   165         for (
auto &buffer : swapchainReadback)
   166                 if (buffer != VK_NULL_HANDLE)
   167                         vkDestroyBuffer(device, buffer, 
nullptr);
   169         for (
auto &memory : swapchainReadbackMemory)
   170                 if (memory != VK_NULL_HANDLE)
   171                         vkFreeMemory(device, memory, 
nullptr);
   180                 vkDestroyDevice(device, 
nullptr);
   184                 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkDestroyDebugReportCallbackEXT);
   185                 vkDestroyDebugReportCallbackEXT(instance, debug_callback, 
nullptr);
   189                 vkDestroyInstance(instance, 
nullptr);
   191         swapchainImages.clear();
   192         swapchainMemory.clear();
   193         swapchainReadback.clear();
   194         swapchainReadbackMemory.clear();
   195         device = VK_NULL_HANDLE;
   196         debug_callback = VK_NULL_HANDLE;
   197         instance = VK_NULL_HANDLE;
   200 PNGPlatform::~PNGPlatform()
   208                 1280, 720, VK_FORMAT_R8G8B8A8_UNORM,
   216         return initVulkan(swapchain);
   221         *images = swapchainImages;
   222         *swapchain = swapchainDimensions;
   225 unsigned PNGPlatform::getNumSwapchainImages()
 const   227         return swapchainImages.size();
   230 Result PNGPlatform::acquireNextImage(
unsigned *image)
   235         *image = pngSwapchain->acquire();
   239         pContext->beginFrame(*image, VK_NULL_HANDLE);
   240         return RESULT_SUCCESS;
   243 void PNGPlatform::imageMemoryBarrier(VkCommandBuffer cmd, VkImage image, VkAccessFlags srcAccessMask,
   244                                      VkAccessFlags dstAccessMask, VkPipelineStageFlags srcStageMask,
   245                                      VkPipelineStageFlags dstStageMask, VkImageLayout oldLayout,
   246                                      VkImageLayout newLayout)
   248         VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
   250         barrier.srcAccessMask = srcAccessMask;
   251         barrier.dstAccessMask = dstAccessMask;
   252         barrier.oldLayout = oldLayout;
   253         barrier.newLayout = newLayout;
   254         barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   255         barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
   256         barrier.image = image;
   257         barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   258         barrier.subresourceRange.levelCount = 1;
   259         barrier.subresourceRange.layerCount = 1;
   261         vkCmdPipelineBarrier(cmd, srcStageMask, dstStageMask, 
false, 0, 
nullptr, 0, 
nullptr, 1, &barrier);
   264 Result PNGPlatform::presentImage(
unsigned index)
   266         auto cmd = pContext->requestPrimaryCommandBuffer();
   268         VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
   269         beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
   270         vkBeginCommandBuffer(cmd, &beginInfo);
   273         imageMemoryBarrier(cmd, swapchainImages[index], VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_TRANSFER_READ_BIT,
   274                            VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
   275                            VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
   278         VkBufferImageCopy region = { 0 };
   279         region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
   280         region.imageSubresource.layerCount = 1;
   281         region.imageExtent.width = swapchainDimensions.width;
   282         region.imageExtent.height = swapchainDimensions.height;
   283         region.imageExtent.depth = 1;
   284         vkCmdCopyImageToBuffer(cmd, swapchainImages[index], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchainReadback[index],
   287         VK_CHECK(vkEndCommandBuffer(cmd));
   288         pContext->submit(cmd);
   294         unsigned numFences = pContext->getFenceManager().getActiveFenceCount();
   295         VkFence *fences = pContext->getFenceManager().getActiveFences();
   296         pngSwapchain->present(index, device, swapchainReadbackMemory[index], swapchainDimensions.width,
   297                               swapchainDimensions.height, numFences, fences, swapchainCoherent);
   298         return RESULT_SUCCESS;
   303         if (!vulkanSymbolWrapperInitLoader())
   305                 LOGE(
"Cannot find Vulkan loader.\n");
   306                 return RESULT_ERROR_GENERIC;
   309         if (!vulkanSymbolWrapperLoadGlobalSymbols())
   311                 LOGE(
"Failed to load global Vulkan symbols.\n");
   312                 return RESULT_ERROR_GENERIC;
   315         uint32_t instanceExtensionCount;
   316         VK_CHECK(vkEnumerateInstanceExtensionProperties(
nullptr, &instanceExtensionCount, 
nullptr));
   317         vector<VkExtensionProperties> instanceExtensions(instanceExtensionCount);
   318         VK_CHECK(vkEnumerateInstanceExtensionProperties(
nullptr, &instanceExtensionCount, instanceExtensions.data()));
   320         for (
auto &instanceExt : instanceExtensions)
   321                 LOGI(
"Instance extension: %s\n", instanceExt.extensionName);
   323 #if ENABLE_VALIDATION_LAYERS   324         uint32_t instanceLayerCount;
   325         VK_CHECK(vkEnumerateInstanceLayerProperties(&instanceLayerCount, 
nullptr));
   326         vector<VkLayerProperties> instanceLayers(instanceLayerCount);
   327         VK_CHECK(vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayers.data()));
   329         vector<const char *> activeLayers;
   330         for (
auto &ext : instanceLayers)
   331                 if (strcmp(ext.layerName, 
"VK_LAYER_LUNARG_standard_validation") == 0)
   332                         activeLayers.push_back(
"VK_LAYER_LUNARG_standard_validation");
   334         if (activeLayers.empty())
   335                 LOGI(
"Did not find validation layers.\n");
   337                 LOGI(
"Found validation layers!\n");
   339         addExternalLayers(activeLayers, instanceLayers);
   342         bool haveDebugReport = 
false;
   343         vector<const char *> activeInstanceExtensions;
   344         for (
auto &ext : instanceExtensions)
   346                 if (strcmp(ext.extensionName, 
"VK_EXT_debug_report") == 0)
   348                         haveDebugReport = 
true;
   349                         activeInstanceExtensions.push_back(
"VK_EXT_debug_report");
   354         VkApplicationInfo app = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
   355         app.pApplicationName = 
"Mali SDK";
   356         app.applicationVersion = 0;
   357         app.pEngineName = 
"Mali SDK";
   358         app.engineVersion = 0;
   359         app.apiVersion = VK_MAKE_VERSION(1, 0, 13);
   361         VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
   362         info.pApplicationInfo = &app;
   364 #if ENABLE_VALIDATION_LAYERS   365         if (!activeLayers.empty())
   367                 info.enabledLayerCount = activeLayers.size();
   368                 info.ppEnabledLayerNames = activeLayers.data();
   369                 LOGI(
"Using Vulkan instance validation layers.\n");
   372         if (!activeInstanceExtensions.empty())
   374                 info.enabledExtensionCount = activeInstanceExtensions.size();
   375                 info.ppEnabledExtensionNames = activeInstanceExtensions.data();
   379         VK_CHECK(vkCreateInstance(&info, 
nullptr, &instance));
   381         if (!vulkanSymbolWrapperLoadCoreInstanceSymbols(instance))
   383                 LOGE(
"Failed to load instance symbols.");
   384                 return RESULT_ERROR_GENERIC;
   389                 VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_EXTENSION_SYMBOL(instance, vkCreateDebugReportCallbackEXT);
   390                 VkDebugReportCallbackCreateInfoEXT info = { VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT };
   391                 info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT |
   392                              VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
   394                 info.pfnCallback = debugCallback;
   395                 info.pUserData = 
this;
   396                 if (vkCreateDebugReportCallbackEXT)
   397                         vkCreateDebugReportCallbackEXT(instance, &info, 
nullptr, &debug_callback);
   398                 LOGI(
"Enabling Vulkan debug reporting.\n");
   401         uint32_t gpuCount = 0;
   402         VK_CHECK(vkEnumeratePhysicalDevices(instance, &gpuCount, 
nullptr));
   405                 LOGE(
"Failed to enumerate Vulkan physical device.\n");
   406                 return RESULT_ERROR_GENERIC;
   409         vector<VkPhysicalDevice> gpus(gpuCount);
   410         VK_CHECK(vkEnumeratePhysicalDevices(instance, &gpuCount, gpus.data()));
   412         gpu = VK_NULL_HANDLE;
   414         for (
auto device : gpus)
   416                 VkPhysicalDeviceProperties properties;
   417                 vkGetPhysicalDeviceProperties(device, &properties);
   420                 if (strstr(properties.deviceName, 
"Mali"))
   423                         LOGI(
"Found ARM Mali physical device: %s.\n", properties.deviceName);
   429         if (gpu == VK_NULL_HANDLE)
   432         vkGetPhysicalDeviceProperties(gpu, &gpuProperties);
   433         vkGetPhysicalDeviceMemoryProperties(gpu, &memoryProperties);
   436         vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queueCount, 
nullptr);
   437         queueProperties.resize(queueCount);
   438         vkGetPhysicalDeviceQueueFamilyProperties(gpu, &queueCount, queueProperties.data());
   440                 return RESULT_ERROR_GENERIC;
   442 #if ENABLE_VALIDATION_LAYERS   443         uint32_t deviceLayerCount;
   444         VK_CHECK(vkEnumerateDeviceLayerProperties(gpu, &deviceLayerCount, 
nullptr));
   445         vector<VkLayerProperties> deviceLayers(deviceLayerCount);
   446         VK_CHECK(vkEnumerateDeviceLayerProperties(gpu, &deviceLayerCount, deviceLayers.data()));
   448         activeLayers.clear();
   449         for (
auto &ext : deviceLayers)
   451                 if (strcmp(ext.layerName, 
"VK_LAYER_LUNARG_standard_validation") == 0)
   452                         activeLayers.push_back(
"VK_LAYER_LUNARG_standard_validation");
   455         addExternalLayers(activeLayers, instanceLayers);
   458         bool foundQueue = 
false;
   459         for (
unsigned i = 0; i < queueCount; i++)
   461                 if (queueProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
   463                         graphicsQueueIndex = i;
   471                 LOGE(
"Did not find suitable graphics queue.\n");
   472                 return RESULT_ERROR_GENERIC;
   475         static const float one = 1.0f;
   476         VkDeviceQueueCreateInfo queueInfo = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO };
   477         queueInfo.queueFamilyIndex = graphicsQueueIndex;
   478         queueInfo.queueCount = 1;
   479         queueInfo.pQueuePriorities = &one;
   481         VkPhysicalDeviceFeatures features = { 
false };
   482         VkDeviceCreateInfo deviceInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
   483         deviceInfo.queueCreateInfoCount = 1;
   484         deviceInfo.pQueueCreateInfos = &queueInfo;
   485         deviceInfo.pEnabledFeatures = &features;
   487 #if ENABLE_VALIDATION_LAYERS   488         if (!activeLayers.empty())
   490                 deviceInfo.enabledLayerCount = activeLayers.size();
   491                 deviceInfo.ppEnabledLayerNames = activeLayers.data();
   492                 LOGI(
"Using Vulkan device validation layers.\n");
   496         VK_CHECK(vkCreateDevice(gpu, &deviceInfo, 
nullptr, &device));
   497         if (!vulkanSymbolWrapperLoadCoreDeviceSymbols(device))
   499                 LOGE(
"Failed to load device symbols.");
   500                 return RESULT_ERROR_GENERIC;
   503         vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue);
   505         swapchainDimensions = swapchain;
   506         swapchainDimensions.
format = VK_FORMAT_R8G8B8A8_UNORM;
   507         swapchainImages.resize(pngSwapchain->getNumImages());
   508         swapchainMemory.resize(pngSwapchain->getNumImages());
   509         swapchainReadback.resize(pngSwapchain->getNumImages());
   510         swapchainReadbackMemory.resize(pngSwapchain->getNumImages());
   512         for (
unsigned i = 0; i < pngSwapchain->getNumImages(); i++)
   514                 VkImageCreateInfo image = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
   516                 image.imageType = VK_IMAGE_TYPE_2D;
   517                 image.format = VK_FORMAT_R8G8B8A8_UNORM;
   518                 image.extent.width = swapchainDimensions.width;
   519                 image.extent.height = swapchainDimensions.height;
   520                 image.extent.depth = 1;
   521                 image.samples = VK_SAMPLE_COUNT_1_BIT;
   522                 image.tiling = VK_IMAGE_TILING_OPTIMAL;
   523                 image.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
   524                 image.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
   526                 image.arrayLayers = 1;
   528                 VK_CHECK(vkCreateImage(device, &image, 
nullptr, &swapchainImages[i]));
   531                 VkMemoryRequirements memReqs;
   532                 vkGetImageMemoryRequirements(device, swapchainImages[i], &memReqs);
   534                 VkMemoryAllocateInfo alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
   535                 alloc.allocationSize = memReqs.size;
   536                 alloc.memoryTypeIndex =
   537                     findMemoryTypeFromRequirements(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
   538                 VK_CHECK(vkAllocateMemory(device, &alloc, 
nullptr, &swapchainMemory[i]));
   539                 vkBindImageMemory(device, swapchainImages[i], swapchainMemory[i], 0);
   542                 VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
   543                 bufferInfo.size = swapchainDimensions.width * swapchainDimensions.height * 4;
   544                 bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   545                 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
   547                 VK_CHECK(vkCreateBuffer(device, &bufferInfo, 
nullptr, &swapchainReadback[i]));
   548                 vkGetBufferMemoryRequirements(device, swapchainReadback[i], &memReqs);
   550                 alloc.allocationSize = memReqs.size;
   553                 alloc.memoryTypeIndex = findMemoryTypeFromRequirementsFallback(
   554                     memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
   555                     VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
   556                 VK_CHECK(vkAllocateMemory(device, &alloc, 
nullptr, &swapchainReadbackMemory[i]));
   561                 swapchainCoherent = (memoryProperties.memoryTypes[alloc.memoryTypeIndex].propertyFlags &
   562                                      VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
   564                 vkBindBufferMemory(device, swapchainReadback[i], swapchainReadbackMemory[i], 0);
   567         Result res = pContext->onPlatformUpdate(
this);
   569                 return RESULT_ERROR_GENERIC;
   571         return RESULT_SUCCESS;
 
The Context is the primary way for samples to interact with the swapchain and get rendered images to ...
 
This class implements a swapchain outside the Vulkan API. Its main purpose is debugging without a scr...