Surface initialization and destruction moved to KRSurface
This commit is contained in:
@@ -819,21 +819,7 @@ KRContext::destroyDeviceContexts()
|
|||||||
void
|
void
|
||||||
KRContext::destroySurfaces()
|
KRContext::destroySurfaces()
|
||||||
{
|
{
|
||||||
if (m_vulkanInstance == VK_NULL_HANDLE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
||||||
for (auto itr = m_surfaces.begin(); itr != m_surfaces.end(); itr++) {
|
|
||||||
KRSurface& surfaceInfo = (*itr).second;
|
|
||||||
KRDevice& deviceInfo = GetDeviceInfo(surfaceInfo.deviceHandle);
|
|
||||||
for (auto framebuffer : surfaceInfo.swapChainFramebuffers) {
|
|
||||||
vkDestroyFramebuffer(deviceInfo.m_logicalDevice, framebuffer, nullptr);
|
|
||||||
}
|
|
||||||
vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, surfaceInfo.swapChain, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo.m_logicalDevice, surfaceInfo.renderFinishedSemaphore, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo.m_logicalDevice, surfaceInfo.imageAvailableSemaphore, nullptr);
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, surfaceInfo.surface, nullptr);
|
|
||||||
}
|
|
||||||
m_surfaces.clear();
|
m_surfaces.clear();
|
||||||
m_surfaceHandleMap.clear();
|
m_surfaceHandleMap.clear();
|
||||||
}
|
}
|
||||||
@@ -923,6 +909,21 @@ void KRContext::removeResource(KRResource* resource)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KrSurfaceHandle KRContext::GetBestDeviceForSurface(const VkSurfaceKHR& surface)
|
||||||
|
{
|
||||||
|
KrDeviceHandle deviceHandle = 0;
|
||||||
|
for (auto itr = m_devices.begin(); itr != m_devices.end(); itr++) {
|
||||||
|
KRDevice& device = *(*itr).second;
|
||||||
|
VkBool32 canPresent = false;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(device.m_device, device.m_graphicsFamilyQueueIndex, surface, &canPresent);
|
||||||
|
if (canPresent) {
|
||||||
|
deviceHandle = (*itr).first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deviceHandle;
|
||||||
|
}
|
||||||
|
|
||||||
KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createWindowSurfaceInfo)
|
KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createWindowSurfaceInfo)
|
||||||
{
|
{
|
||||||
if (createWindowSurfaceInfo->surfaceHandle < 0) {
|
if (createWindowSurfaceInfo->surfaceHandle < 0) {
|
||||||
@@ -942,180 +943,19 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW
|
|||||||
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
||||||
const std::lock_guard<std::mutex> deviceLock(KRContext::g_DeviceInfoMutex);
|
const std::lock_guard<std::mutex> deviceLock(KRContext::g_DeviceInfoMutex);
|
||||||
|
|
||||||
KRDevice* deviceInfo = nullptr;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HWND hWnd = static_cast<HWND>(createWindowSurfaceInfo->hWnd);
|
HWND hWnd = static_cast<HWND>(createWindowSurfaceInfo->hWnd);
|
||||||
|
std::unique_ptr<KRSurface> info = std::make_unique<KRSurface>(*this, hWnd);
|
||||||
|
|
||||||
KRSurface info{};
|
KrResult initialize_result = info->initialize();
|
||||||
info.hWnd = hWnd;
|
if (initialize_result != KR_SUCCESS) {
|
||||||
|
return initialize_result;
|
||||||
VkWin32SurfaceCreateInfoKHR createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
|
||||||
createInfo.hinstance = GetModuleHandle(nullptr);
|
|
||||||
createInfo.hwnd = hWnd;
|
|
||||||
if (vkCreateWin32SurfaceKHR(m_vulkanInstance, &createInfo, nullptr, &info.surface) != VK_SUCCESS) {
|
|
||||||
return KR_ERROR_VULKAN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto itr = m_devices.begin(); itr != m_devices.end(); itr++) {
|
KRDevice* deviceInfo = &GetDeviceInfo(info->m_deviceHandle);
|
||||||
KRDevice& device = *(*itr).second;
|
|
||||||
VkBool32 canPresent = false;
|
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(device.m_device, device.m_graphicsFamilyQueueIndex, info.surface, &canPresent);
|
|
||||||
if (canPresent) {
|
|
||||||
info.deviceHandle = (*itr).first;
|
|
||||||
deviceInfo = &device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deviceInfo == nullptr) {
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, info.surface, nullptr);
|
|
||||||
return KR_ERROR_NO_DEVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
|
||||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
||||||
if (vkCreateSemaphore(deviceInfo->m_logicalDevice, &semaphoreInfo, nullptr, &info.imageAvailableSemaphore) != VK_SUCCESS) {
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, info.surface, nullptr);
|
|
||||||
return KR_ERROR_VULKAN;
|
|
||||||
}
|
|
||||||
if (vkCreateSemaphore(deviceInfo->m_logicalDevice, &semaphoreInfo, nullptr, &info.renderFinishedSemaphore) != VK_SUCCESS) {
|
|
||||||
vkDestroySemaphore(deviceInfo->m_logicalDevice, info.imageAvailableSemaphore, nullptr);
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, info.surface, nullptr);
|
|
||||||
return KR_ERROR_VULKAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(deviceInfo->m_device, info.surface, &surfaceCapabilities);
|
|
||||||
|
|
||||||
std::vector<VkSurfaceFormatKHR> surfaceFormats;
|
|
||||||
uint32_t formatCount = 0;
|
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, info.surface, &formatCount, nullptr);
|
|
||||||
|
|
||||||
|
|
||||||
if (formatCount != 0) {
|
|
||||||
surfaceFormats.resize(formatCount);
|
|
||||||
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, info.surface, &formatCount, surfaceFormats.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<VkPresentModeKHR> surfacePresentModes;
|
|
||||||
|
|
||||||
uint32_t presentModeCount = 0;
|
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(deviceInfo->m_device, info.surface, &presentModeCount, nullptr);
|
|
||||||
|
|
||||||
if (presentModeCount != 0) {
|
|
||||||
surfacePresentModes.resize(presentModeCount);
|
|
||||||
vkGetPhysicalDeviceSurfacePresentModesKHR(deviceInfo->m_device, info.surface, &presentModeCount, surfacePresentModes.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSurfaceFormatKHR selectedSurfaceFormat = surfaceFormats[0];
|
|
||||||
for (const auto& availableFormat : surfaceFormats) {
|
|
||||||
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
|
||||||
selectedSurfaceFormat = availableFormat;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// VK_PRESENT_MODE_FIFO_KHR is always available
|
|
||||||
VkPresentModeKHR selectedPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
|
||||||
|
|
||||||
// Try to find a better mode
|
|
||||||
for (const auto& availablePresentMode : surfacePresentModes) {
|
|
||||||
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
|
|
||||||
selectedPresentMode = availablePresentMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VkExtent2D swapExtent;
|
|
||||||
if (surfaceCapabilities.currentExtent.width != UINT32_MAX) {
|
|
||||||
swapExtent = surfaceCapabilities.currentExtent;
|
|
||||||
} else {
|
|
||||||
const uint32_t MAX_WIDTH = 8192;
|
|
||||||
const uint32_t MAX_HEIGHT = 8192;
|
|
||||||
swapExtent.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, MAX_WIDTH));
|
|
||||||
swapExtent.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, MAX_HEIGHT));
|
|
||||||
}
|
|
||||||
info.swapChainExtent = swapExtent;
|
|
||||||
|
|
||||||
uint32_t imageCount = surfaceCapabilities.minImageCount + 1;
|
|
||||||
if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) {
|
|
||||||
imageCount = surfaceCapabilities.maxImageCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swapChainCreateInfo{};
|
|
||||||
swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
|
||||||
swapChainCreateInfo.surface = info.surface;
|
|
||||||
swapChainCreateInfo.minImageCount = imageCount;
|
|
||||||
swapChainCreateInfo.imageFormat = selectedSurfaceFormat.format;
|
|
||||||
swapChainCreateInfo.imageColorSpace = selectedSurfaceFormat.colorSpace;
|
|
||||||
swapChainCreateInfo.imageExtent = swapExtent;
|
|
||||||
swapChainCreateInfo.imageArrayLayers = 1;
|
|
||||||
swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
|
|
||||||
uint32_t queueFamilyIndices[] = {
|
|
||||||
deviceInfo->m_graphicsFamilyQueueIndex,
|
|
||||||
deviceInfo->m_computeFamilyQueueIndex
|
|
||||||
};
|
|
||||||
if (deviceInfo->m_graphicsFamilyQueueIndex == deviceInfo->m_computeFamilyQueueIndex) {
|
|
||||||
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
swapChainCreateInfo.queueFamilyIndexCount = 0;
|
|
||||||
swapChainCreateInfo.pQueueFamilyIndices = nullptr;
|
|
||||||
} else {
|
|
||||||
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
|
||||||
swapChainCreateInfo.queueFamilyIndexCount = 2;
|
|
||||||
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
|
|
||||||
}
|
|
||||||
|
|
||||||
swapChainCreateInfo.preTransform = surfaceCapabilities.currentTransform;
|
|
||||||
swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
|
||||||
swapChainCreateInfo.presentMode = selectedPresentMode;
|
|
||||||
swapChainCreateInfo.clipped = VK_TRUE;
|
|
||||||
swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
if (vkCreateSwapchainKHR(deviceInfo->m_logicalDevice, &swapChainCreateInfo, nullptr, &info.swapChain) != VK_SUCCESS) {
|
|
||||||
vkDestroySemaphore(deviceInfo->m_logicalDevice, info.renderFinishedSemaphore, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo->m_logicalDevice, info.imageAvailableSemaphore, nullptr);
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, info.surface, nullptr);
|
|
||||||
return KR_ERROR_VULKAN_SWAP_CHAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
vkGetSwapchainImagesKHR(deviceInfo->m_logicalDevice, info.swapChain, &imageCount, nullptr);
|
|
||||||
info.swapChainImages.resize(imageCount);
|
|
||||||
vkGetSwapchainImagesKHR(deviceInfo->m_logicalDevice, info.swapChain, &imageCount, info.swapChainImages.data());
|
|
||||||
|
|
||||||
info.swapChainImageFormat = selectedSurfaceFormat.format;
|
|
||||||
|
|
||||||
info.swapChainImageViews.resize(info.swapChainImages.size());
|
|
||||||
for (size_t i = 0; i < info.swapChainImages.size(); i++) {
|
|
||||||
VkImageViewCreateInfo createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
|
||||||
createInfo.image = info.swapChainImages[i];
|
|
||||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
createInfo.format = info.swapChainImageFormat;
|
|
||||||
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
|
||||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
createInfo.subresourceRange.baseMipLevel = 0;
|
|
||||||
createInfo.subresourceRange.levelCount = 1;
|
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
|
||||||
if (vkCreateImageView(deviceInfo->m_logicalDevice, &createInfo, nullptr, &info.swapChainImageViews[i]) != VK_SUCCESS) {
|
|
||||||
for (size_t j = 0; j < i; j++) {
|
|
||||||
vkDestroyImageView(deviceInfo->m_logicalDevice, info.swapChainImageViews[j], nullptr);
|
|
||||||
}
|
|
||||||
vkDestroySemaphore(deviceInfo->m_logicalDevice, info.renderFinishedSemaphore, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo->m_logicalDevice, info.imageAvailableSemaphore, nullptr);
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, info.surface, nullptr);
|
|
||||||
return KR_ERROR_VULKAN_SWAP_CHAIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KrSurfaceHandle surfaceHandle = ++m_topSurfaceHandle;
|
KrSurfaceHandle surfaceHandle = ++m_topSurfaceHandle;
|
||||||
m_surfaces.insert(std::pair<KrSurfaceHandle, KRSurface>(surfaceHandle, info));
|
m_surfaces.insert(std::pair<KrSurfaceHandle, std::unique_ptr<KRSurface>>(surfaceHandle, std::move(info)));
|
||||||
|
|
||||||
|
|
||||||
m_surfaceHandleMap.insert(std::pair<KrSurfaceMapIndex, KrSurfaceHandle>(createWindowSurfaceInfo->surfaceHandle, surfaceHandle));
|
m_surfaceHandleMap.insert(std::pair<KrSurfaceMapIndex, KrSurfaceHandle>(createWindowSurfaceInfo->surfaceHandle, surfaceHandle));
|
||||||
|
|
||||||
@@ -1123,12 +963,12 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW
|
|||||||
|
|
||||||
{
|
{
|
||||||
KRPipeline* testPipeline = m_pPipelineManager->get("vulkan_test");
|
KRPipeline* testPipeline = m_pPipelineManager->get("vulkan_test");
|
||||||
KRSurface& surface = m_surfaces[surfaceHandle];
|
KRSurface& surface = *m_surfaces[surfaceHandle];
|
||||||
surface.swapChainFramebuffers.resize(surface.swapChainImageViews.size());
|
surface.m_swapChainFramebuffers.resize(surface.m_swapChainImageViews.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < surface.swapChainImageViews.size(); i++) {
|
for (size_t i = 0; i < surface.m_swapChainImageViews.size(); i++) {
|
||||||
VkImageView attachments[] = {
|
VkImageView attachments[] = {
|
||||||
surface.swapChainImageViews[i]
|
surface.m_swapChainImageViews[i]
|
||||||
};
|
};
|
||||||
|
|
||||||
VkFramebufferCreateInfo framebufferInfo{};
|
VkFramebufferCreateInfo framebufferInfo{};
|
||||||
@@ -1136,11 +976,11 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW
|
|||||||
framebufferInfo.renderPass = testPipeline->getRenderPass();
|
framebufferInfo.renderPass = testPipeline->getRenderPass();
|
||||||
framebufferInfo.attachmentCount = 1;
|
framebufferInfo.attachmentCount = 1;
|
||||||
framebufferInfo.pAttachments = attachments;
|
framebufferInfo.pAttachments = attachments;
|
||||||
framebufferInfo.width = surface.swapChainExtent.width;
|
framebufferInfo.width = surface.m_swapChainExtent.width;
|
||||||
framebufferInfo.height = surface.swapChainExtent.height;
|
framebufferInfo.height = surface.m_swapChainExtent.height;
|
||||||
framebufferInfo.layers = 1;
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
if (vkCreateFramebuffer(deviceInfo->m_logicalDevice, &framebufferInfo, nullptr, &surface.swapChainFramebuffers[i]) != VK_SUCCESS) {
|
if (vkCreateFramebuffer(deviceInfo->m_logicalDevice, &framebufferInfo, nullptr, &surface.m_swapChainFramebuffers[i]) != VK_SUCCESS) {
|
||||||
// TODO - Error Handling
|
// TODO - Error Handling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1173,15 +1013,6 @@ KrResult KRContext::deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteW
|
|||||||
if (itr == m_surfaces.end()) {
|
if (itr == m_surfaces.end()) {
|
||||||
return KR_ERROR_NOT_FOUND;
|
return KR_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
KRSurface* surfaceInfo = &(*itr).second;
|
|
||||||
KRDevice& deviceInfo = GetDeviceInfo(surfaceInfo->deviceHandle);
|
|
||||||
for (auto imageView : surfaceInfo->swapChainImageViews) {
|
|
||||||
vkDestroyImageView(deviceInfo.m_logicalDevice, imageView, nullptr);
|
|
||||||
}
|
|
||||||
vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, surfaceInfo->swapChain, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo.m_logicalDevice, surfaceInfo->renderFinishedSemaphore, nullptr);
|
|
||||||
vkDestroySemaphore(deviceInfo.m_logicalDevice, surfaceInfo->imageAvailableSemaphore, nullptr);
|
|
||||||
vkDestroySurfaceKHR(m_vulkanInstance, surfaceInfo->surface, nullptr);
|
|
||||||
m_surfaces.erase(itr);
|
m_surfaces.erase(itr);
|
||||||
return KR_SUCCESS;
|
return KR_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1214,11 +1045,11 @@ void KRContext::renderFrame()
|
|||||||
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
const std::lock_guard<std::mutex> surfaceLock(KRContext::g_SurfaceInfoMutex);
|
||||||
|
|
||||||
for (auto surfaceItr = m_surfaces.begin(); surfaceItr != m_surfaces.end(); surfaceItr++) {
|
for (auto surfaceItr = m_surfaces.begin(); surfaceItr != m_surfaces.end(); surfaceItr++) {
|
||||||
KRSurface& surface = (*surfaceItr).second;
|
KRSurface& surface = *(*surfaceItr).second;
|
||||||
KRDevice& device = GetDeviceInfo(surface.deviceHandle);
|
KRDevice& device = GetDeviceInfo(surface.m_deviceHandle);
|
||||||
|
|
||||||
uint32_t imageIndex = 0;
|
uint32_t imageIndex = 0;
|
||||||
vkAcquireNextImageKHR(device.m_logicalDevice, surface.swapChain, UINT64_MAX, surface.imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
vkAcquireNextImageKHR(device.m_logicalDevice, surface.m_swapChain, UINT64_MAX, surface.m_imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
// TODO - this will break with more than one surface... Expect to refactor this out
|
// TODO - this will break with more than one surface... Expect to refactor this out
|
||||||
VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex];
|
VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex];
|
||||||
@@ -1238,9 +1069,9 @@ void KRContext::renderFrame()
|
|||||||
VkRenderPassBeginInfo renderPassInfo{};
|
VkRenderPassBeginInfo renderPassInfo{};
|
||||||
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
renderPassInfo.renderPass = testPipeline->getRenderPass();
|
renderPassInfo.renderPass = testPipeline->getRenderPass();
|
||||||
renderPassInfo.framebuffer = surface.swapChainFramebuffers[frameIndex % surface.swapChainFramebuffers.size()];
|
renderPassInfo.framebuffer = surface.m_swapChainFramebuffers[frameIndex % surface.m_swapChainFramebuffers.size()];
|
||||||
renderPassInfo.renderArea.offset = { 0, 0 };
|
renderPassInfo.renderArea.offset = { 0, 0 };
|
||||||
renderPassInfo.renderArea.extent = surface.swapChainExtent;
|
renderPassInfo.renderArea.extent = surface.m_swapChainExtent;
|
||||||
renderPassInfo.clearValueCount = 1;
|
renderPassInfo.clearValueCount = 1;
|
||||||
renderPassInfo.pClearValues = &clearColor;
|
renderPassInfo.pClearValues = &clearColor;
|
||||||
|
|
||||||
@@ -1255,7 +1086,7 @@ void KRContext::renderFrame()
|
|||||||
VkSubmitInfo submitInfo{};
|
VkSubmitInfo submitInfo{};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
|
||||||
VkSemaphore waitSemaphores[] = { surface.imageAvailableSemaphore };
|
VkSemaphore waitSemaphores[] = { surface.m_imageAvailableSemaphore };
|
||||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||||
submitInfo.waitSemaphoreCount = 1;
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||||
@@ -1263,7 +1094,7 @@ void KRContext::renderFrame()
|
|||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
VkSemaphore signalSemaphores[] = { surface.renderFinishedSemaphore };
|
VkSemaphore signalSemaphores[] = { surface.m_renderFinishedSemaphore };
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
|
||||||
@@ -1276,7 +1107,7 @@ void KRContext::renderFrame()
|
|||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
presentInfo.pWaitSemaphores = signalSemaphores;
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
||||||
presentInfo.swapchainCount = 1;
|
presentInfo.swapchainCount = 1;
|
||||||
presentInfo.pSwapchains = &surface.swapChain;
|
presentInfo.pSwapchains = &surface.m_swapChain;
|
||||||
presentInfo.pImageIndices = &imageIndex;
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
presentInfo.pResults = nullptr;
|
presentInfo.pResults = nullptr;
|
||||||
vkQueuePresentKHR(device.m_graphicsQueue, &presentInfo);
|
vkQueuePresentKHR(device.m_graphicsQueue, &presentInfo);
|
||||||
@@ -1291,7 +1122,7 @@ KRSurface& KRContext::GetSurfaceInfo(KrSurfaceHandle handle)
|
|||||||
if (itr == m_surfaces.end()) {
|
if (itr == m_surfaces.end()) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
return m_surfaces[handle];
|
return *m_surfaces[handle];
|
||||||
}
|
}
|
||||||
|
|
||||||
KRDevice& KRContext::GetDeviceInfo(KrDeviceHandle handle)
|
KRDevice& KRContext::GetDeviceInfo(KrDeviceHandle handle)
|
||||||
@@ -1357,3 +1188,8 @@ void KRContext::createDevices()
|
|||||||
m_devices[++m_topDeviceHandle] = std::move(device);
|
m_devices[++m_topDeviceHandle] = std::move(device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkInstance& KRContext::GetVulkanInstance()
|
||||||
|
{
|
||||||
|
return m_vulkanInstance;
|
||||||
|
}
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ public:
|
|||||||
|
|
||||||
KRDevice& GetDeviceInfo(KrDeviceHandle handle);
|
KRDevice& GetDeviceInfo(KrDeviceHandle handle);
|
||||||
KRSurface& GetSurfaceInfo(KrSurfaceHandle handle);
|
KRSurface& GetSurfaceInfo(KrSurfaceHandle handle);
|
||||||
|
VkInstance& GetVulkanInstance();
|
||||||
|
KrSurfaceHandle GetBestDeviceForSurface(const VkSurfaceKHR& surface);
|
||||||
|
|
||||||
#if TARGET_OS_MAC
|
#if TARGET_OS_MAC
|
||||||
static void attachToView(void *view);
|
static void attachToView(void *view);
|
||||||
@@ -218,7 +220,7 @@ private:
|
|||||||
unordered_map<KrDeviceHandle, std::unique_ptr<KRDevice>> m_devices;
|
unordered_map<KrDeviceHandle, std::unique_ptr<KRDevice>> m_devices;
|
||||||
KrDeviceHandle m_topDeviceHandle;
|
KrDeviceHandle m_topDeviceHandle;
|
||||||
|
|
||||||
unordered_map<KrSurfaceHandle, KRSurface> m_surfaces;
|
unordered_map<KrSurfaceHandle, std::unique_ptr<KRSurface>> m_surfaces;
|
||||||
KrDeviceHandle m_topSurfaceHandle;
|
KrDeviceHandle m_topSurfaceHandle;
|
||||||
|
|
||||||
unordered_map<KrSurfaceMapIndex, KrSurfaceHandle> m_surfaceHandleMap;
|
unordered_map<KrSurfaceMapIndex, KrSurfaceHandle> m_surfaceHandleMap;
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ KRPipeline::KRPipeline(KRContext& context, KrSurfaceHandle surfaceHandle, const
|
|||||||
m_graphicsPipeline = nullptr;
|
m_graphicsPipeline = nullptr;
|
||||||
m_renderPass = nullptr;
|
m_renderPass = nullptr;
|
||||||
KRSurface& surface = m_pContext->GetSurfaceInfo(surfaceHandle);
|
KRSurface& surface = m_pContext->GetSurfaceInfo(surfaceHandle);
|
||||||
KRDevice& device = m_pContext->GetDeviceInfo(surface.deviceHandle);
|
KRDevice& device = m_pContext->GetDeviceInfo(surface.m_deviceHandle);
|
||||||
|
|
||||||
strcpy(m_szKey, szKey);
|
strcpy(m_szKey, szKey);
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ KRPipeline::KRPipeline(KRContext& context, KrSurfaceHandle surfaceHandle, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkAttachmentDescription colorAttachment{};
|
VkAttachmentDescription colorAttachment{};
|
||||||
colorAttachment.format = surface.swapChainImageFormat;
|
colorAttachment.format = surface.m_swapChainImageFormat;
|
||||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
@@ -199,14 +199,14 @@ KRPipeline::KRPipeline(KRContext& context, KrSurfaceHandle surfaceHandle, const
|
|||||||
VkViewport viewport{};
|
VkViewport viewport{};
|
||||||
viewport.x = 0.0f;
|
viewport.x = 0.0f;
|
||||||
viewport.y = 0.0f;
|
viewport.y = 0.0f;
|
||||||
viewport.width = (float)surface.swapChainExtent.width;
|
viewport.width = (float)surface.m_swapChainExtent.width;
|
||||||
viewport.height = (float)surface.swapChainExtent.height;
|
viewport.height = (float)surface.m_swapChainExtent.height;
|
||||||
viewport.minDepth = 0.0f;
|
viewport.minDepth = 0.0f;
|
||||||
viewport.maxDepth = 1.0f;
|
viewport.maxDepth = 1.0f;
|
||||||
|
|
||||||
VkRect2D scissor{};
|
VkRect2D scissor{};
|
||||||
scissor.offset = { 0, 0 };
|
scissor.offset = { 0, 0 };
|
||||||
scissor.extent = surface.swapChainExtent;
|
scissor.extent = surface.m_swapChainExtent;
|
||||||
|
|
||||||
VkPipelineViewportStateCreateInfo viewportState{};
|
VkPipelineViewportStateCreateInfo viewportState{};
|
||||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||||
|
|||||||
@@ -31,3 +31,212 @@
|
|||||||
|
|
||||||
#include "KRSurface.h"
|
#include "KRSurface.h"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
KRSurface::KRSurface(KRContext& context, HWND hWnd)
|
||||||
|
#else
|
||||||
|
KRSurface::KRSurface(KRContext& context)
|
||||||
|
#endif
|
||||||
|
: KRContextObject(context)
|
||||||
|
#ifdef WIN32
|
||||||
|
, m_hWnd(hWnd)
|
||||||
|
#endif
|
||||||
|
, m_deviceHandle(VK_NULL_HANDLE)
|
||||||
|
, m_surface(VK_NULL_HANDLE)
|
||||||
|
, m_swapChain(VK_NULL_HANDLE)
|
||||||
|
, m_swapChainImageFormat(VK_FORMAT_UNDEFINED)
|
||||||
|
, m_swapChainExtent({ 0, 0 })
|
||||||
|
, m_imageAvailableSemaphore(VK_NULL_HANDLE)
|
||||||
|
, m_renderFinishedSemaphore(VK_NULL_HANDLE)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
KRSurface::~KRSurface()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
KrResult KRSurface::initialize()
|
||||||
|
{
|
||||||
|
VkWin32SurfaceCreateInfoKHR createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
createInfo.hinstance = GetModuleHandle(nullptr);
|
||||||
|
createInfo.hwnd = m_hWnd;
|
||||||
|
if (vkCreateWin32SurfaceKHR(m_pContext->GetVulkanInstance(), &createInfo, nullptr, &m_surface) != VK_SUCCESS) {
|
||||||
|
return KR_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_deviceHandle = m_pContext->GetBestDeviceForSurface(m_surface);
|
||||||
|
if (m_deviceHandle == 0) {
|
||||||
|
return KR_ERROR_NO_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
KRDevice* deviceInfo = &m_pContext->GetDeviceInfo(m_deviceHandle);
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||||
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
if (vkCreateSemaphore(deviceInfo->m_logicalDevice, &semaphoreInfo, nullptr, &m_imageAvailableSemaphore) != VK_SUCCESS) {
|
||||||
|
return KR_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
if (vkCreateSemaphore(deviceInfo->m_logicalDevice, &semaphoreInfo, nullptr, &m_renderFinishedSemaphore) != VK_SUCCESS) {
|
||||||
|
return KR_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(deviceInfo->m_device, m_surface, &surfaceCapabilities);
|
||||||
|
|
||||||
|
std::vector<VkSurfaceFormatKHR> surfaceFormats;
|
||||||
|
uint32_t formatCount = 0;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
if (formatCount != 0) {
|
||||||
|
surfaceFormats.resize(formatCount);
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(deviceInfo->m_device, m_surface, &formatCount, surfaceFormats.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VkPresentModeKHR> surfacePresentModes;
|
||||||
|
|
||||||
|
uint32_t presentModeCount = 0;
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(deviceInfo->m_device, m_surface, &presentModeCount, nullptr);
|
||||||
|
|
||||||
|
if (presentModeCount != 0) {
|
||||||
|
surfacePresentModes.resize(presentModeCount);
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(deviceInfo->m_device, m_surface, &presentModeCount, surfacePresentModes.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR selectedSurfaceFormat = surfaceFormats[0];
|
||||||
|
for (const auto& availableFormat : surfaceFormats) {
|
||||||
|
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
||||||
|
selectedSurfaceFormat = availableFormat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VK_PRESENT_MODE_FIFO_KHR is always available
|
||||||
|
VkPresentModeKHR selectedPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
|
||||||
|
// Try to find a better mode
|
||||||
|
for (const auto& availablePresentMode : surfacePresentModes) {
|
||||||
|
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
|
||||||
|
selectedPresentMode = availablePresentMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExtent2D swapExtent;
|
||||||
|
if (surfaceCapabilities.currentExtent.width != UINT32_MAX) {
|
||||||
|
swapExtent = surfaceCapabilities.currentExtent;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const uint32_t MAX_WIDTH = 8192;
|
||||||
|
const uint32_t MAX_HEIGHT = 8192;
|
||||||
|
swapExtent.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, MAX_WIDTH));
|
||||||
|
swapExtent.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, MAX_HEIGHT));
|
||||||
|
}
|
||||||
|
m_swapChainExtent = swapExtent;
|
||||||
|
|
||||||
|
uint32_t imageCount = surfaceCapabilities.minImageCount + 1;
|
||||||
|
if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) {
|
||||||
|
imageCount = surfaceCapabilities.maxImageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR swapChainCreateInfo{};
|
||||||
|
swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
swapChainCreateInfo.surface = m_surface;
|
||||||
|
swapChainCreateInfo.minImageCount = imageCount;
|
||||||
|
swapChainCreateInfo.imageFormat = selectedSurfaceFormat.format;
|
||||||
|
swapChainCreateInfo.imageColorSpace = selectedSurfaceFormat.colorSpace;
|
||||||
|
swapChainCreateInfo.imageExtent = swapExtent;
|
||||||
|
swapChainCreateInfo.imageArrayLayers = 1;
|
||||||
|
swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
|
uint32_t queueFamilyIndices[] = {
|
||||||
|
deviceInfo->m_graphicsFamilyQueueIndex,
|
||||||
|
deviceInfo->m_computeFamilyQueueIndex
|
||||||
|
};
|
||||||
|
if (deviceInfo->m_graphicsFamilyQueueIndex == deviceInfo->m_computeFamilyQueueIndex) {
|
||||||
|
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
swapChainCreateInfo.queueFamilyIndexCount = 0;
|
||||||
|
swapChainCreateInfo.pQueueFamilyIndices = nullptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
swapChainCreateInfo.queueFamilyIndexCount = 2;
|
||||||
|
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
swapChainCreateInfo.preTransform = surfaceCapabilities.currentTransform;
|
||||||
|
swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
swapChainCreateInfo.presentMode = selectedPresentMode;
|
||||||
|
swapChainCreateInfo.clipped = VK_TRUE;
|
||||||
|
swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
if (vkCreateSwapchainKHR(deviceInfo->m_logicalDevice, &swapChainCreateInfo, nullptr, &m_swapChain) != VK_SUCCESS) {
|
||||||
|
return KR_ERROR_VULKAN_SWAP_CHAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(deviceInfo->m_logicalDevice, m_swapChain, &imageCount, nullptr);
|
||||||
|
m_swapChainImages.resize(imageCount);
|
||||||
|
vkGetSwapchainImagesKHR(deviceInfo->m_logicalDevice, m_swapChain, &imageCount, m_swapChainImages.data());
|
||||||
|
|
||||||
|
m_swapChainImageFormat = selectedSurfaceFormat.format;
|
||||||
|
|
||||||
|
m_swapChainImageViews.resize(m_swapChainImages.size());
|
||||||
|
for (size_t i = 0; i < m_swapChainImages.size(); i++) {
|
||||||
|
VkImageViewCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
createInfo.image = m_swapChainImages[i];
|
||||||
|
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
createInfo.format = m_swapChainImageFormat;
|
||||||
|
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
createInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
if (vkCreateImageView(deviceInfo->m_logicalDevice, &createInfo, nullptr, &m_swapChainImageViews[i]) != VK_SUCCESS) {
|
||||||
|
return KR_ERROR_VULKAN_SWAP_CHAIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return KR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KRSurface::destroy()
|
||||||
|
{
|
||||||
|
KRDevice& deviceInfo = m_pContext->GetDeviceInfo(m_deviceHandle);
|
||||||
|
|
||||||
|
for (auto framebuffer : m_swapChainFramebuffers) {
|
||||||
|
vkDestroyFramebuffer(deviceInfo.m_logicalDevice, framebuffer, nullptr);
|
||||||
|
}
|
||||||
|
m_swapChainFramebuffers.clear();
|
||||||
|
|
||||||
|
for (auto imageView : m_swapChainImageViews) {
|
||||||
|
vkDestroyImageView(deviceInfo.m_logicalDevice, imageView, nullptr);
|
||||||
|
}
|
||||||
|
m_swapChainImageViews.clear();
|
||||||
|
|
||||||
|
if (m_swapChain != VK_NULL_HANDLE) {
|
||||||
|
vkDestroySwapchainKHR(deviceInfo.m_logicalDevice, m_swapChain, nullptr);
|
||||||
|
m_swapChain = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_renderFinishedSemaphore != VK_NULL_HANDLE) {
|
||||||
|
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_renderFinishedSemaphore, nullptr);
|
||||||
|
m_renderFinishedSemaphore = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_imageAvailableSemaphore != VK_NULL_HANDLE) {
|
||||||
|
vkDestroySemaphore(deviceInfo.m_logicalDevice, m_imageAvailableSemaphore, nullptr);
|
||||||
|
m_imageAvailableSemaphore = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_surface != VK_NULL_HANDLE) {
|
||||||
|
vkDestroySurfaceKHR(m_pContext->GetVulkanInstance(), m_surface, nullptr);
|
||||||
|
m_surface = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -30,26 +30,41 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "KREngine-common.h"
|
#include "KREngine-common.h"
|
||||||
|
#include "KRContext.h"
|
||||||
|
|
||||||
#ifndef KRSURFACE_H
|
#ifndef KRSURFACE_H
|
||||||
#define KRSURFACE_H
|
#define KRSURFACE_H
|
||||||
|
|
||||||
class KRSurface
|
class KRSurface : public KRContextObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
KrDeviceHandle deviceHandle;
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
VkSwapchainKHR swapChain;
|
|
||||||
std::vector<VkImage> swapChainImages;
|
|
||||||
VkFormat swapChainImageFormat;
|
|
||||||
VkExtent2D swapChainExtent;
|
|
||||||
std::vector<VkImageView> swapChainImageViews;
|
|
||||||
std::vector<VkFramebuffer> swapChainFramebuffers;
|
|
||||||
VkSemaphore imageAvailableSemaphore;
|
|
||||||
VkSemaphore renderFinishedSemaphore;
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
HWND hWnd;
|
KRSurface(KRContext& context, HWND hWnd);
|
||||||
|
#else
|
||||||
|
KRSurface(KRContext& context);
|
||||||
#endif
|
#endif
|
||||||
|
~KRSurface();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
KRSurface(const KRSurface&) = delete;
|
||||||
|
KRSurface& operator=(const KRSurface&) = delete;
|
||||||
|
|
||||||
|
KrResult initialize();
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
HWND m_hWnd;
|
||||||
|
#endif
|
||||||
|
KrDeviceHandle m_deviceHandle;
|
||||||
|
VkSurfaceKHR m_surface;
|
||||||
|
VkSwapchainKHR m_swapChain;
|
||||||
|
std::vector<VkImage> m_swapChainImages;
|
||||||
|
VkFormat m_swapChainImageFormat;
|
||||||
|
VkExtent2D m_swapChainExtent;
|
||||||
|
std::vector<VkImageView> m_swapChainImageViews;
|
||||||
|
std::vector<VkFramebuffer> m_swapChainFramebuffers;
|
||||||
|
VkSemaphore m_imageAvailableSemaphore;
|
||||||
|
VkSemaphore m_renderFinishedSemaphore;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user