SDL  2.0
testvulkan.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "SDL_test_common.h"
#include "../src/video/khronos/vulkan/vulkan.h"
#include "SDL_vulkan.h"
+ Include dependency graph for testvulkan.c:

Go to the source code of this file.

Data Structures

struct  VulkanContext

Macros

#define VK_NO_PROTOTYPES
#define UINT64_MAX   18446744073709551615
#define VULKAN_FUNCTIONS()
#define VULKAN_DEVICE_FUNCTION(name)   static PFN_##name name = NULL;
#define VULKAN_GLOBAL_FUNCTION(name)   static PFN_##name name = NULL;
#define VULKAN_INSTANCE_FUNCTION(name)   static PFN_##name name = NULL;
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name)
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name)
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name)

Functions

static const char * getVulkanResultString (VkResult result)
static void shutdownVulkan (void)
static void quit (int rc)
static void loadGlobalFunctions (void)
static void createInstance (void)
static void loadInstanceFunctions (void)
static void createSurface (void)
static void findPhysicalDevice (void)
static void createDevice (void)
static void loadDeviceFunctions (void)
static void getQueues (void)
static void createSemaphore (VkSemaphore *semaphore)
static void createSemaphores (void)
static void getSurfaceCaps (void)
static void getSurfaceFormats (void)
static void getSwapchainImages (void)
static SDL_bool createSwapchain (void)
static void destroySwapchain (void)
static void destroyCommandBuffers (void)
static void destroyCommandPool (void)
static void createCommandPool (void)
static void createCommandBuffers (void)
static void createFences (void)
static void destroyFences (void)
static void recordPipelineImageBarrier (VkCommandBuffer commandBuffer, VkAccessFlags sourceAccessMask, VkAccessFlags destAccessMask, VkImageLayout sourceLayout, VkImageLayout destLayout, VkImage image)
static void rerecordCommandBuffer (uint32_t frameIndex, const VkClearColorValue *clearColor)
static void destroySwapchainAndSwapchainSpecificStuff (SDL_bool doDestroySwapchain)
static SDL_bool createNewSwapchainAndSwapchainSpecificStuff (void)
static void initVulkan (void)
static SDL_bool render (void)
int main (int argc, char *argv[])

Variables

static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL
static SDLTest_CommonStatestate
static VulkanContext vulkanContext = {0}

Macro Definition Documentation

#define UINT64_MAX   18446744073709551615

Definition at line 39 of file testvulkan.c.

Referenced by render(), and SDLTest_RandomUint64BoundaryValue().

#define VK_NO_PROTOTYPES

Definition at line 29 of file testvulkan.c.

#define VULKAN_DEVICE_FUNCTION (   name)    static PFN_##name name = NULL;

Definition at line 87 of file testvulkan.c.

#define VULKAN_DEVICE_FUNCTION (   name)

Definition at line 87 of file testvulkan.c.

#define VULKAN_DEVICE_FUNCTION (   name)

Definition at line 87 of file testvulkan.c.

#define VULKAN_DEVICE_FUNCTION (   name)
Value:
if(!name) \
{ \
"vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
quit(2); \
}

Definition at line 87 of file testvulkan.c.

#define VULKAN_FUNCTIONS ( )

Definition at line 42 of file testvulkan.c.

Referenced by loadDeviceFunctions(), loadGlobalFunctions(), and loadInstanceFunctions().

#define VULKAN_GLOBAL_FUNCTION (   name)    static PFN_##name name = NULL;

Definition at line 88 of file testvulkan.c.

#define VULKAN_GLOBAL_FUNCTION (   name)
Value:
if(!name) \
{ \
"vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
quit(2); \
}

Definition at line 88 of file testvulkan.c.

#define VULKAN_GLOBAL_FUNCTION (   name)

Definition at line 88 of file testvulkan.c.

#define VULKAN_GLOBAL_FUNCTION (   name)

Definition at line 88 of file testvulkan.c.

#define VULKAN_INSTANCE_FUNCTION (   name)    static PFN_##name name = NULL;

Definition at line 89 of file testvulkan.c.

#define VULKAN_INSTANCE_FUNCTION (   name)

