Fixed image layout transitions and initial layouts and command buffer submissions for offscreen examples

This commit is contained in:
saschawillems 2016-03-13 16:04:39 +01:00
parent 01f0a1a574
commit 72e6cd8ee5
5 changed files with 77 additions and 46 deletions

View file

@ -199,6 +199,8 @@ public:
// the offscreen framebuffer // the offscreen framebuffer
void prepareTextureTarget(vkTools::VulkanTexture *tex, uint32_t width, uint32_t height, VkFormat format) void prepareTextureTarget(vkTools::VulkanTexture *tex, uint32_t width, uint32_t height, VkFormat format)
{ {
createSetupCommandBuffer();
VkFormatProperties formatProperties; VkFormatProperties formatProperties;
VkResult err; VkResult err;
@ -236,8 +238,7 @@ public:
err = vkBindImageMemory(device, tex->image, tex->deviceMemory, 0); err = vkBindImageMemory(device, tex->image, tex->deviceMemory, 0);
assert(!err); assert(!err);
// Transform image layout to transer destination tex->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
tex->imageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
tex->image, tex->image,
@ -272,6 +273,8 @@ public:
view.image = tex->image; view.image = tex->image;
err = vkCreateImageView(device, &view, nullptr, &tex->view); err = vkCreateImageView(device, &view, nullptr, &tex->view);
assert(!err); assert(!err);
flushSetupCommandBuffer();
} }
// Prepare a new framebuffer for offscreen rendering // Prepare a new framebuffer for offscreen rendering
@ -372,7 +375,7 @@ public:
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
frameBuf->depth.image, frameBuf->depth.image,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);

View file

@ -200,7 +200,7 @@ public:
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
// Texture will be sampled in a shader and is also the blit destination // Texture will be sampled in a shader and is also the blit destination
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageCreateInfo.flags = 0; imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs; VkMemoryRequirements memReqs;
@ -218,12 +218,12 @@ public:
// Image memory barrier // Image memory barrier
// Set initial layout for the offscreen texture transfer destination // Set initial layout for the offscreen texture transfer destination
// Will be transformed while updating the texture // Will be transformed while updating the texture
offScreenFrameBuf.textureTarget.imageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; offScreenFrameBuf.textureTarget.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.textureTarget.image, offScreenFrameBuf.textureTarget.image,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED,
offScreenFrameBuf.textureTarget.imageLayout); offScreenFrameBuf.textureTarget.imageLayout);
// Create sampler // Create sampler
@ -264,6 +264,7 @@ public:
// blitted to our render target // blitted to our render target
void prepareOffscreenFramebuffer() void prepareOffscreenFramebuffer()
{ {
createSetupCommandBuffer(); createSetupCommandBuffer();
offScreenFrameBuf.width = FB_DIM; offScreenFrameBuf.width = FB_DIM;
@ -293,6 +294,7 @@ public:
image.flags = 0; image.flags = 0;
VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo memAlloc = vkTools::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs;
VkImageViewCreateInfo colorImageView = vkTools::initializers::imageViewCreateInfo(); VkImageViewCreateInfo colorImageView = vkTools::initializers::imageViewCreateInfo();
colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D; colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
@ -305,8 +307,6 @@ public:
colorImageView.subresourceRange.baseArrayLayer = 0; colorImageView.subresourceRange.baseArrayLayer = 0;
colorImageView.subresourceRange.layerCount = 1; colorImageView.subresourceRange.layerCount = 1;
VkMemoryRequirements memReqs;
err = vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.color.image); err = vkCreateImage(device, &image, nullptr, &offScreenFrameBuf.color.image);
assert(!err); assert(!err);
vkGetImageMemoryRequirements(device, offScreenFrameBuf.color.image, &memReqs); vkGetImageMemoryRequirements(device, offScreenFrameBuf.color.image, &memReqs);
@ -317,11 +317,12 @@ public:
err = vkBindImageMemory(device, offScreenFrameBuf.color.image, offScreenFrameBuf.color.mem, 0); err = vkBindImageMemory(device, offScreenFrameBuf.color.image, offScreenFrameBuf.color.mem, 0);
assert(!err); assert(!err);
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.color.image, offScreenFrameBuf.color.image,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
colorImageView.image = offScreenFrameBuf.color.image; colorImageView.image = offScreenFrameBuf.color.image;
@ -353,25 +354,25 @@ public:
err = vkBindImageMemory(device, offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.mem, 0); err = vkBindImageMemory(device, offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.mem, 0);
assert(!err); assert(!err);
createSetupCommandBuffer();
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.image,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthStencilView.image = offScreenFrameBuf.depth.image; depthStencilView.image = offScreenFrameBuf.depth.image;
err = vkCreateImageView(device, &depthStencilView, nullptr, &offScreenFrameBuf.depth.view); err = vkCreateImageView(device, &depthStencilView, nullptr, &offScreenFrameBuf.depth.view);
assert(!err); assert(!err);
flushSetupCommandBuffer();
VkImageView attachments[2]; VkImageView attachments[2];
attachments[0] = offScreenFrameBuf.color.view; attachments[0] = offScreenFrameBuf.color.view;
attachments[1] = offScreenFrameBuf.depth.view; attachments[1] = offScreenFrameBuf.depth.view;
VkFramebufferCreateInfo fbufCreateInfo = {}; VkFramebufferCreateInfo fbufCreateInfo = vkTools::initializers::framebufferCreateInfo();
fbufCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbufCreateInfo.pNext = NULL;
fbufCreateInfo.renderPass = renderPass; fbufCreateInfo.renderPass = renderPass;
fbufCreateInfo.attachmentCount = 2; fbufCreateInfo.attachmentCount = 2;
fbufCreateInfo.pAttachments = attachments; fbufCreateInfo.pAttachments = attachments;
@ -381,8 +382,6 @@ public:
err = vkCreateFramebuffer(device, &fbufCreateInfo, nullptr, &offScreenFrameBuf.frameBuffer); err = vkCreateFramebuffer(device, &fbufCreateInfo, nullptr, &offScreenFrameBuf.frameBuffer);
assert(!err); assert(!err);
flushSetupCommandBuffer();
} }
void createOffscreenCommandBuffer() void createOffscreenCommandBuffer()
@ -519,7 +518,6 @@ public:
err = vkEndCommandBuffer(offScreenCmdBuffer); err = vkEndCommandBuffer(offScreenCmdBuffer);
assert(!err); assert(!err);
} }
void buildCommandBuffers() void buildCommandBuffers()

