diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index eeaeeff88..0797e4feb 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -185,6 +185,8 @@ Graphics::Graphics() , height(0) , pixelWidth(0) , pixelHeight(0) + , backbufferHasStencil(false) + , backbufferHasDepth(false) , created(false) , active(true) , batchedDrawState() @@ -617,6 +619,34 @@ Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex) return getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT); } +void Graphics::validateStencilState(const StencilState &s) const +{ + if (s.action != STENCIL_KEEP) + { + const auto &rts = states.back().renderTargets; + love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); + + if (!isRenderTargetActive() && !backbufferHasStencil) + throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer."); + else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) + throw love::Exception("Drawing to the stencil buffer with a Canvas active requires either stencil=true or a custom stencil-type Canvas to be used, in setCanvas."); + } +} + +void Graphics::validateDepthState(bool depthwrite) const +{ + if (depthwrite) + { + const auto &rts = states.back().renderTargets; + love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); + + if (!isRenderTargetActive() && !backbufferHasDepth) + throw love::Exception("The window must have depth enabled to draw to the main screen's depth buffer."); + else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_DEPTH) == 0 && (dstexture == nullptr || !isPixelFormatDepth(dstexture->getPixelFormat()))) + throw love::Exception("Drawing to the depth buffer with a Canvas active requires either depth=true or a custom depth-type Canvas to be used, in setCanvas."); + } +} + int Graphics::getWidth() const { return width; @@ -671,6 +701,11 @@ void Graphics::reset() origin(); } +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight) +{ + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferHasStencil, backbufferHasDepth, getRequestedBackbufferMSAA()); +} + /** * State functions. **/ diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 38dec2568..030d9d7f1 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -506,16 +506,15 @@ public: virtual void present(void *screenshotCallbackData) = 0; /** - * Sets the current graphics display viewport dimensions. + * Called when the backbuffer changes. **/ - virtual void setViewportSize(int width, int height, int pixelwidth, int pixelheight) = 0; + virtual void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) = 0; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight); /** * Sets the current graphics display viewport and initializes the renderer. - * @param width The viewport width. - * @param height The viewport height. **/ - virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) = 0; + virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) = 0; /** * Un-sets the current graphics display mode (uninitializing objects if @@ -1048,6 +1047,9 @@ protected: void releaseDefaultResources(); + void validateStencilState(const StencilState &s) const; + void validateDepthState(bool depthwrite) const; + void restoreState(const DisplayState &s); void restoreStateChecked(const DisplayState &s); @@ -1063,6 +1065,9 @@ protected: int pixelWidth; int pixelHeight; + bool backbufferHasStencil; + bool backbufferHasDepth; + bool created; bool active; diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 1d910eb5e..d0477881c 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -68,8 +68,8 @@ public: Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; @@ -231,7 +231,6 @@ private: uint32 dirtyRenderState; CullMode lastCullMode; Shader::RenderPipelineKey lastRenderPipelineKey; - bool windowHasStencil; int shaderSwitches; StrongRef backbufferMSAA; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 605172584..98dfd1c24 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -274,7 +274,6 @@ Graphics::Graphics() , dirtyRenderState(STATEBIT_ALL) , lastCullMode(CULL_MAX_ENUM) , lastRenderPipelineKey() - , windowHasStencil(false) , shaderSwitches(0) , requestedBackbufferMSAA(0) , attachmentStoreActions() @@ -464,13 +463,23 @@ Matrix4 Graphics::computeDeviceProjection(const Matrix4 &projection, bool /*rend return calculateDeviceProjection(projection, flags); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { + bool sizechanged = width != this->width || height != this->height + || pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight; + + bool dschanged = backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth; + bool msaachanged = msaa != this->requestedBackbufferMSAA; + this->width = width; this->height = height; this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedBackbufferMSAA = msaa; + if (!isRenderTargetActive()) { dirtyRenderState |= STATEBIT_VIEWPORT | STATEBIT_SCISSOR; @@ -485,26 +494,38 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh settings.renderTarget = true; settings.readable.set(false); - backbufferMSAA.set(nullptr); - if (settings.msaa > 1) + if (sizechanged || msaachanged) { - settings.format = isGammaCorrect() ? PIXELFORMAT_BGRA8_sRGB : PIXELFORMAT_BGRA8_UNORM; - backbufferMSAA.set(newTexture(settings), Acquire::NORETAIN); + backbufferMSAA.set(nullptr); + if (settings.msaa > 1) + { + settings.format = isGammaCorrect() ? PIXELFORMAT_BGRA8_sRGB : PIXELFORMAT_BGRA8_UNORM; + backbufferMSAA.set(newTexture(settings), Acquire::NORETAIN); + } } - settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; - backbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + if (sizechanged || msaachanged || dschanged) + { + backbufferDepthStencil.set(nullptr); + if (backbufferstencil || backbufferdepth) + { + if (backbufferstencil && backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; + else if (backbufferstencil) + settings.format = PIXELFORMAT_STENCIL8; + else if (backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM; + backbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + } + } } -bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { @autoreleasepool { this->width = width; this->height = height; this->metalLayer = (__bridge CAMetalLayer *) context; - this->windowHasStencil = windowhasstencil; - this->requestedBackbufferMSAA = msaa; - metalLayer.device = device; metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; @@ -516,7 +537,7 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int metalLayer.magnificationFilter = kCAFilterNearest; #endif - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); created = true; @@ -660,8 +681,10 @@ id Graphics::useRenderEncoder() passDesc.colorAttachments[0].depthPlane = 0; RenderTarget rt(backbufferDepthStencil); - setAttachment(rt, passDesc.depthAttachment, attachmentStoreActions.depth, false); - setAttachment(rt, passDesc.stencilAttachment, attachmentStoreActions.stencil, false); + if (rt.texture != nullptr && isPixelFormatDepth(rt.texture->getPixelFormat())) + setAttachment(rt, passDesc.depthAttachment, attachmentStoreActions.depth, false); + if (rt.texture != nullptr && isPixelFormatStencil(rt.texture->getPixelFormat())) + setAttachment(rt, passDesc.stencilAttachment, attachmentStoreActions.stencil, false); attachmentStoreActions.depth = MTLStoreActionDontCare; attachmentStoreActions.stencil = MTLStoreActionDontCare; @@ -700,11 +723,15 @@ void Graphics::submitRenderEncoder(SubmitType type) for (size_t i = 0; i < rts.colors.size(); i++) [renderEncoder setColorStoreAction:(store ? MTLStoreActionStore : actions.color[i]) atIndex:i]; - if (rts.depthStencil.texture.get() || rts.temporaryRTFlags != 0 || isbackbuffer) - { + love::graphics::Texture *ds = rts.depthStencil.texture.get(); + if (isbackbuffer) + ds = backbufferDepthStencil; + + if ((rts.temporaryRTFlags & TEMPORARY_RT_DEPTH) != 0 || (ds != nullptr && isPixelFormatDepth(ds->getPixelFormat()))) [renderEncoder setDepthStoreAction:store ? MTLStoreActionStore : actions.depth]; + + if ((rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) != 0 || (ds != nullptr && isPixelFormatStencil(ds->getPixelFormat()))) [renderEncoder setStencilStoreAction:store ? MTLStoreActionStore : actions.stencil]; - } [renderEncoder endEncoding]; renderEncoder = nil; @@ -1762,28 +1789,18 @@ void Graphics::setScissor() void Graphics::setStencilState(const StencilState &s) { - DisplayState &state = states.back(); - - if (s.action != STENCIL_KEEP) - { - const auto &rts = state.renderTargets; - love::graphics::Texture *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."); - else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) - throw love::Exception("Drawing to the stencil buffer with a Canvas active requires either stencil=true or a custom stencil-type Canvas to be used, in setCanvas."); - } + validateStencilState(s); flushBatchedDraws(); - state.stencil = s; - + states.back().stencil = s; dirtyRenderState |= STATEBIT_STENCIL; } void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + DisplayState &state = states.back(); if (state.depthTest != compare || state.depthWrite != write) diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index b56ed1cee..f6ff52205 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -200,13 +200,23 @@ Matrix4 Graphics::computeDeviceProjection(const Matrix4 &projection, bool render return calculateDeviceProjection(projection, flags); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { + bool changed = width != this->width || height != this->height + || pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight; + + changed |= backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth; + changed |= msaa != this->requestedBackbufferMSAA; + this->width = width; this->height = height; this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedBackbufferMSAA = msaa; + if (!isRenderTargetActive()) { // Set the viewport to top-left corner. @@ -220,11 +230,9 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh resetProjection(); } - updateBackbuffer(width, height, pixelwidth, pixelheight, requestedBackbufferMSAA); -} + if (!changed) + return; -void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int pixelheight, int msaa) -{ bool useinternalbackbuffer = false; if (msaa > 1) useinternalbackbuffer = true; @@ -253,8 +261,17 @@ void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int p settings.format = isGammaCorrect() ? PIXELFORMAT_RGBA8_sRGB : PIXELFORMAT_RGBA8_UNORM; internalBackbuffer.set(newTexture(settings), Acquire::NORETAIN); - settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; - internalBackbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + internalBackbufferDepthStencil.set(nullptr); + if (backbufferstencil || backbufferdepth) + { + if (backbufferstencil && backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; + else if (backbufferstencil) + settings.format = PIXELFORMAT_STENCIL8; + else if (backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM; + internalBackbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + } RenderTargets rts; rts.colors.push_back(internalBackbuffer.get()); @@ -269,8 +286,6 @@ void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int p internalBackbufferFBO = 0; } - requestedBackbufferMSAA = msaa; - if (restoreFBO) gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, prevFBO); } @@ -300,14 +315,8 @@ GLuint Graphics::getSystemBackbufferFBO() const #endif } -bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - this->width = width; - this->height = height; - - this->windowHasStencil = windowhasstencil; - this->requestedBackbufferMSAA = msaa; - // Okay, setup OpenGL. gl.initContext(); @@ -364,7 +373,7 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, setDebug(isDebugEnabled()); - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); if (batchedDrawState.vb[0] == nullptr) { @@ -1436,18 +1445,7 @@ void Graphics::setScissor() void Graphics::setStencilState(const StencilState &s) { - DisplayState &state = states.back(); - - if (s.action != STENCIL_KEEP) - { - const auto &rts = state.renderTargets; - love::graphics::Texture *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."); - else 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 texture to be used, in setRenderTarget."); - } + validateStencilState(s); flushBatchedDraws(); @@ -1507,11 +1505,13 @@ void Graphics::setStencilState(const StencilState &s) if (s.writeMask != gl.getStencilWriteMask()) gl.setStencilWriteMask(s.writeMask); - state.stencil = s; + states.back().stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + DisplayState &state = states.back(); if (state.depthTest != compare || state.depthWrite != write) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 894b52e21..7e064420e 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -64,8 +64,8 @@ public: Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 399e9b4e8..98e64e520 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -587,9 +587,10 @@ void Graphics::present(void *screenshotCallbackdata) beginFrame(); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - if (swapChain != VK_NULL_HANDLE && (pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight || width != this->width || height != this->height)) + if (swapChain != VK_NULL_HANDLE && (pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight || width != this->width || height != this->height + || backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth || msaa != requestedMsaa)) requestSwapchainRecreation(); this->width = width; @@ -597,17 +598,21 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedMsaa = msaa; + if (!isRenderTargetActive()) resetProjection(); + + if (swapChain != VK_NULL_HANDLE) + msaaSamples = getMsaaCount(requestedMsaa); } -bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - requestedMsaa = msaa; - windowHasStencil = windowhasstencil; - // Must be called before the swapchain is created. - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); cleanUpFunctions.clear(); cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT); @@ -1003,16 +1008,7 @@ void Graphics::setScissor() void Graphics::setStencilState(const StencilState &s) { - if (s.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"); - else 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"); - } + validateStencilState(s); flushBatchedDraws(); @@ -1033,6 +1029,8 @@ void Graphics::setStencilState(const StencilState &s) void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + flushBatchedDraws(); if (optionalDeviceExtensions.extendedDynamicState) @@ -1284,11 +1282,12 @@ void Graphics::beginFrame() if (transitionColorDepthLayouts) { - Vulkan::cmdTransitionImageLayout( - commandBuffers.at(currentFrame), - depthImage, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + if (depthImage) + Vulkan::cmdTransitionImageLayout( + commandBuffers.at(currentFrame), + depthImage, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); if (colorImage) Vulkan::cmdTransitionImageLayout( @@ -2935,6 +2934,13 @@ VkFormat Graphics::findDepthFormat() void Graphics::createDepthResources() { + if (!backbufferHasDepth && !backbufferHasStencil) + { + depthImage = VK_NULL_HANDLE; + depthImageView = VK_NULL_HANDLE; + return; + } + VkImageCreateInfo imageInfo{}; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.imageType = VK_IMAGE_TYPE_2D; @@ -2966,8 +2972,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; - if (windowHasStencil) + if (backbufferHasDepth) + imageViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; + if (backbufferHasStencil) imageViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; imageViewInfo.subresourceRange.baseMipLevel = 0; imageViewInfo.subresourceRange.levelCount = 1; @@ -3076,8 +3083,11 @@ void Graphics::cleanupSwapChain() vkDestroyImageView(device, colorImageView, nullptr); vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation); } - vkDestroyImageView(device, depthImageView, nullptr); - vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation); + if (depthImage) + { + vkDestroyImageView(device, depthImageView, nullptr); + vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation); + } for (const auto &swapChainImageView : swapChainImageViews) vkDestroyImageView(device, swapChainImageView, nullptr); swapChainImageViews.clear(); diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index a7c9f9ffd..fc51d69ce 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -284,8 +284,8 @@ public: Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; void discard(const std::vector& colorbuffers, bool depthstencil) override; void present(void *screenshotCallbackdata) override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; int getRequestedBackbufferMSAA() const override; @@ -394,7 +394,6 @@ private: VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; uint32_t deviceApiVersion = VK_API_VERSION_1_0; - bool windowHasStencil = false; int requestedMsaa = 0; VkDevice device = VK_NULL_HANDLE; OptionalInstanceExtensions optionalInstanceExtensions; diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index d15091e43..9676dd455 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -262,7 +262,7 @@ struct WindowSettings int vsync = 1; int msaa = 0; bool stencil = true; - int depth = 0; + bool depth = false; bool resizable = false; int minwidth = 1; int minheight = 1; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index b124bd54e..5205bcd7e 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -127,8 +127,7 @@ void Window::setGLFramebufferAttributes(bool sRGB) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); - // Always use 24/8 depth/stencil (make sure any Graphics implementations - // that have their own backbuffer match this, too). + // Always use 24/8 depth/stencil. // Changing this after initial window creation would need the context to be // destroyed and recreated, which we really don't want. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); @@ -639,12 +638,12 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) context = (void *) SDL_Metal_GetLayer(metalView); #endif - graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa); + graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth, f.msaa); this->settings.msaa = graphics->getBackbufferMSAA(); } else { - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth, f.msaa); } } @@ -687,7 +686,7 @@ bool Window::onSizeChanged(int width, int height) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); } return true; @@ -771,7 +770,7 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); } } diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 3d3d86708..60aea2993 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -68,7 +68,6 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings) settings.fullscreen = luax_boolflag(L, idx, settingName(Window::SETTING_FULLSCREEN), settings.fullscreen); settings.msaa = luax_intflag(L, idx, settingName(Window::SETTING_MSAA), settings.msaa); settings.stencil = luax_boolflag(L, idx, settingName(Window::SETTING_STENCIL), settings.stencil); - settings.depth = luax_intflag(L, idx, settingName(Window::SETTING_DEPTH), settings.depth); settings.resizable = luax_boolflag(L, idx, settingName(Window::SETTING_RESIZABLE), settings.resizable); settings.minwidth = luax_intflag(L, idx, settingName(Window::SETTING_MIN_WIDTH), settings.minwidth); settings.minheight = luax_intflag(L, idx, settingName(Window::SETTING_MIN_HEIGHT), settings.minheight); @@ -76,6 +75,16 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings) settings.centered = luax_boolflag(L, idx, settingName(Window::SETTING_CENTERED), settings.centered); settings.usedpiscale = luax_boolflag(L, idx, settingName(Window::SETTING_USE_DPISCALE), settings.usedpiscale); + lua_getfield(L, idx, settingName(Window::SETTING_DEPTH)); + if (lua_type(L, -1) == LUA_TNUMBER) + { + luax_markdeprecated(L, 1, "window.depth number", API_FIELD, DEPRECATED_REPLACED, "window.depth boolean field"); + settings.depth = (int) luaL_checknumber(L, -1); + } + else if (!lua_isnoneornil(L, -1)) + settings.depth = lua_toboolean(L, -1); + lua_pop(L, 1); + settings.displayindex = luax_intflag(L, idx, settingName(Window::SETTING_DISPLAYINDEX), settings.displayindex + 1) - 1; lua_getfield(L, idx, settingName(Window::SETTING_DISPLAY)); if (!lua_isnoneornil(L, -1)) @@ -197,7 +206,7 @@ int w_getMode(lua_State *L) luax_pushboolean(L, settings.stencil); lua_setfield(L, -2, settingName(Window::SETTING_STENCIL)); - lua_pushinteger(L, settings.depth); + luax_pushboolean(L, settings.depth); lua_setfield(L, -2, settingName(Window::SETTING_DEPTH)); luax_pushboolean(L, settings.resizable);