Alfonse_Reinheart thanks for your reminder and help.
I post my code on below and after call vkCmdBeginRenderPass the validation message is
A dependency between subpasses 1 and 2 must exist but one is not specified.
A dependency between subpasses 1 and 2 must exist but one is not specified.
A dependency between subpasses 2 and 1 must exist but one is not specified.
A dependency between subpasses 2 and 1 must exist but one is not specified.
void example()
{
VkExtent2D ext = knight::vulkan::env::GetSwapChainExtent();
VkImage depthStencilImg;
VkDeviceMemory depthStencilMem;
VkImageView depthStencilImgView;
VkImageCreateInfo depthStencilCI = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 0, 0,
VK_IMAGE_TYPE_2D, VK_FORMAT_D24_UNORM_S8_UINT,
{ext.width, ext.height, 1},
1, 1, VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_SHARING_MODE_EXCLUSIVE, 0, 0, VK_IMAGE_LAYOUT_UNDEFINED
};
if (vkCreateImage(knight::vulkan::env::Device(), &depthStencilCI, nullptr, &depthStencilImg) == VK_SUCCESS)
{
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(knight::vulkan::env::Device(), depthStencilImg, &memRequirements);
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = knight::vulkan::env::FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (vkAllocateMemory(knight::vulkan::env::Device(), &allocInfo, nullptr, &depthStencilMem) == VK_SUCCESS)
{
vkBindImageMemory(knight::vulkan::env::Device(), depthStencilImg, depthStencilMem, 0);
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
viewInfo.image = depthStencilImg;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = depthStencilCI.format;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(knight::vulkan::env::Device(), &viewInfo, nullptr, &depthStencilImgView) != VK_SUCCESS)
{
throw(-1);
}
}
else
{
throw(-1);
}
}
VkImage transparencyImg;
VkDeviceMemory transparencyMem;
VkImageView transparencyImgView;
VkImageCreateInfo transparencyCI = {
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 0, 0,
VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
{ext.width, ext.height, 1},
1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
VK_SHARING_MODE_EXCLUSIVE, 0, 0, VK_IMAGE_LAYOUT_UNDEFINED
};
if (vkCreateImage(knight::vulkan::env::Device(), &transparencyCI, nullptr, &transparencyImg) == VK_SUCCESS)
{
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(knight::vulkan::env::Device(), transparencyImg, &memRequirements);
VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = knight::vulkan::env::FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
if (vkAllocateMemory(knight::vulkan::env::Device(), &allocInfo, nullptr, &transparencyMem) == VK_SUCCESS)
{
vkBindImageMemory(knight::vulkan::env::Device(), transparencyImg, transparencyMem, 0);
VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
viewInfo.image = transparencyImg;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = transparencyCI.format;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = 0;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
viewInfo.subresourceRange.layerCount = 1;
if (vkCreateImageView(knight::vulkan::env::Device(), &viewInfo, nullptr, &transparencyImgView) != VK_SUCCESS)
{
throw(-1);
}
}
else
{
throw(-1);
}
}
enum {BACKBUFFER, DEPTH_STENCIL, TRANS_IMG};
std::vector<VkAttachmentDescription> attachmentDescription(3);
attachmentDescription[BACKBUFFER] = {
0, knight::vulkan::env::SwapChainFormat(), VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR };
attachmentDescription[DEPTH_STENCIL] = {
0, depthStencilCI.format, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
attachmentDescription[TRANS_IMG] = {
0, transparencyCI.format, VK_SAMPLE_COUNT_1_BIT,
VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
std::vector<VkImageView> attachmentImageView;
attachmentImageView.push_back(knight::vulkan::env::GetSwapChainImageViews()[0]);
attachmentImageView.push_back(depthStencilImgView);
attachmentImageView.push_back(transparencyImgView);
std::vector<VkSubpassDescription> subpassDescription;
subpassDescription.push_back({
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
0, nullptr,
0, nullptr,
nullptr,
new VkAttachmentReference{DEPTH_STENCIL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
0, nullptr
});
subpassDescription.push_back({
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
0, nullptr,
1, new VkAttachmentReference{BACKBUFFER, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
nullptr,
new VkAttachmentReference{DEPTH_STENCIL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL},
0, nullptr
});
subpassDescription.push_back({
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
0, nullptr,
1, new VkAttachmentReference{TRANS_IMG, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
nullptr,
new VkAttachmentReference{DEPTH_STENCIL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL},
0, nullptr
});
subpassDescription.push_back({
0, VK_PIPELINE_BIND_POINT_GRAPHICS,
1, new VkAttachmentReference{TRANS_IMG, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL},
1, new VkAttachmentReference{BACKBUFFER, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
nullptr,
new VkAttachmentReference{DEPTH_STENCIL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL},
0, nullptr
});
std::vector<VkSubpassDependency> subpassDependency;
subpassDependency.push_back({
VK_SUBPASS_EXTERNAL, 0,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
});
subpassDependency.push_back({
0, 1,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
});
subpassDependency.push_back({
0, 2,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
});
subpassDependency.push_back({
1, 3,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT
});
subpassDependency.push_back({
2, 3,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT
});
VkRenderPass renderPass;
VkFramebuffer frameBuffer;
VkRenderPassCreateInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
renderPassInfo.attachmentCount = uint32_t(attachmentDescription.size());
renderPassInfo.pAttachments = attachmentDescription.data();
renderPassInfo.subpassCount = uint32_t(subpassDescription.size());
renderPassInfo.pSubpasses = subpassDescription.data();
renderPassInfo.dependencyCount = uint32_t(subpassDependency.size());
renderPassInfo.pDependencies = subpassDependency.data();
if (vkCreateRenderPass(knight::vulkan::env::Device(), &renderPassInfo, nullptr, &renderPass) == VK_SUCCESS)
{
//for (auto &imgViews : m_SwapImageViews)
{
VkFramebufferCreateInfo framebufferInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = uint32_t(attachmentImageView.size());
framebufferInfo.pAttachments = attachmentImageView.data();
framebufferInfo.width = ext.width;
framebufferInfo.height = ext.height;
framebufferInfo.layers = 1;
if (vkCreateFramebuffer(knight::vulkan::env::Device(), &framebufferInfo, nullptr, &frameBuffer) != VK_SUCCESS)
{
throw(-1);
}
}
}
else
{
throw(-1);
}
std::vector<VkCommandBuffer> primaryCommandBuffer(3);
VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
allocInfo.commandPool = knight::vulkan::env::CommandPool(knight::vulkan::env::RENDER_POOL);
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = (uint32_t)primaryCommandBuffer.size();
if (vkAllocateCommandBuffers(knight::vulkan::env::Device(), &allocInfo, primaryCommandBuffer.data()) != VK_SUCCESS) {
throw(-1);
}
VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
vkBeginCommandBuffer(primaryCommandBuffer[0], &beginInfo);
std::vector<VkClearValue> clearValue = {
{0.0f,0.0f,0.0f,0.0f},
{1.0f, 0},
{0.0f,0.0f,0.0f,0.0f}
};
VkRenderPassBeginInfo renderPassBeginInfo = {};
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.renderArea.offset = {0,0};
renderPassBeginInfo.renderArea.extent = ext;
renderPassBeginInfo.clearValueCount = uint32_t(clearValue.size());
renderPassBeginInfo.pClearValues = clearValue.data();
renderPassBeginInfo.framebuffer = frameBuffer;
vkCmdBeginRenderPass(primaryCommandBuffer[0], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
}