summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-09-19 19:04:09 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-09-19 19:04:09 -0400
commite966fc36c684de7e1f1477cfdd7d50c2da374bad (patch)
tree31ec56e6713752e345e80987bed6df82c2733968
parent2a66b641c1540e297b56e87ca87f10382aa6edd0 (diff)
filling out render pass - color resolve and depth
-rw-r--r--src/entities.cpp5
-rw-r--r--src/window.cpp234
-rw-r--r--src/window.hpp5
3 files changed, 191 insertions, 53 deletions
diff --git a/src/entities.cpp b/src/entities.cpp
index 8d9206b..70b3a58 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -257,12 +257,11 @@ void EntityType_Init() {
VkPipelineRasterizationStateCreateInfo vkPipelineRasterizationStateCreateInfoLine{vkPipelineRasterizationStateCreateInfoFill};
vkPipelineRasterizationStateCreateInfoLine.polygonMode = VK_POLYGON_MODE_LINE;
- // TODO MultiSampling
VkPipelineMultisampleStateCreateInfo vkPipelineMultisampleStateCreateInfo;
vkPipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
vkPipelineMultisampleStateCreateInfo.pNext = nullptr;
vkPipelineMultisampleStateCreateInfo.flags = 0;
- vkPipelineMultisampleStateCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+ vkPipelineMultisampleStateCreateInfo.rasterizationSamples = renderSampleCount;
vkPipelineMultisampleStateCreateInfo.sampleShadingEnable = VK_FALSE;
vkPipelineMultisampleStateCreateInfo.minSampleShading = 0.0f;
vkPipelineMultisampleStateCreateInfo.pSampleMask = nullptr;
@@ -363,7 +362,7 @@ void EntityType_Init() {
vkGraphicsPipelineCreateInfo[i].pColorBlendState = &vkPipelineColorBlendStateCreateInfo;
vkGraphicsPipelineCreateInfo[i].pDynamicState = &vkPipelineDynamicStateCreateInfo;
vkGraphicsPipelineCreateInfo[i].layout = vkPipelineLayout_Texture;
- vkGraphicsPipelineCreateInfo[i].renderPass = vkRenderPass;
+ vkGraphicsPipelineCreateInfo[i].renderPass = renderRenderPass;
vkGraphicsPipelineCreateInfo[i].subpass = 0;
vkGraphicsPipelineCreateInfo[i].basePipelineHandle = VK_NULL_HANDLE;
vkGraphicsPipelineCreateInfo[i].basePipelineIndex = {};
diff --git a/src/window.cpp b/src/window.cpp
index 5d71e98..de1a6ea 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -38,6 +38,7 @@ unsigned int selectedPresentIndex = -1u;
unsigned int swapchainLength = 0u;
VkSwapchainKHR vkSwapchainKHR = VK_NULL_HANDLE;
VkSurfaceFormatKHR vkSurfaceFormatKHR;
+VkFormat depthFormat;
VkPresentModeKHR vkPresentModeKHR;
VkExtent2D extent;
VkImage *swapchainImages = nullptr;
@@ -45,9 +46,16 @@ VkImageView *swapchainImageViews = nullptr;
VkImage *renderImages = nullptr;
VkImageView *renderImageViews = nullptr;
VkDeviceMemory renderImagesMemory;
-VkBuffer renderImagesBuffer;
+VkImage *colorImages = nullptr;
+VkImageView *colorImageViews = nullptr;
+VkDeviceMemory colorImagesMemory;
+VkImage *depthImages = nullptr;
+VkImageView *depthImageViews = nullptr;
+VkDeviceMemory depthImagesMemory;
VkSampler presentSampler;
+VkSampleCountFlagBits renderSampleCount;
VkRenderPass presentRenderPass;
+VkRenderPass renderRenderPass;
VkDescriptorSetLayout vkDescriptorSetLayout;
VkDescriptorPool presentDescriptorPool;
VkDescriptorSet presentDescriptorSets[MAX_FRAMES_IN_FLIGHT];
@@ -115,6 +123,20 @@ unsigned int FindMemoryTypeIndex(uint32_t typeFilter, VkMemoryPropertyFlags memP
return 0;
}
+VkFormat FindSupportedFormat(long candidateCount, const VkFormat *candidates, VkImageTiling tiling, VkFormatFeatureFlags flags) {
+ for (long i = 0; i < candidateCount; ++i) {
+ VkFormatProperties props;
+ vkGetPhysicalDeviceFormatProperties(vkPhysicalDevice, candidates[i], &props);
+ if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & flags) == flags) {
+ return candidates[i];
+ } else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & flags) == flags) {
+ return candidates[i];
+ }
+ }
+ fprintf(stdout, "[vulkan] Failed to find appropriate format: tiling: %u - flags: %u\n", tiling, flags);
+ return VkFormat(0);
+}
+
void BeginTransferBuffer(VkDeviceSize requestedMemorySize, VkBuffer &buffer, VkDeviceMemory &deviceMemory, void *&deviceData) {
VkBufferCreateInfo transferBufferCI;
transferBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -432,6 +454,35 @@ void InitVulkan() {
vkGetDeviceQueue(vkDevice, transferFamilyIndex, 0, &transferQueue);
}
+ // surface formats
+ {
+ VkFormat acceptableDepthFormats[3] = {
+ VK_FORMAT_D32_SFLOAT,
+ VK_FORMAT_D32_SFLOAT_S8_UINT,
+ VK_FORMAT_D24_UNORM_S8_UINT,
+ };
+ depthFormat = FindSupportedFormat(3, acceptableDepthFormats, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
+ }
+
+ // sampler
+ {
+ VkSampleCountFlags counts = vkPhysicalDeviceProperties.limits.framebufferColorSampleCounts & vkPhysicalDeviceProperties.limits.framebufferDepthSampleCounts;
+
+ if (counts & VK_SAMPLE_COUNT_64_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_64_BIT;
+ } else if (counts & VK_SAMPLE_COUNT_32_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_32_BIT;
+ } else if (counts & VK_SAMPLE_COUNT_16_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_16_BIT;
+ } else if (counts & VK_SAMPLE_COUNT_8_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_8_BIT;
+ } else if (counts & VK_SAMPLE_COUNT_4_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_4_BIT;
+ } else if (counts & VK_SAMPLE_COUNT_2_BIT) {
+ renderSampleCount = VK_SAMPLE_COUNT_2_BIT;
+ }
+ }
+
// generic present sampler
VkSamplerCreateInfo samplerCreateInfo;
samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
@@ -456,6 +507,36 @@ void InitVulkan() {
vkCreateSampler(vkDevice, &samplerCreateInfo, vkAllocator, &presentSampler);
}
+void CreateImageResources_Inner(VkImageCreateInfo *imageCreateInfo, VkImageViewCreateInfo *imageViewCreateInfo, VkBufferUsageFlagBits bufferUsageFlagBits, VkBuffer *imagesBuffer, VkImage *images, VkImageView *imageViews, VkDeviceMemory *deviceMemory) {
+ VkImage tmpImage;
+ vkCreateImage(vkDevice, imageCreateInfo, vkAllocator, &tmpImage);
+
+ VkMemoryRequirements imageMemoryRequirements;
+ vkGetImageMemoryRequirements(vkDevice, tmpImage, &imageMemoryRequirements);
+
+ VkDeviceSize paddedImageSize = imageMemoryRequirements.size + (imageMemoryRequirements.alignment - (imageMemoryRequirements.size % imageMemoryRequirements.alignment));
+ assert(paddedImageSize % imageMemoryRequirements.alignment == 0);
+
+ vkDestroyImage(vkDevice, tmpImage, vkAllocator);
+
+ VkMemoryAllocateInfo vkMemoryAllocateInfo{};
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+ vkMemoryAllocateInfo.allocationSize = paddedImageSize * MAX_FRAMES_IN_FLIGHT;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemoryRequirements.memoryTypeBits,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, deviceMemory);
+
+ for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
+ vkCreateImage(vkDevice, imageCreateInfo, vkAllocator, &images[i]);
+ vkBindImageMemory(vkDevice, images[i], *deviceMemory, paddedImageSize * i);
+
+ imageViewCreateInfo->image = images[i];
+ vkCreateImageView(vkDevice, imageViewCreateInfo, vkAllocator, &imageViews[i]);
+ }
+}
+
void CreateSwapchain() {
VkSurfaceCapabilitiesKHR surfaceCapabilities;
@@ -594,56 +675,33 @@ void CreateSwapchain() {
renderTargetImageCI.pQueueFamilyIndices = nullptr;
renderTargetImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- VkImage tmpImage;
- vkCreateImage(vkDevice, &renderTargetImageCI, vkAllocator, &tmpImage);
-
- VkMemoryRequirements imageMemoryRequirements;
- vkGetImageMemoryRequirements(vkDevice, tmpImage, &imageMemoryRequirements);
-
- VkDeviceSize paddedImageSize = imageMemoryRequirements.size + (imageMemoryRequirements.alignment - (imageMemoryRequirements.size % imageMemoryRequirements.alignment));
- assert(paddedImageSize % imageMemoryRequirements.alignment == 0);
-
- vkDestroyImage(vkDevice, tmpImage, vkAllocator);
-
- VkBufferCreateInfo imageBufferCI{};
- imageBufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- imageBufferCI.pNext = nullptr;
- imageBufferCI.flags = 0;
- imageBufferCI.size = paddedImageSize * MAX_FRAMES_IN_FLIGHT;
- imageBufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
- imageBufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- imageBufferCI.queueFamilyIndexCount = 0;
- imageBufferCI.pQueueFamilyIndices = nullptr;
- vkCreateBuffer(vkDevice, &imageBufferCI, vkAllocator, &renderImagesBuffer);
-
- VkMemoryAllocateInfo vkMemoryAllocateInfo{};
- vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- vkMemoryAllocateInfo.pNext = nullptr;
- vkMemoryAllocateInfo.allocationSize = imageBufferCI.size;
- vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(imageMemoryRequirements.memoryTypeBits,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-
- vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &renderImagesMemory);
-
- vkBindBufferMemory(vkDevice, renderImagesBuffer, renderImagesMemory, 0);
-
+ // render images
renderImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT);
renderImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT);
-
- for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
- vkCreateImage(vkDevice, &renderTargetImageCI, vkAllocator, &renderImages[i]);
- vkBindImageMemory(vkDevice, renderImages[i], renderImagesMemory, paddedImageSize * i);
-
- vkImageViewCreateInfo.image = renderImages[i];
- vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &renderImageViews[i]);
- }
+ CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, renderImages, renderImageViews, &renderImagesMemory);
+
+ // color images
+ colorImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT);
+ colorImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT);
+ renderTargetImageCI.samples = renderSampleCount;
+ renderTargetImageCI.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, colorImages, colorImageViews, &colorImagesMemory);
+
+ // depth images
+ depthImages = Pke_New<VkImage>(MAX_FRAMES_IN_FLIGHT);
+ depthImageViews = Pke_New<VkImageView>(MAX_FRAMES_IN_FLIGHT);
+ renderTargetImageCI.format = depthFormat;
+ vkImageViewCreateInfo.format = depthFormat;
+ renderTargetImageCI.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ vkImageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ CreateImageResources_Inner(&renderTargetImageCI, &vkImageViewCreateInfo, VkBufferUsageFlagBits(0), nullptr, depthImages, depthImageViews, &depthImagesMemory);
}
void CreateRenderPass() {
VkAttachmentDescription colorAttachment;
colorAttachment.flags = {};
colorAttachment.format = vkSurfaceFormatKHR.format;
- colorAttachment.samples = VkSampleCountFlagBits::VK_SAMPLE_COUNT_1_BIT;
+ colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -658,12 +716,13 @@ void CreateRenderPass() {
VkSubpassDescription subpass;
subpass.flags = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
- subpass.inputAttachmentCount = {};
+ subpass.inputAttachmentCount = 0;
+ subpass.pInputAttachments = nullptr;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
subpass.pResolveAttachments = nullptr;
subpass.pDepthStencilAttachment = nullptr;
- subpass.preserveAttachmentCount = {};
+ subpass.preserveAttachmentCount = 0;
subpass.pPreserveAttachments = nullptr;
VkSubpassDependency subpassDependencies[2];
@@ -697,6 +756,61 @@ void CreateRenderPass() {
renderPassInfo.pDependencies = subpassDependencies;
if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &presentRenderPass) != VK_SUCCESS) {
+ throw "failed to create present render pass!";
+ }
+
+ colorAttachment.samples = renderSampleCount;
+ colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentDescription depthAttachment;
+ depthAttachment.flags = 0;
+ depthAttachment.format = depthFormat;
+ depthAttachment.samples = renderSampleCount;
+ depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+ depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+ depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentDescription colorAttachmentResolve{colorAttachment};
+ colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
+ colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+ colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+ colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ VkAttachmentReference depthAttachmentRef;
+ depthAttachmentRef.attachment = 1;
+ depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+ VkAttachmentReference colorAttachmentReseolveRef;
+ colorAttachmentReseolveRef.attachment = 2;
+ colorAttachmentReseolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+
+ subpass.pColorAttachments = &colorAttachmentRef;
+ subpass.pResolveAttachments = &colorAttachmentReseolveRef;
+ subpass.pDepthStencilAttachment = &depthAttachmentRef;
+
+ subpassDependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ subpassDependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ subpassDependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ subpassDependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+
+ subpassDependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ subpassDependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
+ subpassDependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+ subpassDependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+
+ VkAttachmentDescription attachments[3] = {
+ colorAttachment, depthAttachment, colorAttachmentResolve
+ };
+
+ renderPassInfo.attachmentCount = 3;
+ renderPassInfo.pAttachments = attachments;
+ renderPassInfo.dependencyCount = 2;
+ renderPassInfo.pDependencies = subpassDependencies;
+
+ if (vkCreateRenderPass(vkDevice, &renderPassInfo, vkAllocator, &renderRenderPass) != VK_SUCCESS) {
throw "failed to create render pass!";
}
}
@@ -969,10 +1083,20 @@ void CreateFramebuffers() {
if (result != VK_SUCCESS) {
throw "failed to create framebuffer";
}
- attachments[0] = renderImageViews[i];
- result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &renderImageFramebuffers[i]);
+ }
+
+ framebufferInfo.attachmentCount = 3;
+ framebufferInfo.renderPass = renderRenderPass;
+ for (long i = 0; i < swapchainLength; ++i) {
+ VkImageView attachments[] = {
+ colorImageViews[i],
+ depthImageViews[i],
+ renderImageViews[i],
+ };
+ framebufferInfo.pAttachments = attachments;
+ auto result = vkCreateFramebuffer(vkDevice, &framebufferInfo, vkAllocator, &renderImageFramebuffers[i]);
if (result != VK_SUCCESS) {
- throw "failed to create render framebuffer";
+ throw "failed to create framebuffer";
}
}
}
@@ -1268,12 +1392,23 @@ void DestroySwapchain() {
}
if (renderImageViews!= nullptr && renderImageViews != CAFE_BABE(VkImageView)) {
for (long i = 0; i < swapchainLength; ++i) {
+ vkDestroyImageView(vkDevice, depthImageViews[i], vkAllocator);
+ vkDestroyImage(vkDevice, depthImages[i], vkAllocator);
+
+ vkDestroyImageView(vkDevice, colorImageViews[i], vkAllocator);
+ vkDestroyImage(vkDevice, colorImages[i], vkAllocator);
+
vkDestroyImageView(vkDevice, renderImageViews[i], vkAllocator);
vkDestroyImage(vkDevice, renderImages[i], vkAllocator);
}
+ Pke_Delete<VkImageView>(depthImageViews, swapchainLength);
+ Pke_Delete<VkImage>(depthImages, swapchainLength);
+ Pke_Delete<VkImageView>(colorImageViews, swapchainLength);
+ Pke_Delete<VkImage>(colorImages, swapchainLength);
Pke_Delete<VkImageView>(renderImageViews, swapchainLength);
Pke_Delete<VkImage>(renderImages, swapchainLength);
- vkDestroyBuffer(vkDevice, renderImagesBuffer, vkAllocator);
+ vkFreeMemory(vkDevice, depthImagesMemory, vkAllocator);
+ vkFreeMemory(vkDevice, colorImagesMemory, vkAllocator);
vkFreeMemory(vkDevice, renderImagesMemory, vkAllocator);
}
if (swapchainImageViews!= nullptr && swapchainImageViews != CAFE_BABE(VkImageView)) {
@@ -1354,6 +1489,7 @@ void DestroyWindow() {
vkDestroyDescriptorPool(vkDevice, presentDescriptorPool, vkAllocator);
vkDestroyDescriptorPool(vkDevice, imGuiDescriptorPool, vkAllocator);
vkDestroyDescriptorSetLayout(vkDevice, vkDescriptorSetLayout, vkAllocator);
+ vkDestroyRenderPass(vkDevice, renderRenderPass, vkAllocator);
vkDestroyRenderPass(vkDevice, presentRenderPass, vkAllocator);
vkDestroySurfaceKHR(vkInstance, vkSurfaceKHR, vkAllocator);
vkDestroySampler(vkDevice, presentSampler, vkAllocator);
diff --git a/src/window.hpp b/src/window.hpp
index 84e3d33..a307671 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -25,6 +25,7 @@ extern VkInstance vkInstance;
extern VkPhysicalDevice vkPhysicalDevice;
extern VkPhysicalDeviceProperties vkPhysicalDeviceProperties;
extern VkSurfaceKHR vkSurfaceKHR;
+extern VkFormat depthFormat;
extern VkDevice vkDevice;
extern VkAllocationCallbacks *vkAllocator;
extern VkQueue graphicsQueue;
@@ -36,7 +37,9 @@ extern VkCommandBuffer transferCommandBuffer;
extern unsigned int graphicsFamilyIndex;
extern unsigned int presentFamilyIndex;
extern unsigned int transferFamilyIndex;
-extern VkRenderPass vkRenderPass;
+extern VkRenderPass presentRenderPass;
+extern VkRenderPass renderRenderPass;
+extern VkSampleCountFlagBits renderSampleCount;
struct PKEWindowProperties {
unsigned int width = 1280;