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 = {};