Definition at line 89 of file testvulkan.c.

#define VULKAN_INSTANCE_FUNCTION (   name)
Value:
if(!name) \
{ \
"vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
quit(2); \
}

Definition at line 89 of file testvulkan.c.

#define VULKAN_INSTANCE_FUNCTION (   name)

Definition at line 89 of file testvulkan.c.

Function Documentation

static void createDevice ( void  )
static

Definition at line 497 of file testvulkan.c.

References VulkanContext::device, VkDeviceCreateInfo::enabledExtensionCount, getVulkanResultString(), VulkanContext::graphicsQueueFamilyIndex, NULL, VkDeviceCreateInfo::pEnabledFeatures, VulkanContext::physicalDevice, VkDeviceCreateInfo::ppEnabledExtensionNames, VkDeviceCreateInfo::pQueueCreateInfos, VkDeviceQueueCreateInfo::pQueuePriorities, VkDeviceQueueCreateInfo::queueCount, VkDeviceCreateInfo::queueCreateInfoCount, VkDeviceQueueCreateInfo::queueFamilyIndex, quit(), SDL_arraysize, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, VkDeviceQueueCreateInfo::sType, VkDeviceCreateInfo::sType, VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_NULL_HANDLE, VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, VK_SUCCESS, and vkCreateDevice().

Referenced by initVulkan().

{
VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {0};
static const float queuePriority[] = {1.0f};
VkDeviceCreateInfo deviceCreateInfo = {0};
static const char *const deviceExtensionNames[] = {
};
deviceQueueCreateInfo->queueCount = 1;
deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0];
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
deviceCreateInfo.pEnabledFeatures = NULL;
deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames);
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames;
result = vkCreateDevice(
if(result != VK_SUCCESS)
{
SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result));
quit(2);
}
}
static void createInstance ( void  )
static

Definition at line 245 of file testvulkan.c.

References VkApplicationInfo::apiVersion, VkInstanceCreateInfo::enabledExtensionCount, getVulkanResultString(), VulkanContext::instance, NULL, VkInstanceCreateInfo::pApplicationInfo, VkInstanceCreateInfo::ppEnabledExtensionNames, quit(), SDL_free, SDL_GetError, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_malloc, SDL_OutOfMemory, SDL_Vulkan_GetInstanceExtensions, VkApplicationInfo::sType, VkInstanceCreateInfo::sType, VK_API_VERSION_1_0, VK_NULL_HANDLE, VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, VK_SUCCESS, and vkCreateInstance().

Referenced by initVulkan().

{
VkApplicationInfo appInfo = {0};
VkInstanceCreateInfo instanceCreateInfo = {0};
const char **extensions = NULL;
unsigned extensionCount = 0;
instanceCreateInfo.pApplicationInfo = &appInfo;
if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL))
{
"SDL_Vulkan_GetInstanceExtensions(): %s\n",
quit(2);
}
extensions = SDL_malloc(sizeof(const char *) * extensionCount);
if(!extensions)
{
quit(2);
}
if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions))
{
SDL_free((void*)extensions);
"SDL_Vulkan_GetInstanceExtensions(): %s\n",
quit(2);
}
instanceCreateInfo.enabledExtensionCount = extensionCount;
instanceCreateInfo.ppEnabledExtensionNames = extensions;
result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance);
SDL_free((void*)extensions);
if(result != VK_SUCCESS)
{
"vkCreateInstance(): %s\n",
quit(2);
}
}
static void createSemaphore ( VkSemaphore *  semaphore)
static
static SDL_bool createSwapchain ( void  )
static

Definition at line 687 of file testvulkan.c.

