From f2f18b4c1b0b0f36cc80165405d1baa2263631a1 Mon Sep 17 00:00:00 2001 From: Sergey Kosarevsky Date: Sun, 24 Sep 2023 20:58:39 -0700 Subject: [PATCH] igl | Initial interface for texture dependencies Summary: Implemented initial interface for texture dependencies. This is necessary to ensure automatic layout conversions and barriers for external textures. Reviewed By: pixelperfect3 Differential Revision: D49475720 fbshipit-source-id: 9250ee723db893205758f2cbd5d6717a4164d5fd --- IGLU/sentinel/CommandBuffer.cpp | 1 + IGLU/sentinel/CommandBuffer.h | 1 + IGLU/simple_renderer/ForwardRenderPass.cpp | 3 ++- src/igl/CommandBuffer.h | 12 +++++++++++- src/igl/metal/CommandBuffer.h | 1 + src/igl/metal/CommandBuffer.mm | 1 + src/igl/opengl/CommandBuffer.cpp | 4 +++- src/igl/opengl/CommandBuffer.h | 1 + src/igl/opengl/RenderCommandEncoder.cpp | 3 +++ src/igl/opengl/RenderCommandEncoder.h | 2 ++ src/igl/vulkan/CommandBuffer.cpp | 3 +++ src/igl/vulkan/CommandBuffer.h | 1 + 12 files changed, 30 insertions(+), 3 deletions(-) diff --git a/IGLU/sentinel/CommandBuffer.cpp b/IGLU/sentinel/CommandBuffer.cpp index 6b91ae4adc..5d9fb75bf8 100644 --- a/IGLU/sentinel/CommandBuffer.cpp +++ b/IGLU/sentinel/CommandBuffer.cpp @@ -17,6 +17,7 @@ CommandBuffer::CommandBuffer(bool shouldAssert) : shouldAssert_(shouldAssert) {} std::unique_ptr CommandBuffer::createRenderCommandEncoder( const igl::RenderPassDesc& /*renderPass*/, std::shared_ptr /*framebuffer*/, + const igl::Dependencies& /*dependencies*/, igl::Result* IGL_NULLABLE /*outResult*/) { IGLU_SENTINEL_ASSERT_IF_NOT(shouldAssert_); return nullptr; diff --git a/IGLU/sentinel/CommandBuffer.h b/IGLU/sentinel/CommandBuffer.h index 2de428db9a..099c5f9beb 100644 --- a/IGLU/sentinel/CommandBuffer.h +++ b/IGLU/sentinel/CommandBuffer.h @@ -25,6 +25,7 @@ class CommandBuffer final : public igl::ICommandBuffer { [[nodiscard]] std::unique_ptr createRenderCommandEncoder( const igl::RenderPassDesc& /*renderPass*/, std::shared_ptr /*framebuffer*/, + const igl::Dependencies& /*dependencies*/, igl::Result* IGL_NULLABLE /*outResult*/) final; [[nodiscard]] std::unique_ptr createComputeCommandEncoder() final; void present(std::shared_ptr /*surface*/) const final; diff --git a/IGLU/simple_renderer/ForwardRenderPass.cpp b/IGLU/simple_renderer/ForwardRenderPass.cpp index c966785a19..001ee3fa1e 100644 --- a/IGLU/simple_renderer/ForwardRenderPass.cpp +++ b/IGLU/simple_renderer/ForwardRenderPass.cpp @@ -42,7 +42,8 @@ void ForwardRenderPass::begin(std::shared_ptr target, igl::CommandBufferDesc cbDesc; _commandBuffer = _commandQueue->createCommandBuffer(cbDesc, nullptr); - _commandEncoder = _commandBuffer->createRenderCommandEncoder(*finalDesc, _framebuffer); + _commandEncoder = + _commandBuffer->createRenderCommandEncoder(*finalDesc, _framebuffer, {}, nullptr); } void ForwardRenderPass::draw(drawable::Drawable& drawable, igl::IDevice& device) const { diff --git a/src/igl/CommandBuffer.h b/src/igl/CommandBuffer.h index f4953245c3..412094ea9f 100644 --- a/src/igl/CommandBuffer.h +++ b/src/igl/CommandBuffer.h @@ -34,6 +34,15 @@ struct CommandBufferStatistics { uint32_t currentDrawCount = 0; }; +/** + * Dependencies are used to issue proper memory barriers for external resources, such as textures + * modified by non-IGL code (Skia, Qt, etc), and synchronize between graphics and compute pipelines. + */ +struct Dependencies { + static constexpr uint32_t IGL_MAX_TEXTURE_DEPENDENCIES = 4; + ITexture* IGL_NULLABLE textures[IGL_MAX_TEXTURE_DEPENDENCIES] = {}; +}; + /** * @brief ICommandBuffer represents an object which accepts and stores commands to be executed on * the GPU. @@ -61,13 +70,14 @@ class ICommandBuffer { virtual std::unique_ptr createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* IGL_NULLABLE outResult) = 0; // Use an overload here instead of a default parameter in a pure virtual function. std::unique_ptr createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer) { - return createRenderCommandEncoder(renderPass, std::move(framebuffer), nullptr); + return createRenderCommandEncoder(renderPass, std::move(framebuffer), Dependencies{}, nullptr); } /** diff --git a/src/igl/metal/CommandBuffer.h b/src/igl/metal/CommandBuffer.h index 790b14fe46..79e0913bde 100644 --- a/src/igl/metal/CommandBuffer.h +++ b/src/igl/metal/CommandBuffer.h @@ -24,6 +24,7 @@ class CommandBuffer final : public ICommandBuffer, std::unique_ptr createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* outResult) override; void present(std::shared_ptr surface) const override; diff --git a/src/igl/metal/CommandBuffer.mm b/src/igl/metal/CommandBuffer.mm index f54733b26d..d8a64cc092 100644 --- a/src/igl/metal/CommandBuffer.mm +++ b/src/igl/metal/CommandBuffer.mm @@ -26,6 +26,7 @@ std::unique_ptr CommandBuffer::createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& /*dependencies*/, Result* outResult) { return RenderCommandEncoder::create(shared_from_this(), renderPass, framebuffer, outResult); } diff --git a/src/igl/opengl/CommandBuffer.cpp b/src/igl/opengl/CommandBuffer.cpp index 66a8d52906..6c8c47aa96 100644 --- a/src/igl/opengl/CommandBuffer.cpp +++ b/src/igl/opengl/CommandBuffer.cpp @@ -22,8 +22,10 @@ CommandBuffer::~CommandBuffer() = default; std::unique_ptr CommandBuffer::createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* outResult) { - return RenderCommandEncoder::create(shared_from_this(), renderPass, framebuffer, outResult); + return RenderCommandEncoder::create( + shared_from_this(), renderPass, framebuffer, dependencies, outResult); } std::unique_ptr CommandBuffer::createComputeCommandEncoder() { diff --git a/src/igl/opengl/CommandBuffer.h b/src/igl/opengl/CommandBuffer.h index 6ab97c715b..8c76136230 100644 --- a/src/igl/opengl/CommandBuffer.h +++ b/src/igl/opengl/CommandBuffer.h @@ -26,6 +26,7 @@ class CommandBuffer final : public ICommandBuffer, std::unique_ptr createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* outResult) override; std::unique_ptr createComputeCommandEncoder() override; diff --git a/src/igl/opengl/RenderCommandEncoder.cpp b/src/igl/opengl/RenderCommandEncoder.cpp index f8b94622c0..ec31af9a9a 100644 --- a/src/igl/opengl/RenderCommandEncoder.cpp +++ b/src/igl/opengl/RenderCommandEncoder.cpp @@ -31,7 +31,10 @@ std::unique_ptr RenderCommandEncoder::create( const std::shared_ptr& commandBuffer, const RenderPassDesc& renderPass, const std::shared_ptr& framebuffer, + const Dependencies& dependencies, Result* outResult) { + (void)dependencies; // not used in OpenGL + if (!commandBuffer) { Result::setResult(outResult, Result::Code::ArgumentNull, "commandBuffer was null"); return {}; diff --git a/src/igl/opengl/RenderCommandEncoder.h b/src/igl/opengl/RenderCommandEncoder.h index 54b6317f8f..a9c67cd4c0 100644 --- a/src/igl/opengl/RenderCommandEncoder.h +++ b/src/igl/opengl/RenderCommandEncoder.h @@ -19,6 +19,7 @@ class IDepthStencilState; class IRenderPipelineState; class ISamplerState; class ITexture; +struct Dependencies; namespace opengl { class RenderCommandAdapter; @@ -30,6 +31,7 @@ class RenderCommandEncoder final : public IRenderCommandEncoder, public WithCont const std::shared_ptr& commandBuffer, const RenderPassDesc& renderPass, const std::shared_ptr& framebuffer, + const Dependencies& dependencies, Result* outResult); ~RenderCommandEncoder() override; diff --git a/src/igl/vulkan/CommandBuffer.cpp b/src/igl/vulkan/CommandBuffer.cpp index 8b9278f814..7dd3065ce8 100644 --- a/src/igl/vulkan/CommandBuffer.cpp +++ b/src/igl/vulkan/CommandBuffer.cpp @@ -65,10 +65,13 @@ void transitionToColorAttachment(VkCommandBuffer buffer, std::unique_ptr CommandBuffer::createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* outResult) { IGL_PROFILER_FUNCTION(); IGL_ASSERT(framebuffer); + (void)dependencies; // will be implemented later + framebuffer_ = framebuffer; // prepare all the color attachments diff --git a/src/igl/vulkan/CommandBuffer.h b/src/igl/vulkan/CommandBuffer.h index 4a2d7bb742..29502bf842 100644 --- a/src/igl/vulkan/CommandBuffer.h +++ b/src/igl/vulkan/CommandBuffer.h @@ -27,6 +27,7 @@ class CommandBuffer final : public ICommandBuffer, virtual std::unique_ptr createRenderCommandEncoder( const RenderPassDesc& renderPass, std::shared_ptr framebuffer, + const Dependencies& dependencies, Result* outResult) override; void present(std::shared_ptr surface) const override;