View file

@ -175,6 +175,8 @@ public:
// the offscreen framebuffer // the offscreen framebuffer
void prepareTextureTarget(vkTools::VulkanTexture *tex, uint32_t width, uint32_t height, VkFormat format) void prepareTextureTarget(vkTools::VulkanTexture *tex, uint32_t width, uint32_t height, VkFormat format)
{ {
createSetupCommandBuffer();
VkFormatProperties formatProperties; VkFormatProperties formatProperties;
VkResult err; VkResult err;
@ -196,6 +198,8 @@ public:
imageCreateInfo.arrayLayers = 1; imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
// Texture will be sampled in a shader and is also the blit destination // Texture will be sampled in a shader and is also the blit destination
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
@ -212,13 +216,13 @@ public:
err = vkBindImageMemory(device, tex->image, tex->deviceMemory, 0); err = vkBindImageMemory(device, tex->image, tex->deviceMemory, 0);
assert(!err); assert(!err);
// Transform image layout to transer destination // Transform image layout to transfer destination
tex->imageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; tex->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
tex->image, tex->image,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED,
tex->imageLayout); tex->imageLayout);
// Create sampler // Create sampler
@ -248,6 +252,8 @@ public:
view.image = tex->image; view.image = tex->image;
err = vkCreateImageView(device, &view, nullptr, &tex->view); err = vkCreateImageView(device, &view, nullptr, &tex->view);
assert(!err); assert(!err);
flushSetupCommandBuffer();
} }
// Prepare a new framebuffer for offscreen rendering // Prepare a new framebuffer for offscreen rendering
@ -348,7 +354,7 @@ public:
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.image,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);

View file

@ -166,8 +166,11 @@ public:
vkDestroyFramebuffer(device, offScreenFrameBuf.frameBuffer, nullptr); vkDestroyFramebuffer(device, offScreenFrameBuf.frameBuffer, nullptr);
vkDestroyRenderPass(device, offScreenFrameBuf.renderPass, nullptr);
vkDestroyPipeline(device, pipelines.quad, nullptr); vkDestroyPipeline(device, pipelines.quad, nullptr);
vkDestroyPipeline(device, pipelines.offscreen, nullptr); vkDestroyPipeline(device, pipelines.offscreen, nullptr);
vkDestroyPipeline(device, pipelines.scene, nullptr);
vkDestroyPipelineLayout(device, pipelineLayouts.quad, nullptr); vkDestroyPipelineLayout(device, pipelineLayouts.quad, nullptr);
vkDestroyPipelineLayout(device, pipelineLayouts.offscreen, nullptr); vkDestroyPipelineLayout(device, pipelineLayouts.offscreen, nullptr);
@ -213,9 +216,8 @@ public:
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
imageCreateInfo.flags = 0;
imageCreateInfo.pQueueFamilyIndices = 0;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo();
VkMemoryRequirements memReqs; VkMemoryRequirements memReqs;
@ -235,7 +237,7 @@ public:
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.textureTarget.image, offScreenFrameBuf.textureTarget.image,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED,
offScreenFrameBuf.textureTarget.imageLayout); offScreenFrameBuf.textureTarget.imageLayout);
// Create sampler // Create sampler