References VkSwapchainCreateInfoKHR::clipped, VkSurfaceFormatKHR::colorSpace, VkSwapchainCreateInfoKHR::compositeAlpha, VkSurfaceCapabilitiesKHR::currentTransform, VulkanContext::device, VkSurfaceFormatKHR::format, getSwapchainImages(), getVulkanResultString(), VkExtent2D::height, i, VkSwapchainCreateInfoKHR::imageArrayLayers, VkSwapchainCreateInfoKHR::imageColorSpace, VkSwapchainCreateInfoKHR::imageExtent, VkSwapchainCreateInfoKHR::imageFormat, VkSwapchainCreateInfoKHR::imageSharingMode, VkSwapchainCreateInfoKHR::imageUsage, VkSurfaceCapabilitiesKHR::maxImageCount, VkSurfaceCapabilitiesKHR::minImageCount, VkSwapchainCreateInfoKHR::minImageCount, NULL, VkSwapchainCreateInfoKHR::oldSwapchain, VkSwapchainCreateInfoKHR::presentMode, VkSwapchainCreateInfoKHR::preTransform, quit(), SDL_FALSE, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_TRUE, SDL_Vulkan_GetDrawableSize, VkSwapchainCreateInfoKHR::sType, VulkanContext::surface, VkSwapchainCreateInfoKHR::surface, VulkanContext::surfaceCapabilities, VulkanContext::surfaceFormat, VulkanContext::surfaceFormats, VulkanContext::surfaceFormatsCount, VulkanContext::swapchain, VulkanContext::swapchainDesiredImageCount, VulkanContext::swapchainSize, VK_COLORSPACE_SRGB_NONLINEAR_KHR, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_UNDEFINED, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_NULL_HANDLE, VK_PRESENT_MODE_FIFO_KHR, VK_SHARING_MODE_EXCLUSIVE, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, VK_SUCCESS, VK_TRUE, vkCreateSwapchainKHR(), vkDestroySwapchainKHR(), VkExtent2D::width, and SDLTest_CommonState::windows.

Referenced by createNewSwapchainAndSwapchainSpecificStuff().

{
int w, h;
VkSwapchainCreateInfoKHR createInfo = {0};
// pick an image count
// pick a format
{
// aren't any preferred formats, so we pick
}
else
{
for(i = 0; i < vulkanContext.surfaceFormatsCount; i++)
{
{
break;
}
}
}
// get size
SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h);
if(w == 0 || h == 0)
return SDL_FALSE;
createInfo.imageArrayLayers = 1;
createInfo.clipped = VK_TRUE;
result =
if(createInfo.oldSwapchain)
if(result != VK_SUCCESS)
{
"vkCreateSwapchainKHR(): %s\n",
quit(2);
}
return SDL_TRUE;
}
static void destroySwapchainAndSwapchainSpecificStuff ( SDL_bool  doDestroySwapchain)
static
static void findPhysicalDevice ( void  )
static

Definition at line 324 of file testvulkan.c.

References VkPhysicalDeviceProperties::apiVersion, getVulkanResultString(), VulkanContext::graphicsQueueFamilyIndex, i, VulkanContext::instance, NULL, VulkanContext::physicalDevice, VulkanContext::physicalDeviceFeatures, VulkanContext::physicalDeviceProperties, VulkanContext::presentQueueFamilyIndex, quit(), SDL_FALSE, SDL_free, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_malloc, SDL_OutOfMemory, SDL_strcmp, SDL_TRUE, VulkanContext::surface, VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_QUEUE_GRAPHICS_BIT, VK_SUCCESS, VK_VERSION_MAJOR, vkEnumerateDeviceExtensionProperties(), vkEnumeratePhysicalDevices(), vkGetPhysicalDeviceFeatures(), vkGetPhysicalDeviceProperties(), vkGetPhysicalDeviceQueueFamilyProperties(), and vkGetPhysicalDeviceSurfaceSupportKHR().

Referenced by initVulkan().

