vulkan: implement discard

This commit is contained in:
niki
2022-09-11 17:09:38 +02:00
parent fd951909c0
commit 76199688f6
3 changed files with 126 additions and 41 deletions
+101 -35
View File
@@ -170,6 +170,51 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect); vkCmdClearAttachments(commandBuffers[currentFrame], static_cast<uint32_t>(attachments.size()), attachments.data(), 1, &rect);
} }
void Graphics::discard(const std::vector<bool>& colorbuffers, bool depthstencil)
{
if (renderPassState.active)
endRenderPass();
if (renderPassState.useConfigurations)
{
auto & renderPassConfiguration = renderPassState.renderPassConfiguration;
for (size_t i = 0; i < colorbuffers.size(); i++)
renderPassConfiguration.colorAttachments[i].discard = colorbuffers[i];
renderPassConfiguration.staticData.depthAttachment.discard = depthstencil;
}
else
{
RenderPassConfiguration renderPassConfiguration{};
renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, colorbuffers[0] });
renderPassConfiguration.staticData.depthAttachment = { findDepthFormat(), depthstencil };
renderPassConfiguration.staticData.msaaSamples = msaaSamples;
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
renderPassConfiguration.staticData.resolve = false;
else
renderPassConfiguration.staticData.resolve = true;
FramebufferConfiguration framebufferConfiguration{};
framebufferConfiguration.staticData.depthView = depthImageView;
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
{
framebufferConfiguration.colorViews.push_back(swapChainImageViews.at(imageIndex));
framebufferConfiguration.staticData.resolveView = VK_NULL_HANDLE;
}
else
{
framebufferConfiguration.colorViews.push_back(colorImageView);
framebufferConfiguration.staticData.resolveView = swapChainImageViews.at(imageIndex);
}
renderPassState.useConfigurations = true;
renderPassState.renderPassConfiguration = renderPassConfiguration;
renderPassState.framebufferConfiguration = framebufferConfiguration;
}
startRenderPass();
}
void Graphics::submitGpuCommands(bool present) void Graphics::submitGpuCommands(bool present)
{ {
flushBatchedDraws(); flushBatchedDraws();
@@ -357,6 +402,12 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
drawCalls = 0; drawCalls = 0;
drawCallsBatched = 0; drawCallsBatched = 0;
Vulkan::cmdTransitionImageLayout(
commandBuffers.at(currentFrame),
depthImage,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
return true; return true;
} }
@@ -892,7 +943,7 @@ uint32_t Graphics::getNumImagesInFlight() const
uint32_t Graphics::getFrameIndex() const uint32_t Graphics::getFrameIndex() const
{ {
return currentFrame; return static_cast<uint32_t>(currentFrame);
} }
const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const const VkDeviceSize Graphics::getMinUniformBufferOffsetAlignment() const
@@ -1640,9 +1691,9 @@ void Graphics::createImageViews()
void Graphics::createDefaultRenderPass() void Graphics::createDefaultRenderPass()
{ {
RenderPassConfiguration renderPassConfiguration{}; RenderPassConfiguration renderPassConfiguration{};
renderPassConfiguration.colorFormats.push_back(swapChainImageFormat); renderPassConfiguration.colorAttachments.push_back({ swapChainImageFormat, false });
renderPassConfiguration.staticData.msaaSamples = msaaSamples; renderPassConfiguration.staticData.msaaSamples = msaaSamples;
renderPassConfiguration.staticData.depthFormat = findDepthFormat(); renderPassConfiguration.staticData.depthAttachment = { findDepthFormat(), false };
if (msaaSamples & VK_SAMPLE_COUNT_1_BIT) if (msaaSamples & VK_SAMPLE_COUNT_1_BIT)
renderPassConfiguration.staticData.resolve = false; renderPassConfiguration.staticData.resolve = false;
else else
@@ -1738,7 +1789,7 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
std::vector<VkAttachmentReference> colorAttachmentRefs; std::vector<VkAttachmentReference> colorAttachmentRefs;
uint32_t attachment = 0; uint32_t attachment = 0;
for (const auto &colorFormat : configuration.colorFormats) for (const auto &colorAttachment : configuration.colorAttachments)
{ {
VkAttachmentReference reference{}; VkAttachmentReference reference{};
reference.attachment = attachment++; reference.attachment = attachment++;
@@ -1746,9 +1797,12 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
colorAttachmentRefs.push_back(reference); colorAttachmentRefs.push_back(reference);
VkAttachmentDescription colorDescription{}; VkAttachmentDescription colorDescription{};
colorDescription.format = colorFormat; colorDescription.format = colorAttachment.format;
colorDescription.samples = configuration.staticData.msaaSamples; colorDescription.samples = configuration.staticData.msaaSamples;
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; if (colorAttachment.discard)
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
else
colorDescription.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorDescription.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorDescription.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorDescription.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
@@ -1761,20 +1815,23 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
subPass.pColorAttachments = colorAttachmentRefs.data(); subPass.pColorAttachments = colorAttachmentRefs.data();
VkAttachmentReference depthStencilAttachmentRef{}; VkAttachmentReference depthStencilAttachmentRef{};
if (configuration.staticData.depthFormat != VK_FORMAT_UNDEFINED) if (configuration.staticData.depthAttachment.format != VK_FORMAT_UNDEFINED)
{ {
depthStencilAttachmentRef.attachment = attachment++; depthStencilAttachmentRef.attachment = attachment++;
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
subPass.pDepthStencilAttachment = &depthStencilAttachmentRef; subPass.pDepthStencilAttachment = &depthStencilAttachmentRef;
VkAttachmentDescription depthStencilAttachment{}; VkAttachmentDescription depthStencilAttachment{};
depthStencilAttachment.format = configuration.staticData.depthFormat; depthStencilAttachment.format = configuration.staticData.depthAttachment.format;
depthStencilAttachment.samples = configuration.staticData.msaaSamples; depthStencilAttachment.samples = configuration.staticData.msaaSamples;
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; if (configuration.staticData.depthAttachment.discard)
depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
else
depthStencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
depthStencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthStencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthStencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; depthStencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; depthStencilAttachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; depthStencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments.push_back(depthStencilAttachment); attachments.push_back(depthStencilAttachment);
} }
@@ -1787,7 +1844,7 @@ VkRenderPass Graphics::createRenderPass(RenderPassConfiguration &configuration)
subPass.pResolveAttachments = &colorAttachmentResolveRef; subPass.pResolveAttachments = &colorAttachmentResolveRef;
VkAttachmentDescription colorAttachmentResolve{}; VkAttachmentDescription colorAttachmentResolve{};
colorAttachmentResolve.format = configuration.colorFormats.at(0); colorAttachmentResolve.format = configuration.colorAttachments.at(0).format;
colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT; colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -1861,7 +1918,7 @@ void Graphics::createVulkanVertexFormat(
auto attrib = vertexAttributes.attribs[i]; auto attrib = vertexAttributes.attribs[i];
auto bufferBinding = attrib.bufferIndex; auto bufferBinding = attrib.bufferIndex;
if (usedBuffers.find(bufferBinding) == usedBuffers.end()) // use .contains() when c++20 is enabled if (usedBuffers.find(bufferBinding) == usedBuffers.end())
{ {
usedBuffers.insert(bufferBinding); usedBuffers.insert(bufferBinding);
@@ -1918,7 +1975,7 @@ void Graphics::prepareDraw(const VertexAttributes &attributes, const BufferBindi
GraphicsPipelineConfiguration configuration{}; GraphicsPipelineConfiguration configuration{};
configuration.renderPass = renderPassState.renderPass; configuration.renderPass = renderPassState.beginInfo.renderPass;
configuration.vertexAttributes = attributes; configuration.vertexAttributes = attributes;
configuration.shader = (Shader*)Shader::current; configuration.shader = (Shader*)Shader::current;
configuration.wireFrame = states.back().wireframe; configuration.wireFrame = states.back().wireframe;
@@ -1976,7 +2033,7 @@ void Graphics::setDefaultRenderPass()
renderPassState.beginInfo.renderArea.extent = swapChainExtent; renderPassState.beginInfo.renderArea.extent = swapChainExtent;
renderPassState.beginInfo.clearValueCount = 0; renderPassState.beginInfo.clearValueCount = 0;
renderPassState.renderPass = defaultRenderPass; renderPassState.useConfigurations = false;
renderPassState.pipeline = VK_NULL_HANDLE; renderPassState.pipeline = VK_NULL_HANDLE;
renderPassState.width = static_cast<float>(swapChainExtent.width); renderPassState.width = static_cast<float>(swapChainExtent.width);
renderPassState.height = static_cast<float>(swapChainExtent.height); renderPassState.height = static_cast<float>(swapChainExtent.height);
@@ -2017,7 +2074,7 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
// fixme: use mipmap and slice. // fixme: use mipmap and slice.
color.mipmap; color.mipmap;
color.slice; color.slice;
renderPassConfiguration.colorFormats.push_back(Vulkan::getTextureFormat(color.texture->getPixelFormat()).internalFormat); renderPassConfiguration.colorAttachments.push_back({ Vulkan::getTextureFormat(color.texture->getPixelFormat()).internalFormat, false });
} }
if (rts.depthStencil.texture != nullptr) if (rts.depthStencil.texture != nullptr)
{ {
@@ -2025,17 +2082,7 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
rts.depthStencil.mipmap; rts.depthStencil.mipmap;
rts.depthStencil.slice; rts.depthStencil.slice;
if (rts.depthStencil.texture != nullptr) if (rts.depthStencil.texture != nullptr)
renderPassConfiguration.staticData.depthFormat = Vulkan::getTextureFormat(rts.depthStencil.texture->getPixelFormat()).internalFormat; renderPassConfiguration.staticData.depthAttachment = { Vulkan::getTextureFormat(rts.depthStencil.texture->getPixelFormat()).internalFormat, false };
}
VkRenderPass renderPass;
auto it = renderPasses.find(renderPassConfiguration);
if (it != renderPasses.end())
renderPass = it->second;
else
{
renderPass = createRenderPass(renderPassConfiguration);
renderPasses[renderPassConfiguration] = renderPass;
} }
FramebufferConfiguration configuration{}; FramebufferConfiguration configuration{};
@@ -2051,20 +2098,20 @@ void Graphics::setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, b
// fixme: layout transition of depth stencil image? // fixme: layout transition of depth stencil image?
configuration.staticData.depthView = (VkImageView)rts.depthStencil.texture->getRenderTargetHandle(); configuration.staticData.depthView = (VkImageView)rts.depthStencil.texture->getRenderTargetHandle();
configuration.staticData.renderPass = renderPass;
configuration.staticData.width = static_cast<uint32_t>(pixelw); configuration.staticData.width = static_cast<uint32_t>(pixelw);
configuration.staticData.height = static_cast<uint32_t>(pixelh); configuration.staticData.height = static_cast<uint32_t>(pixelh);
VkFramebuffer framebuffer = getFramebuffer(configuration);
renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; renderPassState.beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassState.beginInfo.renderPass = renderPass; renderPassState.beginInfo.renderPass = VK_NULL_HANDLE;
renderPassState.beginInfo.framebuffer = framebuffer; renderPassState.beginInfo.framebuffer = VK_NULL_HANDLE;
renderPassState.beginInfo.renderArea.offset = {0, 0}; renderPassState.beginInfo.renderArea.offset = {0, 0};
renderPassState.beginInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw); renderPassState.beginInfo.renderArea.extent.width = static_cast<uint32_t>(pixelw);
renderPassState.beginInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh); renderPassState.beginInfo.renderArea.extent.height = static_cast<uint32_t>(pixelh);
renderPassState.beginInfo.clearValueCount = 0; renderPassState.beginInfo.clearValueCount = 0;
renderPassState.renderPass = renderPass; renderPassState.useConfigurations = true;
renderPassState.renderPassConfiguration = renderPassConfiguration;
renderPassState.framebufferConfiguration = configuration;
renderPassState.pipeline = VK_NULL_HANDLE; renderPassState.pipeline = VK_NULL_HANDLE;
renderPassState.width = static_cast<float>(pixelw); renderPassState.width = static_cast<float>(pixelw);
renderPassState.height = static_cast<float>(pixelh); renderPassState.height = static_cast<float>(pixelh);
@@ -2077,6 +2124,25 @@ void Graphics::startRenderPass()
{ {
renderPassState.active = true; renderPassState.active = true;
if (renderPassState.useConfigurations)
{
auto &renderPassConfiguration = renderPassState.renderPassConfiguration;
VkRenderPass renderPass;
auto it = renderPasses.find(renderPassConfiguration);
if (it != renderPasses.end())
renderPass = it->second;
else
{
renderPass = createRenderPass(renderPassConfiguration);
renderPasses[renderPassConfiguration] = renderPass;
}
renderPassState.beginInfo.renderPass = renderPass;
auto &framebufferConfiguration = renderPassState.framebufferConfiguration;
framebufferConfiguration.staticData.renderPass = renderPass;
renderPassState.beginInfo.framebuffer = getFramebuffer(framebufferConfiguration);
}
for (const auto& image : renderPassState.transitionImages) for (const auto& image : renderPassState.transitionImages)
Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); Vulkan::cmdTransitionImageLayout(commandBuffers.at(currentFrame), image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
@@ -2429,12 +2495,12 @@ VkFormat Graphics::findDepthFormat()
void Graphics::createDepthResources() void Graphics::createDepthResources()
{ {
VkFormat depthFormat = findDepthFormat(); VkFormat depthAttachment = findDepthFormat();
VkImageCreateInfo imageInfo{}; VkImageCreateInfo imageInfo{};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageInfo.imageType = VK_IMAGE_TYPE_2D; imageInfo.imageType = VK_IMAGE_TYPE_2D;
imageInfo.format = depthFormat; imageInfo.format = depthAttachment;
imageInfo.extent.width = swapChainExtent.width; imageInfo.extent.width = swapChainExtent.width;
imageInfo.extent.height = swapChainExtent.height; imageInfo.extent.height = swapChainExtent.height;
imageInfo.extent.depth = 1; imageInfo.extent.depth = 1;
@@ -2456,7 +2522,7 @@ void Graphics::createDepthResources()
imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; imageViewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
imageViewInfo.image = depthImage; imageViewInfo.image = depthImage;
imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; imageViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewInfo.format = depthFormat; imageViewInfo.format = depthAttachment;
imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
+19 -6
View File
@@ -27,20 +27,31 @@ namespace graphics
namespace vulkan namespace vulkan
{ {
struct RenderPassAttachment
{
VkFormat format = VK_FORMAT_UNDEFINED;
bool discard = true;
bool operator==(const RenderPassAttachment &attachment) const
{
return format == attachment.format && discard == attachment.discard;
}
};
struct RenderPassConfiguration struct RenderPassConfiguration
{ {
std::vector<VkFormat> colorFormats; std::vector<RenderPassAttachment> colorAttachments;
struct StaticRenderPassConfiguration struct StaticRenderPassConfiguration
{ {
VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT; VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
VkFormat depthFormat = VK_FORMAT_UNDEFINED; RenderPassAttachment depthAttachment;
bool resolve = false; bool resolve = false;
} staticData; } staticData;
bool operator==(const RenderPassConfiguration &conf) const bool operator==(const RenderPassConfiguration &conf) const
{ {
return colorFormats == conf.colorFormats && return colorAttachments == conf.colorAttachments &&
(memcmp(&staticData, &conf.staticData, sizeof(StaticRenderPassConfiguration)) == 0); (memcmp(&staticData, &conf.staticData, sizeof(StaticRenderPassConfiguration)) == 0);
} }
}; };
@@ -50,7 +61,7 @@ struct RenderPassConfigurationHasher
size_t operator()(const RenderPassConfiguration &configuration) const size_t operator()(const RenderPassConfiguration &configuration) const
{ {
size_t hashes[] = { size_t hashes[] = {
XXH32(configuration.colorFormats.data(), configuration.colorFormats.size() * sizeof(VkFormat), 0), XXH32(configuration.colorAttachments.data(), configuration.colorAttachments.size() * sizeof(VkFormat), 0),
XXH32(&configuration.staticData, sizeof(configuration.staticData), 0), XXH32(&configuration.staticData, sizeof(configuration.staticData), 0),
}; };
return XXH32(hashes, sizeof(hashes), 0); return XXH32(hashes, sizeof(hashes), 0);
@@ -233,7 +244,9 @@ struct RenderpassState
{ {
bool active = false; bool active = false;
VkRenderPassBeginInfo beginInfo{}; VkRenderPassBeginInfo beginInfo{};
VkRenderPass renderPass = VK_NULL_HANDLE; bool useConfigurations = false;
RenderPassConfiguration renderPassConfiguration{};
FramebufferConfiguration framebufferConfiguration{};
VkPipeline pipeline = VK_NULL_HANDLE; VkPipeline pipeline = VK_NULL_HANDLE;
std::vector<VkImage> transitionImages; std::vector<VkImage> transitionImages;
uint32_t numColorAttachments = 0; uint32_t numColorAttachments = 0;
@@ -268,7 +281,7 @@ public:
void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override; void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override; void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override;
Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override;
void discard(const std::vector<bool> &colorbuffers, bool depthstencil) override { } void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override;
void present(void *screenshotCallbackdata) override; void present(void *screenshotCallbackdata) override;
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) 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; bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
+6
View File
@@ -792,6 +792,8 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
(newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)) (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL))
{ {
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
barrier.srcAccessMask = 0; barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
@@ -801,6 +803,8 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
else if ((oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || oldLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) && else if ((oldLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || oldLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL) &&
newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
{ {
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
@@ -810,6 +814,8 @@ void Vulkan::cmdTransitionImageLayout(VkCommandBuffer commandBuffer, VkImage ima
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
(newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL)) (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || newLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL))
{ {
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;