View file

@ -195,6 +195,7 @@ public:
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; imageCreateInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo();
@ -231,12 +232,18 @@ public:
assert(!err); assert(!err);
// Image barrier for optimal image (target) // Image barrier for optimal image (target)
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 6;
vkTools::setImageLayout( vkTools::setImageLayout(
cmdBuffer, cmdBuffer,
shadowCubeMap.image, shadowCubeMap.image,
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
err = vkEndCommandBuffer(cmdBuffer); err = vkEndCommandBuffer(cmdBuffer);
assert(!err); assert(!err);
@ -357,14 +364,14 @@ public:
// Depth stencil attachment // Depth stencil attachment
image.format = fbDepthFormat; image.format = fbDepthFormat;
image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
image.initialLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; image.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
VkImageViewCreateInfo depthStencilView = vkTools::initializers::imageViewCreateInfo(); VkImageViewCreateInfo depthStencilView = vkTools::initializers::imageViewCreateInfo();
depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D;
depthStencilView.format = fbDepthFormat; depthStencilView.format = fbDepthFormat;
depthStencilView.flags = 0; depthStencilView.flags = 0;
depthStencilView.subresourceRange = {}; depthStencilView.subresourceRange = {};
depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; depthStencilView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
depthStencilView.subresourceRange.baseMipLevel = 0; depthStencilView.subresourceRange.baseMipLevel = 0;
depthStencilView.subresourceRange.levelCount = 1; depthStencilView.subresourceRange.levelCount = 1;
depthStencilView.subresourceRange.baseArrayLayer = 0; depthStencilView.subresourceRange.baseArrayLayer = 0;
@ -384,8 +391,8 @@ public:
vkTools::setImageLayout( vkTools::setImageLayout(
setupCmdBuffer, setupCmdBuffer,
offScreenFrameBuf.depth.image, offScreenFrameBuf.depth.image,
VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
flushSetupCommandBuffer(); flushSetupCommandBuffer();
@ -481,7 +488,6 @@ public:
vkCmdDrawIndexed(offScreenCmdBuffer, meshes.scene.indexCount, 1, 0, 0, 0); vkCmdDrawIndexed(offScreenCmdBuffer, meshes.scene.indexCount, 1, 0, 0, 0);
vkCmdEndRenderPass(offScreenCmdBuffer); vkCmdEndRenderPass(offScreenCmdBuffer);
// Make sure color writes to the framebuffer are finished before using it as transfer source // Make sure color writes to the framebuffer are finished before using it as transfer source
vkTools::setImageLayout( vkTools::setImageLayout(
offScreenCmdBuffer, offScreenCmdBuffer,
@ -519,14 +525,6 @@ public:
1, 1,
&copyRegion); &copyRegion);
// Make sure transfer to cube map face is finished before sampling it in a shader
vkTools::setImageLayout(
offScreenCmdBuffer,
shadowCubeMap.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// Transform framebuffer color attachment back // Transform framebuffer color attachment back
vkTools::setImageLayout( vkTools::setImageLayout(
offScreenCmdBuffer, offScreenCmdBuffer,
@ -572,11 +570,35 @@ public:
0); 0);
vkCmdSetScissor(offScreenCmdBuffer, 0, 1, &scissor); vkCmdSetScissor(offScreenCmdBuffer, 0, 1, &scissor);
VkImageSubresourceRange subresourceRange = {};
subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresourceRange.baseMipLevel = 0;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 6;
// Change image layout for all cubemap faces to transfer destination
vkTools::setImageLayout(
offScreenCmdBuffer,
shadowCubeMap.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
for (uint32_t face = 0; face < 6; ++face) for (uint32_t face = 0; face < 6; ++face)
{ {
updateCubeFace(face); updateCubeFace(face);
} }
// Change image layout for all cubemap faces to shader read after they have been copied
vkTools::setImageLayout(
offScreenCmdBuffer,
shadowCubeMap.image,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
err = vkEndCommandBuffer(offScreenCmdBuffer); err = vkEndCommandBuffer(offScreenCmdBuffer);
assert(!err); assert(!err);
} }