{
uint32_t physicalDeviceCount = 0;
VkPhysicalDevice *physicalDevices;
VkQueueFamilyProperties *queueFamiliesProperties = NULL;
uint32_t queueFamiliesPropertiesAllocatedSize = 0;
VkExtensionProperties *deviceExtensions = NULL;
uint32_t deviceExtensionsAllocatedSize = 0;
uint32_t physicalDeviceIndex;
if(result != VK_SUCCESS)
{
"vkEnumeratePhysicalDevices(): %s\n",
quit(2);
}
if(physicalDeviceCount == 0)
{
"vkEnumeratePhysicalDevices(): no physical devices\n");
quit(2);
}
physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
if(!physicalDevices)
{
quit(2);
}
result =
vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices);
if(result != VK_SUCCESS)
{
SDL_free(physicalDevices);
"vkEnumeratePhysicalDevices(): %s\n",
quit(2);
}
for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount;
physicalDeviceIndex++)
{
uint32_t queueFamiliesCount = 0;
uint32_t queueFamilyIndex;
uint32_t deviceExtensionCount = 0;
SDL_bool hasSwapchainExtension = SDL_FALSE;
VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
continue;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL);
if(queueFamiliesCount == 0)
continue;
if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount)
{
SDL_free(queueFamiliesProperties);
queueFamiliesPropertiesAllocatedSize = queueFamiliesCount;
queueFamiliesProperties =
SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize);
if(!queueFamiliesProperties)
{
SDL_free(physicalDevices);
SDL_free(deviceExtensions);
quit(2);
}
}
physicalDevice, &queueFamiliesCount, queueFamiliesProperties);
vulkanContext.presentQueueFamilyIndex = queueFamiliesCount;
for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount;
queueFamilyIndex++)
{
VkBool32 supported = 0;
if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0)
continue;
if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported);
if(result != VK_SUCCESS)
{
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
"vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n",
quit(2);
}
if(supported)
{
if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT)
break; // use this queue because it can present and do graphics
}
}
if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found
continue;
if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found
continue;
result =
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL);
if(result != VK_SUCCESS)
{
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
"vkEnumerateDeviceExtensionProperties(): %s\n",
quit(2);
}
if(deviceExtensionCount == 0)
continue;
if(deviceExtensionsAllocatedSize < deviceExtensionCount)
{
SDL_free(deviceExtensions);
deviceExtensionsAllocatedSize = deviceExtensionCount;
deviceExtensions =
SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize);
if(!deviceExtensions)
{
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
quit(2);
}
}
physicalDevice, NULL, &deviceExtensionCount, deviceExtensions);
if(result != VK_SUCCESS)
{
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
"vkEnumerateDeviceExtensionProperties(): %s\n",
quit(2);
}
for(i = 0; i < deviceExtensionCount; i++)
{
if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME))
{
hasSwapchainExtension = SDL_TRUE;
break;
}
}
if(!hasSwapchainExtension)
continue;
vulkanContext.physicalDevice = physicalDevice;
break;
}
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found");
quit(2);
}
}
static void getSurfaceFormats ( void  )
static

Definition at line 608 of file testvulkan.c.

References getVulkanResultString(), NULL, VulkanContext::physicalDevice, quit(), SDL_free, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_malloc, SDL_OutOfMemory, VulkanContext::surface, VulkanContext::surfaceFormats, VulkanContext::surfaceFormatsAllocatedCount, VulkanContext::surfaceFormatsCount, VK_SUCCESS, and vkGetPhysicalDeviceSurfaceFormatsKHR().

Referenced by createNewSwapchainAndSwapchainSpecificStuff().

static const char* getVulkanResultString ( VkResult  result)
static

Definition at line 111 of file testvulkan.c.

References VK_ERROR_DEVICE_LOST, VK_ERROR_EXTENSION_NOT_PRESENT, VK_ERROR_FEATURE_NOT_PRESENT, VK_ERROR_FORMAT_NOT_SUPPORTED, VK_ERROR_FRAGMENTED_POOL, VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, VK_ERROR_INCOMPATIBLE_DRIVER, VK_ERROR_INITIALIZATION_FAILED, VK_ERROR_INVALID_SHADER_NV, VK_ERROR_LAYER_NOT_PRESENT, VK_ERROR_MEMORY_MAP_FAILED, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, VK_ERROR_OUT_OF_DATE_KHR, VK_ERROR_OUT_OF_DEVICE_MEMORY, VK_ERROR_OUT_OF_HOST_MEMORY, VK_ERROR_OUT_OF_POOL_MEMORY_KHR, VK_ERROR_SURFACE_LOST_KHR, VK_ERROR_TOO_MANY_OBJECTS, VK_ERROR_VALIDATION_FAILED_EXT, VK_EVENT_RESET, VK_EVENT_SET, VK_INCOMPLETE, VK_NOT_READY, VK_RESULT_MAX_ENUM, VK_RESULT_RANGE_SIZE, VK_SUBOPTIMAL_KHR, VK_SUCCESS, and VK_TIMEOUT.

