diff --git a/filament/backend/CMakeLists.txt b/filament/backend/CMakeLists.txt index 6f68d2802a..946b55d1c7 100644 --- a/filament/backend/CMakeLists.txt +++ b/filament/backend/CMakeLists.txt @@ -179,15 +179,12 @@ if (FILAMENT_SUPPORTS_VULKAN) src/vulkan/VulkanPipelineCache.cpp src/vulkan/VulkanPipelineCache.h src/vulkan/VulkanPlatform.cpp - src/vulkan/VulkanReadPixels.cpp - src/vulkan/VulkanReadPixels.h src/vulkan/VulkanSamplerCache.cpp src/vulkan/VulkanSamplerCache.h src/vulkan/VulkanStagePool.cpp src/vulkan/VulkanStagePool.h src/vulkan/VulkanSwapChain.cpp src/vulkan/VulkanSwapChain.h - src/vulkan/VulkanTaskHandler.h src/vulkan/VulkanTexture.cpp src/vulkan/VulkanTexture.h src/vulkan/VulkanUtility.cpp diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 0149365975..76af3124e5 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -75,8 +75,6 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, mContext.commands->setObserver(&mPipelineCache); mPipelineCache.setDevice(mContext.device, mContext.allocator); mPipelineCache.setDummyTexture(mContext.emptyTexture->getPrimaryImageView()); - - mReadPixels.initialize(mContext.device); } VulkanDriver::~VulkanDriver() noexcept = default; @@ -136,9 +134,6 @@ void VulkanDriver::terminate() { void VulkanDriver::tick(int) { mContext.commands->updateFences(); - - // Handle any posted tasks - runTaskHandler(); } // Garbage collection should not occur too frequently, only about once per frame. Internally, the @@ -1330,18 +1325,152 @@ void VulkanDriver::stopCapture(int) { } -void VulkanDriver::readPixels(Handle src, uint32_t x, uint32_t y, uint32_t width, - uint32_t height, PixelBufferDescriptor&& pbd) { +void VulkanDriver::readPixels(Handle src, uint32_t x, uint32_t y, + uint32_t width, uint32_t height, PixelBufferDescriptor&& pbd) { + const VkDevice device = mContext.device; VulkanRenderTarget* srcTarget = handle_cast(src); - mReadPixels.run( - srcTarget, x, y, width, height, mContext.graphicsQueueFamilyIndex, std::move(pbd), - getTaskHandler(), - [&context = mContext](uint32_t reqs, VkFlags flags) { - return context.selectMemoryType(reqs, flags); - }, - [this](PixelBufferDescriptor&& pbd) { - this->scheduleDestroy(std::move(pbd)); - }); + VulkanTexture* srcTexture = srcTarget->getColor(0).texture; + assert_invariant(srcTexture); + const VkFormat srcFormat = srcTexture->getVkFormat(); + const bool swizzle = srcFormat == VK_FORMAT_B8G8R8A8_UNORM; + + // Create a host visible, linearly tiled image as a staging area. + + VkImageCreateInfo imageInfo { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .format = srcFormat, + .extent = { width, height, 1 }, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_LINEAR, + .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + VkImage stagingImage; + vkCreateImage(device, &imageInfo, VKALLOC, &stagingImage); + + VkMemoryRequirements memReqs; + VkDeviceMemory stagingMemory; + vkGetImageMemoryRequirements(device, stagingImage, &memReqs); + VkMemoryAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = memReqs.size, + .memoryTypeIndex = mContext.selectMemoryType(memReqs.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT) + }; + + vkAllocateMemory(device, &allocInfo, nullptr, &stagingMemory); + vkBindImageMemory(device, stagingImage, stagingMemory, 0); + + // TODO: don't flush/wait here, this should be asynchronous + + mContext.commands->flush(); + mContext.commands->wait(); + + // Transition the staging image layout. + + const VkCommandBuffer cmdbuffer = mContext.commands->get().cmdbuffer; + + transitionImageLayout(cmdbuffer, { + .image = stagingImage, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .subresources = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + .srcAccessMask = 0, + .dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + }); + + const VulkanAttachment srcAttachment = srcTarget->getColor(0); + + VkImageCopy imageCopyRegion = { + .srcSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = srcAttachment.level, + .baseArrayLayer = srcAttachment.layer, + .layerCount = 1, + }, + .srcOffset = { + .x = (int32_t) x, + .y = (int32_t) (srcTarget->getExtent().height - (height + y)), + }, + .dstSubresource = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .layerCount = 1, + }, + .extent = { + .width = width, + .height = height, + .depth = 1, + }, + }; + + // Transition the source image layout (which might be the swap chain) + + const VkImageSubresourceRange srcRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = srcAttachment.level, + .levelCount = 1, + .baseArrayLayer = srcAttachment.layer, + .layerCount = 1, + }; + + srcTexture->transitionLayout(cmdbuffer, srcRange, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + // Perform the copy into the staging area. At this point we know that the src layout is + // TRANSFER_SRC_OPTIMAL and the staging area is GENERAL. + + UTILS_UNUSED_IN_RELEASE VkExtent2D srcExtent = srcAttachment.getExtent2D(); + assert_invariant(imageCopyRegion.srcOffset.x + imageCopyRegion.extent.width <= srcExtent.width); + assert_invariant(imageCopyRegion.srcOffset.y + imageCopyRegion.extent.height <= srcExtent.height); + + vkCmdCopyImage(cmdbuffer, srcAttachment.getImage(), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingImage, VK_IMAGE_LAYOUT_GENERAL, + 1, &imageCopyRegion); + + // Restore the source image layout. Between driver API calls, color images are always kept in + // UNDEFINED layout or in their "usage default" layout (see comment for getDefaultImageLayout). + + srcTexture->transitionLayout(cmdbuffer, srcRange, + getDefaultImageLayout(TextureUsage::COLOR_ATTACHMENT)); + + // TODO: don't flush/wait here -- we should do this asynchronously + + // Flush and wait. + mContext.commands->flush(); + mContext.commands->wait(); + + VkImageSubresource subResource { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT }; + VkSubresourceLayout subResourceLayout; + vkGetImageSubresourceLayout(device, stagingImage, &subResource, &subResourceLayout); + + // Map image memory so we can start copying from it. + + const uint8_t* srcPixels; + vkMapMemory(device, stagingMemory, 0, VK_WHOLE_SIZE, 0, (void**) &srcPixels); + srcPixels += subResourceLayout.offset; + + if (!DataReshaper::reshapeImage(&pbd, getComponentType(srcFormat), getComponentCount(srcFormat), + srcPixels, subResourceLayout.rowPitch, width, height, swizzle)) { + utils::slog.e << "Unsupported PixelDataFormat or PixelDataType" << utils::io::endl; + } + + vkUnmapMemory(device, stagingMemory); + vkDestroyImage(device, stagingImage, nullptr); + vkFreeMemory(device, stagingMemory, nullptr); + + scheduleDestroy(std::move(pbd)); } void VulkanDriver::readBufferSubData(backend::BufferObjectHandle boh, diff --git a/filament/backend/src/vulkan/VulkanDriver.h b/filament/backend/src/vulkan/VulkanDriver.h index 793f08bd9f..e403d0926f 100644 --- a/filament/backend/src/vulkan/VulkanDriver.h +++ b/filament/backend/src/vulkan/VulkanDriver.h @@ -23,10 +23,8 @@ #include "VulkanConstants.h" #include "VulkanContext.h" #include "VulkanFboCache.h" -#include "VulkanReadPixels.h" #include "VulkanSamplerCache.h" #include "VulkanStagePool.h" -#include "VulkanTaskHandler.h" #include "VulkanUtility.h" #include "private/backend/Driver.h" @@ -41,14 +39,11 @@ namespace filament::backend { class VulkanPlatform; struct VulkanSamplerGroup; -class VulkanDriver final : public DriverBase, private VulkanTaskHandler::Host { +class VulkanDriver final : public DriverBase { public: static Driver* create(VulkanPlatform* platform, const char* const* ppEnabledExtensions, uint32_t enabledExtensionCount, const Platform::DriverConfig& driverConfig) noexcept; - VulkanDriver(VulkanDriver const&) = delete; - VulkanDriver& operator = (VulkanDriver const&) = delete; - private: void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override; @@ -78,6 +73,9 @@ private: #include "private/backend/DriverAPI.inc" + VulkanDriver(VulkanDriver const&) = delete; + VulkanDriver& operator = (VulkanDriver const&) = delete; + private: HandleAllocatorVK mHandleAllocator; @@ -153,7 +151,6 @@ private: VulkanSamplerCache mSamplerCache; VulkanBlitter mBlitter; VulkanSamplerGroup* mSamplerBindings[VulkanPipelineCache::SAMPLER_BINDING_COUNT] = {}; - VulkanReadPixels mReadPixels; }; } // namespace filament::backend diff --git a/filament/backend/src/vulkan/VulkanReadPixels.cpp b/filament/backend/src/vulkan/VulkanReadPixels.cpp deleted file mode 100644 index fb1388a8f6..0000000000 --- a/filament/backend/src/vulkan/VulkanReadPixels.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "VulkanReadPixels.h" - -#include "DataReshaper.h" -#include "VulkanHandles.h" -#include "VulkanTaskHandler.h" -#include "VulkanTexture.h" - -#include - -using namespace bluevk; - -namespace filament::backend { - -VulkanReadPixels::~VulkanReadPixels() noexcept { - assert_invariant(mDevice != VK_NULL_HANDLE); - if (mCommandPool == VK_NULL_HANDLE) { - return; - } - vkDestroyCommandPool(mDevice, mCommandPool, VKALLOC); -} - -void VulkanReadPixels::initialize(VkDevice device) { - mDevice = device; -} - -void VulkanReadPixels::run(VulkanRenderTarget const* srcTarget, uint32_t const x, uint32_t const y, - uint32_t const width, uint32_t const height, uint32_t const graphicsQueueFamilyIndex, - PixelBufferDescriptor&& pbd, VulkanTaskHandler& taskHandler, - SelecteMemoryFunction const& selectMemoryFunc, - OnReadCompleteFunction const& readCompleteFunc) { - assert_invariant(mDevice != VK_NULL_HANDLE); - - VkDevice device = mDevice; - - if (mCommandPool == VK_NULL_HANDLE) { - // Create a command pool if one has not been created. - VkCommandPoolCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT - | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - .queueFamilyIndex = graphicsQueueFamilyIndex, - }; - vkCreateCommandPool(device, &createInfo, VKALLOC, &mCommandPool); - } - VkCommandPool cmdpool = mCommandPool; - - VulkanTexture* srcTexture = srcTarget->getColor(0).texture; - assert_invariant(srcTexture); - VkFormat const srcFormat = srcTexture->getVkFormat(); - bool const swizzle - = srcFormat == VK_FORMAT_B8G8R8A8_UNORM || srcFormat == VK_FORMAT_B8G8R8A8_SRGB; - - // Create a host visible, linearly tiled image as a staging area. - VkImageCreateInfo const imageInfo{ - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .format = srcFormat, - .extent = {width, height, 1}, - .mipLevels = 1, - .arrayLayers = 1, - .samples = VK_SAMPLE_COUNT_1_BIT, - .tiling = VK_IMAGE_TILING_LINEAR, - .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - VkImage stagingImage; - vkCreateImage(device, &imageInfo, VKALLOC, &stagingImage); - - VkMemoryRequirements memReqs; - VkDeviceMemory stagingMemory; - vkGetImageMemoryRequirements(device, stagingImage, &memReqs); - VkMemoryAllocateInfo const allocInfo = {.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = memReqs.size, - .memoryTypeIndex = selectMemoryFunc(memReqs.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - | VK_MEMORY_PROPERTY_HOST_CACHED_BIT)}; - - vkAllocateMemory(device, &allocInfo, VKALLOC, &stagingMemory); - vkBindImageMemory(device, stagingImage, stagingMemory, 0); - - VkCommandBuffer cmdbuffer; - VkCommandBufferAllocateInfo const allocateInfo{ - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .commandPool = cmdpool, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = 1, - }; - vkAllocateCommandBuffers(device, &allocateInfo, &cmdbuffer); - - VkCommandBufferBeginInfo const binfo{ - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, - }; - vkBeginCommandBuffer(cmdbuffer, &binfo); - - transitionImageLayout(cmdbuffer, { - .image = stagingImage, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .subresources = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - .srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - .srcAccessMask = 0, - .dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - }); - - VulkanAttachment const srcAttachment = srcTarget->getColor(0); - - VkImageCopy const imageCopyRegion = { - .srcSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .mipLevel = srcAttachment.level, - .baseArrayLayer = srcAttachment.layer, - .layerCount = 1, - }, - .srcOffset = { - .x = (int32_t) x, - .y = (int32_t) (srcTarget->getExtent().height - (height + y)), - }, - .dstSubresource = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .layerCount = 1, - }, - .extent = { - .width = width, - .height = height, - .depth = 1, - }, - }; - - // Transition the source image layout (which might be the swap chain) - VkImageSubresourceRange const srcRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = srcAttachment.level, - .levelCount = 1, - .baseArrayLayer = srcAttachment.layer, - .layerCount = 1, - }; - - srcTexture->transitionLayout(cmdbuffer, srcRange, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); - - // Perform the copy into the staging area. At this point we know that the src layout is - // TRANSFER_SRC_OPTIMAL and the staging area is GENERAL. - UTILS_UNUSED_IN_RELEASE VkExtent2D srcExtent = srcAttachment.getExtent2D(); - assert_invariant(imageCopyRegion.srcOffset.x + imageCopyRegion.extent.width <= srcExtent.width); - assert_invariant( - imageCopyRegion.srcOffset.y + imageCopyRegion.extent.height <= srcExtent.height); - - vkCmdCopyImage(cmdbuffer, srcAttachment.getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - stagingImage, VK_IMAGE_LAYOUT_GENERAL, 1, &imageCopyRegion); - - // Restore the source image layout. Between driver API calls, color images are always kept in - // UNDEFINED layout or in their "usage default" layout (see comment for getDefaultImageLayout). - srcTexture->transitionLayout(cmdbuffer, srcRange, - getDefaultImageLayout(TextureUsage::COLOR_ATTACHMENT)); - - vkEndCommandBuffer(cmdbuffer); - - VkQueue queue; - vkGetDeviceQueue(device, graphicsQueueFamilyIndex, 0, &queue); - - VkSubmitInfo const submitInfo{ - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .waitSemaphoreCount = 0, - .pWaitSemaphores = VK_NULL_HANDLE, - .pWaitDstStageMask = VK_NULL_HANDLE, - .commandBufferCount = 1, - .pCommandBuffers = &cmdbuffer, - .signalSemaphoreCount = 0, - .pSignalSemaphores = VK_NULL_HANDLE, - }; - VkFence fence; - VkFenceCreateInfo const fenceCreateInfo{ - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - }; - vkCreateFence(device, &fenceCreateInfo, VKALLOC, &fence); - vkQueueSubmit(queue, 1, &submitInfo, fence); - - auto* const pUserBuffer = new PixelBufferDescriptor(std::move(pbd)); - auto const waitTaskId = taskHandler.createTask( - [device, width, height, swizzle, srcFormat, fence, stagingImage, stagingMemory, cmdpool, - cmdbuffer, pUserBuffer, readCompleteFunc, - &taskHandler](VulkanTaskHandler::TaskId taskId, void* data) mutable { - PixelBufferDescriptor& p = *pUserBuffer; - vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); - VkResult status = vkGetFenceStatus(device, fence); - - // Fence hasn't been reached. Try waiting again. - if (status == VK_NOT_READY) { - taskHandler.post(taskId); - return; - } - - // Need to abort the readPixels if the device is lost. - if (status == VK_ERROR_DEVICE_LOST) { - utils::slog.e << "Device lost while in VulkanReadPixels::run" - << utils::io::endl; - taskHandler.completed(taskId); - - // Try to free the pbd anyway - readCompleteFunc(std::move(p)); - delete pUserBuffer; - return; - } - - VkImageSubresource subResource{.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT}; - VkSubresourceLayout subResourceLayout; - vkGetImageSubresourceLayout(device, stagingImage, &subResource, &subResourceLayout); - - // Map image memory so that we can start copying from it. - uint8_t const* srcPixels; - vkMapMemory(device, stagingMemory, 0, VK_WHOLE_SIZE, 0, (void**) &srcPixels); - srcPixels += subResourceLayout.offset; - - if (!DataReshaper::reshapeImage(&p, getComponentType(srcFormat), - getComponentCount(srcFormat), srcPixels, - static_cast(subResourceLayout.rowPitch), static_cast(width), - static_cast(height), swizzle)) { - utils::slog.e << "Unsupported PixelDataFormat or PixelDataType" - << utils::io::endl; - } - - vkUnmapMemory(device, stagingMemory); - vkDestroyImage(device, stagingImage, VKALLOC); - vkFreeMemory(device, stagingMemory, VKALLOC); - vkDestroyFence(device, fence, VKALLOC); - vkFreeCommandBuffers(device, cmdpool, 1, &cmdbuffer); - readCompleteFunc(std::move(p)); - delete pUserBuffer; - - taskHandler.completed(taskId); - }, - nullptr); - - taskHandler.post(waitTaskId); -} - -}// namespace filament::backend diff --git a/filament/backend/src/vulkan/VulkanReadPixels.h b/filament/backend/src/vulkan/VulkanReadPixels.h deleted file mode 100644 index a402e7eab0..0000000000 --- a/filament/backend/src/vulkan/VulkanReadPixels.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TNT_FILAMENT_BACKEND_VULKANREADPIXELS_H -#define TNT_FILAMENT_BACKEND_VULKANREADPIXELS_H - -#include "VulkanTaskHandler.h" -#include "private/backend/Driver.h" - -#include -#include - -namespace filament::backend { - -struct VulkanContext; -struct VulkanRenderTarget; - -class VulkanReadPixels { -public: - using OnReadCompleteFunction = std::function; - using SelecteMemoryFunction = std::function; - - ~VulkanReadPixels() noexcept; - - void initialize(VkDevice device); - - void run(VulkanRenderTarget const* srcTarget, uint32_t x, uint32_t y, uint32_t width, - uint32_t height, uint32_t graphicsQueueFamilyIndex, PixelBufferDescriptor&& pbd, - VulkanTaskHandler& taskHandler, SelecteMemoryFunction const& selectMemoryFunc, - OnReadCompleteFunction const& readCompleteFunc); - -private: - VkDevice mDevice = VK_NULL_HANDLE; - VkCommandPool mCommandPool = VK_NULL_HANDLE; -}; - -}// namespace filament::backend - -#endif//TNT_FILAMENT_BACKEND_VULKANREADPIXELS_H diff --git a/filament/backend/src/vulkan/VulkanTaskHandler.h b/filament/backend/src/vulkan/VulkanTaskHandler.h deleted file mode 100644 index 65004652ea..0000000000 --- a/filament/backend/src/vulkan/VulkanTaskHandler.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TNT_FILAMENT_BACKEND_VULKANTASKHANDLER_H -#define TNT_FILAMENT_BACKEND_VULKANTASKHANDLER_H - -#include "utils/Panic.h" - -#include -#include -#include -#include - -namespace filament::backend { - -class VulkanTaskHandler { -public: - // The Host class is meant to be called on the thread that processes the tasks. It has access to - // the handle function. - class Host { - public: - Host(Host const&) = delete; - Host& operator=(Host const&) = delete; - protected: - Host() - : mHandler(std::make_unique()) {} - - void runTaskHandler() noexcept { - mHandler->handle(); - } - - VulkanTaskHandler& getTaskHandler() noexcept { - return *mHandler; - } - private: - std::unique_ptr mHandler; - }; - - using TaskId = uint32_t; - using TaskFunc = std::function; - using Task = std::pair; - - TaskId createTask(TaskFunc const& func, void* data) noexcept { - TaskId const id = mNextTaskId++; - mTasks[id] = std::pair(func, data); - return id; - } - - // Task that will never be put on the queue again should be marked as completed by calling this - // function. - void completed(TaskId taskId) noexcept { - assert_invariant(mTasks.find(taskId) != mTasks.end()); - mTasks.erase(taskId); - } - - void post(TaskId taskId) noexcept { - assert_invariant(mTasks.find(taskId) != mTasks.end()); - mTaskQueue.push(taskId); - } - - VulkanTaskHandler() = default; - - VulkanTaskHandler(VulkanTaskHandler const&) = delete; - VulkanTaskHandler& operator=(VulkanTaskHandler const&) = delete; - -private: - inline void handle() { - while (!mTaskQueue.empty()) { - auto taskId = mTaskQueue.front(); - mTaskQueue.pop(); - // It is possible for taskIds in the queue to refer to a task that has already been - // completed. Just ignore. - if (mTasks.find(taskId) == mTasks.end()) { - continue; - } - - auto& [func, data] = mTasks[taskId]; - func(taskId, data); - } - } - - std::queue mTaskQueue; - std::map mTasks; - uint32_t mNextTaskId = 0; - - friend class Host; -}; - -}// namespace filament::backend - -#endif// TNT_FILAMENT_BACKEND_VULKANTASKHANDLER_H