static int create_surface(void);
static int choose_phys_dev(void);
static int create_device(void);
+static int create_swapchain(void);
+
static int choose_pixfmt(void);
static int eval_pdev_score(VkPhysicalDevice dev);
static int have_inst_layer(const char *name);
static VkSurfaceFormatKHR *vksurf_fmt;
static VkSwapchainKHR vksc;
static int vksc_numimg;
+static VkImage *vksc_img;
+static VkExtent2D vksc_extent;
+static VkImageView *vksc_view;
static VkLayerProperties *inst_layers;
static VkExtensionProperties *inst_ext, *dev_ext;
void vk_cleanup(void)
{
- vkDestroyInstance(vk, 0);
+ int i;
+
+ free(vksc_img);
+ vksc_img = 0;
+ free(vksc_view);
+ vksc_view = 0;
+ if(vksc_view) {
+ for(i=0; i<vksc_numimg; i++) {
+ vkDestroyImageView(vkdev, vksc_view[i], 0);
+ }
+ vksc_view = 0;
+ }
+ if(vksc) {
+ vkDestroySwapchainKHR(vkdev, vksc, 0);
+ vksc = 0;
+ }
+ if(vkdev) {
+ vkDestroyDevice(vkdev, 0);
+ vkdev = 0;
+ }
+ if(vksurf) {
+ vkDestroySurfaceKHR(vk, vksurf, 0);
+ vksurf = 0;
+ }
+ if(vk) {
+ vkDestroyInstance(vk, 0);
+ vk = 0;
+ }
free(inst_layers);
+ inst_layers = 0;
free(inst_ext);
+ inst_ext = 0;
+ free(dev_ext);
+ dev_ext = 0;
free(pdev_list);
+ pdev_list = 0;
}
+int vk_reshape(int xsz, int ysz)
+{
+ int i;
+
+ if(vksc && vksc_extent.width == xsz && vksc_extent.height == ysz) {
+ return 0;
+ }
+
+ if(vksc_view) {
+ for(i=0; i<vksc_numimg; i++) {
+ vkDestroyImageView(vkdev, vksc_view[i], 0);
+ }
+ }
+ if(vksc) vkDestroySwapchainKHR(vkdev, vksc, 0);
+
+ vksc_extent.width = xsz;
+ vksc_extent.height = ysz;
+
+ return create_swapchain();
+}
#define ARRSZ(arr) (sizeof arr / sizeof *arr)
static const char *known_layer_list[] = {
VkPhysicalDevice *pdev;
VkPhysicalDeviceProperties pdevprop;
VkQueueFamilyProperties *qfam;
+ VkBool32 can_pres;
vkEnumeratePhysicalDevices(vk, &num_pdev, 0);
if(!num_pdev) {
}
vkpdev = pdev[best_dev];
- vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, 0);
+ vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, 0);
qfam = malloc_nf(num_qfam * sizeof *qfam);
- vkGetPhysicalDeviceQueueFamilyProperties(dev, &num_qfam, qfam);
+ vkGetPhysicalDeviceQueueFamilyProperties(vkpdev, &num_qfam, qfam);
vkqfam_idx = -1;
for(i=0; i<num_qfam; i++) {
- vkGetPhysicalDeviceSurfaceSupportKHR(dev, i, vksurf, &can_pres);
+ vkGetPhysicalDeviceSurfaceSupportKHR(vkpdev, i, vksurf, &can_pres);
if(qfam[i].queueCount && (qfam[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && can_pres) {
vkqfam_maxq = qfam[i].queueCount;
vkqfam_idx = i;
dev_ext = malloc_nf(dev_ext_count * sizeof *dev_ext);
vkEnumerateDeviceExtensionProperties(vkpdev, 0, &dev_ext_count, dev_ext);
+ num_ext = 0;
for(i=0; i<ARRSZ(known_devext_list); i++) {
if(have_ext(dev_ext, dev_ext_count, known_devext_list[i].name)) {
ext[num_ext++] = known_devext_list[i].name;
static int create_swapchain(void)
{
+ int i;
uint32_t num;
- VkSwapchainCreateInfoKHR scinf;
+ VkSwapchainCreateInfoKHR scinf = {0};
+ VkImageViewCreateInfo ivinf;
- vksc_extent.width = win_width;
- vksc_extent.height = win_height;
+ if(vksc_extent.width <= 0 || vksc_extent.height <= 0) {
+ return -1;
+ }
- memset(&scinf, 0, sizeof scinf);
scinf.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
scinf.surface = vksurf;
scinf.minImageCount = 2;
return -1;
}
- vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
- vksc_img = malloc_nf(num * sizeof *vksc_img);
- vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+ if(!vksc_img || vksc_numimg != num) {
+ free(vksc_img);
+ vkGetSwapchainImagesKHR(vkdev, vksc, &num, 0);
+ vksc_img = malloc_nf(num * sizeof *vksc_img);
+ vkGetSwapchainImagesKHR(vkdev, vksc, &num, vksc_img);
+ }
+ if(!vksc_view || vksc_numimg != num) {
+ free(vksc_view);
+ vksc_view = malloc_nf(num * sizeof *vksc_view);
+ }
vksc_numimg = num;
+ for(i=0; i<num; i++) {
+ memset(&ivinf, 0, sizeof ivinf);
+ ivinf.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ ivinf.image = vksc_img[i];
+ ivinf.format = vksurf_fmt[vksurf_selfmt].format;
+ ivinf.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ivinf.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ivinf.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ivinf.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
+ ivinf.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ ivinf.subresourceRange.levelCount = 1;
+ ivinf.subresourceRange.layerCount = 1;
+ ivinf.viewType = VK_IMAGE_VIEW_TYPE_2D;
+
+ if(vkCreateImageView(vkdev, &ivinf, 0, vksc_view + i) != 0) {
+ fprintf(stderr, "failed to create image view (%d)\n", i);
+ return -1;
+ }
+ }
return 0;
}
};
int i, j;
uint32_t num_fmt;
- VkSurfaceFormatKHR *sfmt;
vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, 0);
if(!num_fmt) return -1;
- sfmt = malloc_nf(num_fmt * sizeof *sfmt);
- vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, sfmt);
+ vksurf_fmt = malloc_nf(num_fmt * sizeof *vksurf_fmt);
+ vkGetPhysicalDeviceSurfaceFormatsKHR(vkpdev, vksurf, &num_fmt, vksurf_fmt);
vksurf_selfmt = 0;
for(i=0; i<num_fmt; i++) {
- if(sfmt[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
+ if(vksurf_fmt[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
continue;
}
for(j=0; j<sizeof pref / sizeof *pref; j++) {
- if(sfmt[i].format == pref[j]) {
+ if(vksurf_fmt[i].format == pref[j]) {
vksurf_selfmt = i;
- free(sfmt);
+ vksurf_numfmt = num_fmt;
return i;
}
}
}
- free(sfmt);
+ free(vksurf_fmt);
+ vksurf_fmt = 0;
return -1;
}