Referenced by createCommandBuffers(), createCommandPool(), createDevice(), createFences(), createInstance(), createSemaphore(), createSwapchain(), findPhysicalDevice(), getSurfaceCaps(), getSurfaceFormats(), getSwapchainImages(), render(), and rerecordCommandBuffer().

{
switch((int)result)
{
case VK_SUCCESS:
return "VK_SUCCESS";
return "VK_NOT_READY";
case VK_TIMEOUT:
return "VK_TIMEOUT";
return "VK_EVENT_SET";
return "VK_EVENT_RESET";
return "VK_INCOMPLETE";
return "VK_ERROR_OUT_OF_HOST_MEMORY";
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
return "VK_ERROR_INITIALIZATION_FAILED";
return "VK_ERROR_DEVICE_LOST";
return "VK_ERROR_MEMORY_MAP_FAILED";
return "VK_ERROR_LAYER_NOT_PRESENT";
return "VK_ERROR_EXTENSION_NOT_PRESENT";
return "VK_ERROR_FEATURE_NOT_PRESENT";
return "VK_ERROR_INCOMPATIBLE_DRIVER";
return "VK_ERROR_TOO_MANY_OBJECTS";
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
return "VK_ERROR_FRAGMENTED_POOL";
return "VK_ERROR_SURFACE_LOST_KHR";
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
return "VK_SUBOPTIMAL_KHR";
return "VK_ERROR_OUT_OF_DATE_KHR";
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
return "VK_ERROR_VALIDATION_FAILED_EXT";
return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR";
return "VK_ERROR_INVALID_SHADER_NV";
break;
}
if(result < 0)
return "VK_ERROR_<Unknown>";
return "VK_<Unknown>";
}
static void loadDeviceFunctions ( void  )
static

Definition at line 529 of file testvulkan.c.

References VULKAN_FUNCTIONS.

Referenced by initVulkan().

{
#define VULKAN_DEVICE_FUNCTION(name) \
name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name); \
if(!name) \
{ \
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
"vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
quit(2); \
}
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name)
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}
static void loadGlobalFunctions ( void  )
static

Definition at line 218 of file testvulkan.c.

References quit(), SDL_GetError, SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_Vulkan_GetVkGetInstanceProcAddr, and VULKAN_FUNCTIONS.

Referenced by initVulkan().

{
{
"SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n",
quit(2);
}
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name) \
name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
if(!name) \
{ \
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
"vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
quit(2); \
}
#define VULKAN_INSTANCE_FUNCTION(name)
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}
static void loadInstanceFunctions ( void  )
static

Definition at line 293 of file testvulkan.c.

References VULKAN_FUNCTIONS.

Referenced by initVulkan().

{
#define VULKAN_DEVICE_FUNCTION(name)
#define VULKAN_GLOBAL_FUNCTION(name)
#define VULKAN_INSTANCE_FUNCTION(name) \
name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name); \
if(!name) \
{ \
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \
"vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
quit(2); \
}
#undef VULKAN_DEVICE_FUNCTION
#undef VULKAN_GLOBAL_FUNCTION
#undef VULKAN_INSTANCE_FUNCTION
}
int main ( int  argc,
char *  argv[] 
)

Definition at line 1119 of file testvulkan.c.

References done, SDL_DisplayMode::format, i, initVulkan(), SDLTest_CommonState::num_windows, quit(), render(), SDL_BITSPERPIXEL, SDL_GetCurrentDisplayMode, SDL_GetTicks(), SDL_GetWindowSize, SDL_INIT_VIDEO, SDL_Log, SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, SDL_LogSetPriority, SDL_PollEvent, SDL_Vulkan_GetDrawableSize, SDL_WINDOW_VULKAN, SDLTest_CommonArg(), SDLTest_CommonCreateState(), SDLTest_CommonEvent(), SDLTest_CommonInit(), SDLTest_CommonUsage(), SDLTest_CommonState::skip_renderer, SDLTest_CommonState::window_flags, and SDLTest_CommonState::windows.

