From 9af9bb5bd538c4289716749695b55a28466acb26 Mon Sep 17 00:00:00 2001 From: niki Date: Sun, 18 Sep 2022 14:16:42 +0200 Subject: [PATCH] vulkan: keep track of window stencil buffer --- src/modules/graphics/vulkan/Graphics.cpp | 20 ++++++++++++++++++-- src/modules/graphics/vulkan/Graphics.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index e4aef3078..0a1ad4caf 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -473,6 +473,7 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) { requestedMsaa = msaa; + windowHasStencil = windowhasstencil; cleanUpFunctions.clear(); cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT); @@ -858,6 +859,17 @@ void Graphics::setScissor() void Graphics::setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) { + if (action != STENCIL_KEEP) + { + const auto& rts = states.back().renderTargets; + auto dsTexture = rts.depthStencil.texture.get(); + + if (!isRenderTargetActive() && !windowHasStencil) + throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer"); + if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && dsTexture == nullptr || !isPixelFormatStencil(dsTexture->getPixelFormat())) + throw love::Exception("drawing to the stencil buffer with a render target active requires either stencil=true or a custom stencil-type to be used, in setRenderTarget"); + } + flushBatchedDraws(); vkCmdSetStencilWriteMask(commandBuffers.at(currentFrame), VK_STENCIL_FACE_FRONT_AND_BACK, writemask); @@ -1300,7 +1312,7 @@ void Graphics::createVulkanInstance() VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "LOVE"; - appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0); //todo, get this version from somewhere else? + appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0); // get this version from somewhere else? appInfo.pEngineName = "LOVE Engine"; appInfo.engineVersion = VK_MAKE_API_VERSION(0, VERSION_MAJOR, VERSION_MINOR, VERSION_REV); appInfo.apiVersion = vulkanApiVersion; @@ -1565,6 +1577,8 @@ void Graphics::createLogicalDevice() findOptionalDeviceExtensions(physicalDevice, optionalDeviceFeatures); + // sanity check for dependencies. + if (optionalDeviceFeatures.extendedDynamicState && !optionalInstanceExtensions.physicalDeviceProperties2) optionalDeviceFeatures.extendedDynamicState = false; if (optionalDeviceFeatures.dedicatedAllocation && !optionalDeviceFeatures.memoryRequirements2) @@ -2866,7 +2880,9 @@ void Graphics::createDepthResources() imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + if (windowHasStencil) + imageViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; imageViewInfo.subresourceRange.baseMipLevel = 0; imageViewInfo.subresourceRange.levelCount = 1; imageViewInfo.subresourceRange.baseArrayLayer = 0; diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index e95d2d161..75b413bf5 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -394,6 +394,7 @@ private: uint32_t vulkanApiVersion = VK_VERSION_1_0; VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; + bool windowHasStencil = false; int requestedMsaa = 0; VkDevice device = VK_NULL_HANDLE; OptionalInstanceExtensions optionalInstanceExtensions;