Skip to content

Commit

Permalink
igl | vulkan | Take care of texture dependencies
Browse files Browse the repository at this point in the history
Summary: Make sure texture dependencies are transitioned to correct image layouts.

Reviewed By: pixelperfect3

Differential Revision: D49522647

fbshipit-source-id: 7fea148b30d19c9eabc92029fc5050f8646ef46c
  • Loading branch information
corporateshark authored and facebook-github-bot committed Sep 26, 2023
1 parent f2f18b4 commit 6948072
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 9 deletions.
41 changes: 33 additions & 8 deletions src/igl/vulkan/CommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ std::unique_ptr<IComputeCommandEncoder> CommandBuffer::createComputeCommandEncod

namespace {

void transitionToColorAttachment(VkCommandBuffer buffer,
const std::shared_ptr<ITexture>& colorTex) {
void transitionToColorAttachment(VkCommandBuffer buffer, ITexture* colorTex) {
// We really shouldn't get a null here, but just in case.
if (!IGL_VERIFY(colorTex)) {
return;
Expand Down Expand Up @@ -60,6 +59,28 @@ void transitionToColorAttachment(VkCommandBuffer buffer,
VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS});
}

void transitionToShaderReadOnly(VkCommandBuffer cmdBuf, ITexture* texture) {
// We really shouldn't get a null here, but just in case.
if (!IGL_VERIFY(texture)) {
return;
}

const vulkan::Texture& tex = static_cast<vulkan::Texture&>(*texture);
const vulkan::VulkanImage& img = tex.getVulkanTexture().getVulkanImage();
// this must match the final layout of the render pass
img.imageLayout_ = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
if (img.usageFlags_ & VK_IMAGE_USAGE_SAMPLED_BIT) {
// transition sampled images to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
img.transitionLayout(
cmdBuf,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // wait for all subsequent fragment shaders
VkImageSubresourceRange{
VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS});
}
}

} // namespace

std::unique_ptr<IRenderCommandEncoder> CommandBuffer::createRenderCommandEncoder(
Expand All @@ -70,19 +91,23 @@ std::unique_ptr<IRenderCommandEncoder> CommandBuffer::createRenderCommandEncoder
IGL_PROFILER_FUNCTION();
IGL_ASSERT(framebuffer);

(void)dependencies; // will be implemented later

framebuffer_ = framebuffer;

for (ITexture* IGL_NULLABLE tex : dependencies.textures) {
if (tex) {
transitionToShaderReadOnly(wrapper_.cmdBuf_, tex);
}
}

// prepare all the color attachments
const auto& indices = framebuffer->getColorAttachmentIndices();
for (auto i : indices) {
const auto colorTex = framebuffer->getColorAttachment(i);
transitionToColorAttachment(wrapper_.cmdBuf_, colorTex);
transitionToColorAttachment(wrapper_.cmdBuf_, colorTex.get());
// handle MSAA
const auto colorResolveTex = framebuffer->getResolveColorAttachment(i);
if (colorResolveTex) {
transitionToColorAttachment(wrapper_.cmdBuf_, colorResolveTex);
transitionToColorAttachment(wrapper_.cmdBuf_, colorResolveTex.get());
}
}

Expand All @@ -102,8 +127,8 @@ std::unique_ptr<IRenderCommandEncoder> CommandBuffer::createRenderCommandEncoder
VkImageSubresourceRange{flags, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS});
}

auto encoder =
RenderCommandEncoder::create(shared_from_this(), ctx_, renderPass, framebuffer, outResult);
auto encoder = RenderCommandEncoder::create(
shared_from_this(), ctx_, renderPass, framebuffer, dependencies, outResult);

if (ctx_.enhancedShaderDebuggingStore_) {
encoder->binder().bindStorageBuffer(
Expand Down
29 changes: 28 additions & 1 deletion src/igl/vulkan/RenderCommandEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,11 @@ RenderCommandEncoder::RenderCommandEncoder(const std::shared_ptr<CommandBuffer>&

void RenderCommandEncoder::initialize(const RenderPassDesc& renderPass,
const std::shared_ptr<IFramebuffer>& framebuffer,
const Dependencies& dependencies,
Result* outResult) {
IGL_PROFILER_FUNCTION();
framebuffer_ = framebuffer;
dependencies_ = dependencies;

Result::setOk(outResult);

Expand Down Expand Up @@ -288,13 +290,14 @@ std::unique_ptr<RenderCommandEncoder> RenderCommandEncoder::create(
VulkanContext& ctx,
const RenderPassDesc& renderPass,
const std::shared_ptr<IFramebuffer>& framebuffer,
const Dependencies& dependencies,
Result* outResult) {
IGL_PROFILER_FUNCTION();

Result ret;

std::unique_ptr<RenderCommandEncoder> encoder(new RenderCommandEncoder(commandBuffer, ctx));
encoder->initialize(renderPass, framebuffer, &ret);
encoder->initialize(renderPass, framebuffer, dependencies, &ret);

Result::setResult(outResult, ret);
return ret.isOk() ? std::move(encoder) : nullptr;
Expand Down Expand Up @@ -328,11 +331,35 @@ void RenderCommandEncoder::endEncoding() {
VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS});
}
};
auto transitionToColorAttachment = [](VkCommandBuffer cmdBuf, ITexture* texture) {
if (!texture) {
return;
}
const vulkan::Texture& tex = static_cast<vulkan::Texture&>(*texture);
const vulkan::VulkanImage& img = tex.getVulkanTexture().getVulkanImage();
img.imageLayout_ = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
if (img.usageFlags_ & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
img.transitionLayout(
cmdBuf,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VkImageSubresourceRange{
VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS});
}
};

isEncoding_ = false;

ctx_.vf_.vkCmdEndRenderPass(cmdBuffer_);

for (ITexture* IGL_NULLABLE tex : dependencies_.textures) {
if (tex) {
transitionToColorAttachment(cmdBuffer_, tex);
}
}
dependencies_ = {};

// set image layouts after the render pass
const FramebufferDesc& desc = static_cast<const Framebuffer&>((*framebuffer_)).getDesc();

Expand Down
4 changes: 4 additions & 0 deletions src/igl/vulkan/RenderCommandEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class RenderCommandEncoder : public IRenderCommandEncoder {
VulkanContext& ctx,
const RenderPassDesc& renderPass,
const std::shared_ptr<IFramebuffer>& framebuffer,
const Dependencies& dependencies,
Result* outResult);

~RenderCommandEncoder() override {
Expand Down Expand Up @@ -124,7 +125,10 @@ class RenderCommandEncoder : public IRenderCommandEncoder {

void initialize(const RenderPassDesc& renderPass,
const std::shared_ptr<IFramebuffer>& framebuffer,
const Dependencies& dependencies,
Result* outResult);

Dependencies dependencies_ = {};
};

} // namespace vulkan
Expand Down

0 comments on commit 6948072

Please sign in to comment.