{
int fsaa, accel;
int i, done;
Uint32 then, now, frames;
int dw, dh;
/* Enable standard application logging */
/* Initialize parameters */
fsaa = 0;
accel = -1;
/* Initialize test framework */
if(!state)
{
return 1;
}
for(i = 1; i < argc;)
{
int consumed;
consumed = SDLTest_CommonArg(state, i);
if(consumed < 0)
{
SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
quit(1);
}
i += consumed;
}
/* Set Vulkan parameters */
state->window_flags |= SDL_WINDOW_VULKAN;
state->num_windows = 1;
state->skip_renderer = 1;
{
quit(2);
}
SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
SDL_GetWindowSize(state->windows[0], &dw, &dh);
SDL_Log("Window Size : %d,%d\n", dw, dh);
SDL_Vulkan_GetDrawableSize(state->windows[0], &dw, &dh);
SDL_Log("Draw Size : %d,%d\n", dw, dh);
SDL_Log("\n");
/* Main render loop */
frames = 0;
then = SDL_GetTicks();
done = 0;
while(!done)
{
/* Check for events */
++frames;
while(SDL_PollEvent(&event))
{
SDLTest_CommonEvent(state, &event, &done);
}
if(!done)
render();
}
/* Print out some timing information */
now = SDL_GetTicks();
if(now > then)
{
SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then));
}
quit(0);
return 0;
}
static void quit ( int  rc)
static

Definition at line 211 of file testvulkan.c.

References SDLTest_CommonQuit(), and shutdownVulkan().

static void recordPipelineImageBarrier ( VkCommandBuffer  commandBuffer,
VkAccessFlags  sourceAccessMask,
VkAccessFlags  destAccessMask,
VkImageLayout  sourceLayout,
VkImageLayout  destLayout,
VkImage  image 
)
static

Definition at line 879 of file testvulkan.c.

References VkImageSubresourceRange::aspectMask, VkImageSubresourceRange::baseArrayLayer, VkImageSubresourceRange::baseMipLevel, VkImageMemoryBarrier::dstAccessMask, VkImageMemoryBarrier::dstQueueFamilyIndex, VkImageMemoryBarrier::image, VkImageSubresourceRange::layerCount, VkImageSubresourceRange::levelCount, VkImageMemoryBarrier::newLayout, NULL, VkImageMemoryBarrier::oldLayout, VkImageMemoryBarrier::srcAccessMask, VkImageMemoryBarrier::srcQueueFamilyIndex, VkImageMemoryBarrier::sType, VkImageMemoryBarrier::subresourceRange, VK_IMAGE_ASPECT_COLOR_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_QUEUE_FAMILY_IGNORED, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, and vkCmdPipelineBarrier().

Referenced by rerecordCommandBuffer().

static SDL_bool render ( void  )
static

Definition at line 1023 of file testvulkan.c.

References VkSubmitInfo::commandBufferCount, VulkanContext::commandBuffers, createNewSwapchainAndSwapchainSpecificStuff(), VulkanContext::device, VulkanContext::fences, VkClearColorValue::float32, getVulkanResultString(), VulkanContext::graphicsQueue, VkExtent2D::height, VulkanContext::imageAvailableSemaphore, VkSubmitInfo::pCommandBuffers, VkPresentInfoKHR::pImageIndices, VulkanContext::presentQueue, VkSubmitInfo::pSignalSemaphores, VkPresentInfoKHR::pSwapchains, VkSubmitInfo::pWaitDstStageMask, VkSubmitInfo::pWaitSemaphores, VkPresentInfoKHR::pWaitSemaphores, quit(), VulkanContext::renderingFinishedSemaphore, rerecordCommandBuffer(), retval, SDL_Delay, SDL_GetPerformanceCounter, SDL_GetPerformanceFrequency(), SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, SDL_sin, SDL_TRUE, SDL_Vulkan_GetDrawableSize, VkSubmitInfo::signalSemaphoreCount, VkSubmitInfo::sType, VkPresentInfoKHR::sType, VulkanContext::swapchain, VkPresentInfoKHR::swapchainCount, VulkanContext::swapchainSize, UINT64_MAX, VK_ERROR_OUT_OF_DATE_KHR, VK_FALSE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, VK_STRUCTURE_TYPE_SUBMIT_INFO, VK_SUBOPTIMAL_KHR, VK_SUCCESS, vkAcquireNextImageKHR(), vkQueuePresentKHR(), vkQueueSubmit(), vkResetFences(), vkWaitForFences(), VkSubmitInfo::waitSemaphoreCount, VkPresentInfoKHR::waitSemaphoreCount, VkExtent2D::width, and SDLTest_CommonState::windows.

