diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 980a565a8..735946f6c 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -185,89 +185,12 @@ void Graphics::clear(OptionalColorD color, OptionalInt stencil, OptionalDouble d if (!color.hasValue && !stencil.hasValue && !depth.hasValue) return; - flushBatchedDraws(); - - if (renderPassState.active) - { - VkClearAttachment attachment{}; - - if (color.hasValue) - { - Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a); - gammaCorrectColor(cf); - - attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - attachment.clearValue.color.float32[0] = static_cast(cf.r); - attachment.clearValue.color.float32[1] = static_cast(cf.g); - attachment.clearValue.color.float32[2] = static_cast(cf.b); - attachment.clearValue.color.float32[3] = static_cast(cf.a); - } - - VkClearAttachment depthStencilAttachment{}; - - if (stencil.hasValue) - { - depthStencilAttachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; - depthStencilAttachment.clearValue.depthStencil.stencil = static_cast(stencil.value); - } - if (depth.hasValue) - { - depthStencilAttachment.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; - depthStencilAttachment.clearValue.depthStencil.depth = static_cast(depth.value); - } - - std::array attachments = { - attachment, - depthStencilAttachment - }; - - VkClearRect rect{}; - rect.layerCount = 1; - rect.rect.extent.width = static_cast(renderPassState.width); - rect.rect.extent.height = static_cast(renderPassState.height); - - vkCmdClearAttachments( - commandBuffers[currentFrame], - static_cast(attachments.size()), attachments.data(), - 1, &rect); - } - else - { - if (color.hasValue) - { - renderPassState.renderPassConfiguration.colorAttachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + std::vector colors; - Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a); - gammaCorrectColor(cf); + if (color.hasValue) + colors.resize(std::max(1, (int)states.back().renderTargets.colors.size()), color); - renderPassState.clearColors[0].color.float32[0] = static_cast(cf.r); - renderPassState.clearColors[0].color.float32[1] = static_cast(cf.g); - renderPassState.clearColors[0].color.float32[2] = static_cast(cf.b); - renderPassState.clearColors[0].color.float32[3] = static_cast(cf.a); - } - - if (depth.hasValue) - { - renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.depthLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - renderPassState.clearColors[1].depthStencil.depth = static_cast(depth.value); - } - - if (stencil.hasValue) - { - renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - renderPassState.clearColors[1].depthStencil.stencil = static_cast(stencil.value); - } - - if (renderPassState.isWindow) - { - renderPassState.windowClearRequested = true; - renderPassState.mainWindowClearColorValue = color; - renderPassState.mainWindowClearDepthValue = depth; - renderPassState.mainWindowClearStencilValue = stencil; - } - else - startRenderPass(); - } + clear(colors, stencil, depth); } void Graphics::clear(const std::vector &colors, OptionalInt stencil, OptionalDouble depth) @@ -277,22 +200,22 @@ void Graphics::clear(const std::vector &colors, OptionalInt sten flushBatchedDraws(); + const auto &rts = states.back().renderTargets.colors; + size_t ncolorbuffers = isRenderTargetActive() ? rts.size() : 1; + size_t ncolors = std::min(ncolorbuffers, colors.size()); + if (renderPassState.active) { std::vector attachments; - for (const auto &color : colors) + for (size_t i = 0; i < ncolors; i++) { + const OptionalColorD &color = colors[i]; VkClearAttachment attachment{}; if (color.hasValue) { - Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a); - gammaCorrectColor(cf); - + auto texture = i < rts.size() ? rts[i].texture.get() : nullptr; attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - attachment.clearValue.color.float32[0] = static_cast(cf.r); - attachment.clearValue.color.float32[1] = static_cast(cf.g); - attachment.clearValue.color.float32[2] = static_cast(cf.b); - attachment.clearValue.color.float32[3] = static_cast(cf.a); + attachment.clearValue.color = Texture::getClearColor(texture, color.value); } attachments.push_back(attachment); } @@ -310,7 +233,8 @@ void Graphics::clear(const std::vector &colors, OptionalInt sten depthStencilAttachment.clearValue.depthStencil.depth = static_cast(depth.value); } - attachments.push_back(depthStencilAttachment); + if (stencil.hasValue || depth.hasValue) + attachments.push_back(depthStencilAttachment); VkClearRect rect{}; rect.layerCount = 1; @@ -324,36 +248,38 @@ void Graphics::clear(const std::vector &colors, OptionalInt sten } else { - for (size_t i = 0; i < colors.size(); i++) + for (size_t i = 0; i < ncolors; i++) { if (colors[i].hasValue) { renderPassState.renderPassConfiguration.colorAttachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - auto &color = colors[i]; - Colorf cf((float)color.value.r, (float)color.value.g, (float)color.value.b, (float)color.value.a); - gammaCorrectColor(cf); - - renderPassState.clearColors[i].color.float32[0] = static_cast(cf.r); - renderPassState.clearColors[i].color.float32[1] = static_cast(cf.g); - renderPassState.clearColors[i].color.float32[2] = static_cast(cf.b); - renderPassState.clearColors[i].color.float32[3] = static_cast(cf.a); + auto texture = i < rts.size() ? rts[i].texture.get() : nullptr; + renderPassState.clearColors[i].color = Texture::getClearColor(texture, colors[i].value); } } if (depth.hasValue) { renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.depthLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - renderPassState.clearColors[colors.size()].depthStencil.depth = static_cast(depth.value); + renderPassState.clearColors[ncolorbuffers].depthStencil.depth = static_cast(depth.value); } if (stencil.hasValue) { renderPassState.renderPassConfiguration.staticData.depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - renderPassState.clearColors[colors.size()].depthStencil.stencil = static_cast(stencil.value); + renderPassState.clearColors[ncolorbuffers].depthStencil.stencil = static_cast(stencil.value); } - startRenderPass(); + if (renderPassState.isWindow) + { + renderPassState.windowClearRequested = true; + renderPassState.mainWindowClearColorValue = colors.empty() ? OptionalColorD() : colors[0]; + renderPassState.mainWindowClearDepthValue = depth; + renderPassState.mainWindowClearStencilValue = stencil; + } + else + startRenderPass(); } } diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index 7400a1464..ccf01dfca 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -383,7 +383,7 @@ void Texture::clear() VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS); - auto clearColor = getClearValue(); + auto clearColor = getClearColor(this, ColorD(0, 0, 0, 0)); vkCmdClearColorImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); @@ -393,7 +393,7 @@ void Texture::clear() } else if (imageLayout == VK_IMAGE_LAYOUT_GENERAL) { - auto clearColor = getClearValue(); + auto clearColor = getClearColor(this, ColorD(0, 0, 0, 0)); vkCmdClearColorImage(commandBuffer, textureImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &range); } @@ -415,33 +415,41 @@ void Texture::clear() } } -VkClearColorValue Texture::getClearValue() +VkClearColorValue Texture::getClearColor(love::graphics::Texture *texture, const ColorD &color) { - auto vulkanFormat = Vulkan::getTextureFormat(format); + PixelFormatType formattype = PIXELFORMATTYPE_SFLOAT; + if (texture != nullptr) + formattype = getPixelFormatInfo(texture->getPixelFormat()).dataType; + + VkClearColorValue c{}; - VkClearColorValue clearColor{}; - switch (vulkanFormat.internalFormatRepresentation) + switch (formattype) { - case FORMATREPRESENTATION_FLOAT: - clearColor.float32[0] = 0.0f; - clearColor.float32[1] = 0.0f; - clearColor.float32[2] = 0.0f; - clearColor.float32[3] = 0.0f; + case PIXELFORMATTYPE_SINT: + c.int32[0] = (int32)color.r; + c.int32[1] = (int32)color.g; + c.int32[2] = (int32)color.b; + c.int32[3] = (int32)color.a; break; - case FORMATREPRESENTATION_SINT: - clearColor.int32[0] = 0; - clearColor.int32[1] = 0; - clearColor.int32[2] = 0; - clearColor.int32[3] = 0; + case PIXELFORMATTYPE_UINT: + c.uint32[0] = (uint32)color.r; + c.uint32[1] = (uint32)color.g; + c.uint32[2] = (uint32)color.b; + c.uint32[3] = (uint32)color.a; break; - case FORMATREPRESENTATION_UINT: - clearColor.uint32[0] = 0; - clearColor.uint32[1] = 0; - clearColor.uint32[2] = 0; - clearColor.uint32[3] = 0; + default: + { + Colorf cf((float)color.r, (float)color.g, (float)color.b, (float)color.a); + gammaCorrectColor(cf); + c.float32[0] = cf.r; + c.float32[1] = cf.g; + c.float32[2] = cf.b; + c.float32[3] = cf.a; + } break; } - return clearColor; + + return c; } void Texture::generateMipmapsInternal() diff --git a/src/modules/graphics/vulkan/Texture.h b/src/modules/graphics/vulkan/Texture.h index 9ad198378..e9dac8be7 100644 --- a/src/modules/graphics/vulkan/Texture.h +++ b/src/modules/graphics/vulkan/Texture.h @@ -68,12 +68,12 @@ class Texture final int getMSAA() const override; ptrdiff_t getHandle() const override; + static VkClearColorValue getClearColor(love::graphics::Texture *texture, const ColorD &color); + private: void createTextureImageView(); void clear(); - VkClearColorValue getClearValue(); - Graphics *vgfx = nullptr; VkDevice device = VK_NULL_HANDLE; VkImageAspectFlags imageAspect;