From a8d64a52df4f3b2c0f0249ba3c65cc55ce07e260 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 27 Apr 2024 17:49:03 -0400 Subject: [PATCH] Properly transition image layouts and create barriers This along with other misc fixes by listening to the validation layers "fixes" specular, but just for the skin. I need to do some more work to figure out why it doesn't work for character shaders yet. Also introduces new helper functions to Device to easily transition textures and name them. --- parts/mdl/vulkanwindow.cpp | 2 + renderer/include/camera.h | 1 + renderer/include/device.h | 5 ++ renderer/include/texture.h | 2 + renderer/src/device.cpp | 40 ++++++++++-- renderer/src/gamerenderer.cpp | 107 ++++++++++++++++++--------------- renderer/src/rendermanager.cpp | 18 ++++++ 7 files changed, 121 insertions(+), 54 deletions(-) diff --git a/parts/mdl/vulkanwindow.cpp b/parts/mdl/vulkanwindow.cpp index 871f2f8..d2c1f18 100644 --- a/parts/mdl/vulkanwindow.cpp +++ b/parts/mdl/vulkanwindow.cpp @@ -227,10 +227,12 @@ void VulkanWindow::render() m_renderer->camera.view = glm::translate(m_renderer->camera.view, part->position); m_renderer->camera.view *= glm::mat4_cast(glm::angleAxis(part->yaw, glm::vec3(0, 1, 0)) * glm::angleAxis(part->pitch, glm::vec3(1, 0, 0))); m_renderer->camera.view = glm::inverse(m_renderer->camera.view); + m_renderer->camera.position = part->position; } else { glm::vec3 position(part->cameraDistance * sin(part->yaw), part->cameraDistance * part->pitch, part->cameraDistance * cos(part->yaw)); m_renderer->camera.view = glm::lookAt(part->position + position, part->position, glm::vec3(0, -1, 0)); + m_renderer->camera.position = part->position + position; } m_renderer->render(models); diff --git a/renderer/include/camera.h b/renderer/include/camera.h index 6ed4702..51d11af 100644 --- a/renderer/include/camera.h +++ b/renderer/include/camera.h @@ -19,4 +19,5 @@ struct Camera { float farPlane = 100.0f; glm::mat4 perspective, view; + glm::vec3 position; }; \ No newline at end of file diff --git a/renderer/include/device.h b/renderer/include/device.h index cc08936..aeebf5c 100644 --- a/renderer/include/device.h +++ b/renderer/include/device.h @@ -51,4 +51,9 @@ public: VkImageLayout newLayout, VkPipelineStageFlags src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + + void transitionTexture(VkCommandBuffer commandBuffer, Texture &texture, VkImageLayout oldLayout, VkImageLayout newLayout); + + VkResult nameObject(VkObjectType type, uint64_t object, std::string_view name); + void nameTexture(Texture &texture, std::string_view name); }; \ No newline at end of file diff --git a/renderer/include/texture.h b/renderer/include/texture.h index d535259..fc1b9aa 100644 --- a/renderer/include/texture.h +++ b/renderer/include/texture.h @@ -8,6 +8,8 @@ class Texture { public: + VkFormat format; + VkImageSubresourceRange range; VkImage image; VkImageView imageView; VkDeviceMemory imageMemory; diff --git a/renderer/src/device.cpp b/renderer/src/device.cpp index 8db426e..c9afa81 100644 --- a/renderer/src/device.cpp +++ b/renderer/src/device.cpp @@ -124,14 +124,15 @@ Texture Device::createTexture(const int width, const int height, const VkFormat viewCreateInfo.image = image; viewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; viewCreateInfo.format = format; - viewCreateInfo.subresourceRange.aspectMask = - usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; // TODO: hardcoded + viewCreateInfo.subresourceRange.aspectMask = (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT + ? VK_IMAGE_ASPECT_DEPTH_BIT + : VK_IMAGE_ASPECT_COLOR_BIT; // TODO: hardcoded viewCreateInfo.subresourceRange.levelCount = 1; viewCreateInfo.subresourceRange.layerCount = 1; vkCreateImageView(device, &viewCreateInfo, nullptr, &imageView); - return {image, imageView, imageMemory}; + return {format, viewCreateInfo.subresourceRange, image, imageView, imageMemory}; } Texture Device::createDummyTexture() @@ -308,4 +309,35 @@ void Device::inlineTransitionImageLayout(VkCommandBuffer commandBuffer, } vkCmdPipelineBarrier(commandBuffer, src_stage_mask, dst_stage_mask, 0, 0, nullptr, 0, nullptr, 1, &barrier); -} \ No newline at end of file +} + +void Device::transitionTexture(VkCommandBuffer commandBuffer, Texture &texture, VkImageLayout oldLayout, VkImageLayout newLayout) +{ + inlineTransitionImageLayout(commandBuffer, texture.image, texture.format, texture.range.aspectMask, texture.range, oldLayout, newLayout); +} + +VkResult Device::nameObject(VkObjectType type, uint64_t object, std::string_view name) +{ + if (object == 0x0) { + return VK_ERROR_DEVICE_LOST; + } + + VkDebugUtilsObjectNameInfoEXT info = {}; + info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + info.objectType = type; + info.pObjectName = name.data(); + info.objectHandle = object; + + auto func = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT"); + if (func != nullptr) + return func(device, &info); + else + return VK_ERROR_EXTENSION_NOT_PRESENT; +} + +void Device::nameTexture(Texture &texture, std::string_view name) +{ + nameObject(VK_OBJECT_TYPE_IMAGE, reinterpret_cast(texture.image), name.data()); + nameObject(VK_OBJECT_TYPE_IMAGE_VIEW, reinterpret_cast(texture.imageView), name.data()); + nameObject(VK_OBJECT_TYPE_DEVICE_MEMORY, reinterpret_cast(texture.imageMemory), name.data()); +} diff --git a/renderer/src/gamerenderer.cpp b/renderer/src/gamerenderer.cpp index c2747a6..c3d73e2 100644 --- a/renderer/src/gamerenderer.cpp +++ b/renderer/src/gamerenderer.cpp @@ -214,11 +214,11 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca cameraParameter.m_InverseViewProjectionMatrix = glm::transpose(glm::inverse(viewProjectionMatrix)); // known params - cameraParameter.m_InverseProjectionMatrix = glm::transpose(glm::inverse(viewProjectionMatrix)); + cameraParameter.m_InverseProjectionMatrix = glm::transpose(glm::inverse(camera.perspective)); cameraParameter.m_ProjectionMatrix = glm::transpose(viewProjectionMatrix); cameraParameter.m_MainViewToProjectionMatrix = glm::transpose(glm::inverse(camera.perspective)); - cameraParameter.m_EyePosition = glm::vec3(5.0f); // placeholder + cameraParameter.m_EyePosition = camera.position; // placeholder cameraParameter.m_LookAtVector = glm::vec3(0.0f); // placeholder m_device.copyToBuffer(g_CameraParameter, &cameraParameter, sizeof(CameraParameter)); @@ -343,7 +343,11 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca } endPass(commandBuffer, pass); + + m_device.transitionTexture(commandBuffer, m_depthBuffer, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } else if (pass == "PASS_LIGHTING_OPAQUE") { + m_device.transitionTexture(commandBuffer, m_normalGBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + // first we need to generate the view positions with createviewpositions beginPass(imageIndex, commandBuffer, "PASS_LIGHTING_OPAQUE_VIEWPOSITION"); { @@ -391,6 +395,8 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca } endPass(commandBuffer, pass); + m_device.transitionTexture(commandBuffer, m_viewPositionBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + beginPass(imageIndex, commandBuffer, pass); // then run the directionallighting shader { @@ -442,6 +448,12 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca } } endPass(commandBuffer, pass); + + m_device.transitionTexture(commandBuffer, m_lightBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + m_device.transitionTexture(commandBuffer, + m_lightSpecularBuffer, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } else if (pass == "PASS_COMPOSITE_SEMITRANSPARENCY") { beginPass(imageIndex, commandBuffer, pass); @@ -532,6 +544,8 @@ void GameRenderer::render(VkCommandBuffer commandBuffer, uint32_t imageIndex, Ca } endPass(commandBuffer, pass); + + m_device.transitionTexture(commandBuffer, m_compositeBuffer, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } i++; @@ -557,6 +571,8 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, VkRenderingAttachmentInfo depthStencilAttachment{}; if (passName == "PASS_G_OPAQUE") { + m_device.transitionTexture(commandBuffer, m_normalGBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + // normals, it seems like { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; @@ -573,27 +589,7 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, colorAttachments.push_back(attachmentInfo); } - // unknown, seems to be background? - { - VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; - attachmentInfo.imageView = VK_NULL_HANDLE; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - colorAttachments.push_back(attachmentInfo); - } - - // unknown, seems to be background? - { - VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; - attachmentInfo.imageView = VK_NULL_HANDLE; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - colorAttachments.push_back(attachmentInfo); - } + m_device.transitionTexture(commandBuffer, m_depthBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); // depth { @@ -607,49 +603,52 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, depthStencilAttachment = attachmentInfo; } } else if (passName == "PASS_LIGHTING_OPAQUE") { - // normals, it seems like + m_device.transitionTexture(commandBuffer, m_lightBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + // diffuse { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; attachmentInfo.imageView = m_lightBuffer.imageView; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - attachmentInfo.clearValue.color.float32[0] = 0.24; - attachmentInfo.clearValue.color.float32[1] = 0.24; - attachmentInfo.clearValue.color.float32[2] = 0.24; attachmentInfo.clearValue.color.float32[3] = 1.0; colorAttachments.push_back(attachmentInfo); } + m_device.transitionTexture(commandBuffer, m_lightSpecularBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + // specular? { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; attachmentInfo.imageView = m_lightSpecularBuffer.imageView; attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentInfo.clearValue.color.float32[3] = 1.0; colorAttachments.push_back(attachmentInfo); } } else if (passName == "PASS_LIGHTING_OPAQUE_VIEWPOSITION") { + m_device.transitionTexture(commandBuffer, m_viewPositionBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + // TODO: Hack we should not be using a special pass for this, we should just design our API better { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; attachmentInfo.imageView = m_viewPositionBuffer.imageView; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachmentInfo.clearValue.color.float32[0] = 0.24; - attachmentInfo.clearValue.color.float32[1] = 0.24; - attachmentInfo.clearValue.color.float32[2] = 0.24; attachmentInfo.clearValue.color.float32[3] = 1.0; colorAttachments.push_back(attachmentInfo); } } else if (passName == "PASS_Z_OPAQUE") { + m_device.transitionTexture(commandBuffer, m_ZBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + m_device.transitionTexture(commandBuffer, m_depthBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + // normals, it seems like { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; @@ -665,18 +664,9 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, colorAttachments.push_back(attachmentInfo); } - - // unknown - { - VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; - attachmentInfo.imageView = VK_NULL_HANDLE; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - - colorAttachments.push_back(attachmentInfo); - } } else if (passName == "PASS_COMPOSITE_SEMITRANSPARENCY") { + m_device.transitionTexture(commandBuffer, m_compositeBuffer, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + // composite { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; @@ -693,6 +683,8 @@ void GameRenderer::beginPass(uint32_t imageIndex, VkCommandBuffer commandBuffer, colorAttachments.push_back(attachmentInfo); } + m_device.transitionTexture(commandBuffer, m_depthBuffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL); + // depth buffer for depth testing { VkRenderingAttachmentInfo attachmentInfo{VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO}; @@ -935,9 +927,7 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN int colorAttachmentCount = 1; // TODO: hardcoded, should be a reusable function to get the color attachments - if (passName == "PASS_G_OPAQUE") { - colorAttachmentCount = 3; - } else if (passName == "PASS_LIGHTING_OPAQUE") { + if (passName == "PASS_LIGHTING_OPAQUE") { colorAttachmentCount = 2; } @@ -984,11 +974,15 @@ GameRenderer::bindPipeline(VkCommandBuffer commandBuffer, std::string_view passN depthStencil.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; depthStencil.maxDepthBounds = 1.0f; - std::array colorAttachmentFormats = {VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED}; + std::array colorAttachmentFormats = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM}; VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo = {}; pipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; - pipelineRenderingCreateInfo.colorAttachmentCount = 3; // TODO: hardcoded + if (passName == "PASS_LIGHTING_OPAQUE") { + pipelineRenderingCreateInfo.colorAttachmentCount = 2; // TODO: hardcoded + } else { + pipelineRenderingCreateInfo.colorAttachmentCount = 1; + } pipelineRenderingCreateInfo.pColorAttachmentFormats = colorAttachmentFormats.data(); pipelineRenderingCreateInfo.depthAttachmentFormat = VK_FORMAT_D32_SFLOAT; // TODO: hardcoded @@ -1280,30 +1274,43 @@ void GameRenderer::createImageResources() m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_normalGBuffer, "Normal GBuffer"); + m_viewPositionBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_viewPositionBuffer, "View Position"); + m_lightBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_lightBuffer, "Light Diffuse"); + m_lightSpecularBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_lightSpecularBuffer, "Light Specular"); + m_compositeBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_compositeBuffer, "Composite"); + m_ZBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_ZBuffer, "ZBuffer"); + m_depthBuffer = m_device.createTexture(m_device.swapChain->extent.width, m_device.swapChain->extent.height, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); + m_device.nameTexture(m_depthBuffer, "Depth"); CommonParameter commonParam{}; commonParam.m_RenderTarget = {1.0f / m_device.swapChain->extent.width, diff --git a/renderer/src/rendermanager.cpp b/renderer/src/rendermanager.cpp index fdac8bf..7249cfc 100644 --- a/renderer/src/rendermanager.cpp +++ b/renderer/src/rendermanager.cpp @@ -77,6 +77,10 @@ RenderManager::RenderManager(GameData *data) if (strstr(extension.extensionName, "VK_KHR_get_physical_device_properties2") != nullptr) { instanceExtensions.push_back(extension.extensionName); } + + if (strstr(extension.extensionName, "VK_EXT_debug_utils") != nullptr) { + instanceExtensions.push_back(extension.extensionName); + } } VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = {}; @@ -88,12 +92,16 @@ RenderManager::RenderManager(GameData *data) VkApplicationInfo applicationInfo = {VK_STRUCTURE_TYPE_APPLICATION_INFO}; applicationInfo.apiVersion = VK_API_VERSION_1_3; + const char *layers[] = {"VK_LAYER_KHRONOS_validation"}; + VkInstanceCreateInfo createInfo = {}; createInfo.pNext = &debugCreateInfo; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.ppEnabledExtensionNames = instanceExtensions.data(); createInfo.enabledExtensionCount = instanceExtensions.size(); createInfo.pApplicationInfo = &applicationInfo; + createInfo.ppEnabledLayerNames = layers; + createInfo.enabledLayerCount = 1; vkCreateInstance(&createInfo, nullptr, &m_device->instance); @@ -198,8 +206,17 @@ RenderManager::RenderManager(GameData *data) enabledFeatures.shaderCullDistance = VK_TRUE; enabledFeatures.fillModeNonSolid = VK_TRUE; + VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR localReadFeaturesKhr{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES_KHR}; + localReadFeaturesKhr.dynamicRenderingLocalRead = VK_TRUE; + + VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT unusedAttachmentsFeaturesExt{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT}; + unusedAttachmentsFeaturesExt.dynamicRenderingUnusedAttachments = VK_TRUE; + unusedAttachmentsFeaturesExt.pNext = &localReadFeaturesKhr; + VkPhysicalDeviceVulkan11Features enabled11Features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES}; enabled11Features.shaderDrawParameters = VK_TRUE; + enabled11Features.pNext = &unusedAttachmentsFeaturesExt; VkPhysicalDeviceVulkan12Features enabled12Features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES}; enabled12Features.vulkanMemoryModel = VK_TRUE; @@ -208,6 +225,7 @@ RenderManager::RenderManager(GameData *data) VkPhysicalDeviceVulkan13Features enabled13Features{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES}; enabled13Features.shaderDemoteToHelperInvocation = VK_TRUE; enabled13Features.dynamicRendering = VK_TRUE; + enabled13Features.synchronization2 = VK_TRUE; enabled13Features.pNext = &enabled12Features; VkDeviceCreateInfo deviceCeateInfo = {};