{
uint32_t frameIndex;
double currentTime;
VkClearColorValue clearColor = {0};
VkSubmitInfo submitInfo = {0};
VkPresentInfoKHR presentInfo = {0};
int w, h;
{
if(!retval)
SDL_Delay(100);
return retval;
}
&frameIndex);
if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS)
{
"vkAcquireNextImageKHR(): %s\n",
quit(2);
}
result = vkWaitForFences(
if(result != VK_SUCCESS)
{
SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result));
quit(2);
}
if(result != VK_SUCCESS)
{
SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result));
quit(2);
}
clearColor.float32[0] = (float)(0.5 + 0.5 * SDL_sin(currentTime));
clearColor.float32[1] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 2 / 3));
clearColor.float32[2] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 4 / 3));
clearColor.float32[3] = 1;
rerecordCommandBuffer(frameIndex, &clearColor);
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitDstStageMask = &waitDestStageMask;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex];
submitInfo.signalSemaphoreCount = 1;
result = vkQueueSubmit(
vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]);
if(result != VK_SUCCESS)
{
SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result));
quit(2);
}
presentInfo.waitSemaphoreCount = 1;
presentInfo.swapchainCount = 1;
presentInfo.pImageIndices = &frameIndex;
result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo);
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
{
}
if(result != VK_SUCCESS)
{
"vkQueuePresentKHR(): %s\n",
quit(2);
}
SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h);
{
}
return SDL_TRUE;
}
static void rerecordCommandBuffer ( uint32_t  frameIndex,
const VkClearColorValue clearColor 
)
static

Definition at line 912 of file testvulkan.c.

References VkImageSubresourceRange::aspectMask, VkImageSubresourceRange::baseArrayLayer, VkImageSubresourceRange::baseMipLevel, VulkanContext::commandBuffers, VkCommandBufferBeginInfo::flags, getVulkanResultString(), VkImageSubresourceRange::layerCount, VkImageSubresourceRange::levelCount, quit(), recordPipelineImageBarrier(), SDL_LOG_CATEGORY_APPLICATION, SDL_LogError, VkCommandBufferBeginInfo::sType, VulkanContext::swapchainImages, VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_UNDEFINED, VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, VK_SUCCESS, vkBeginCommandBuffer(), vkCmdClearColorImage(), vkEndCommandBuffer(), and vkResetCommandBuffer().

Referenced by render().

{
VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex];
VkImage image = vulkanContext.swapchainImages[frameIndex];
VkCommandBufferBeginInfo beginInfo = {0};
VkImageSubresourceRange clearRange = {0};
VkResult result = vkResetCommandBuffer(commandBuffer, 0);
if(result != VK_SUCCESS)
{
"vkResetCommandBuffer(): %s\n",
quit(2);
}
result = vkBeginCommandBuffer(commandBuffer, &beginInfo);
if(result != VK_SUCCESS)
{
"vkBeginCommandBuffer(): %s\n",
quit(2);
}
0,
image);
clearRange.baseMipLevel = 0;
clearRange.levelCount = 1;
clearRange.baseArrayLayer = 0;
clearRange.layerCount = 1;
commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange);
image);
result = vkEndCommandBuffer(commandBuffer);
if(result != VK_SUCCESS)
{
"vkEndCommandBuffer(): %s\n",
quit(2);
}
}

Variable Documentation

SDLTest_CommonState* state
static

Definition at line 205 of file testvulkan.c.

PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL
static

Definition at line 94 of file testvulkan.c.

VulkanContext vulkanContext = {0}
static

Definition at line 206 of file testvulkan.c.