diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index 23e80821fb9..e3bbe4231e6 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -16,7 +16,9 @@ #include "VulkanBlitter.h" #include "VulkanContext.h" +#include "VulkanFboCache.h" #include "VulkanHandles.h" +#include "VulkanSamplerCache.h" #include #include diff --git a/filament/backend/src/vulkan/VulkanCommands.cpp b/filament/backend/src/vulkan/VulkanCommands.cpp index 324de0ae0d5..70cad45185a 100644 --- a/filament/backend/src/vulkan/VulkanCommands.cpp +++ b/filament/backend/src/vulkan/VulkanCommands.cpp @@ -23,7 +23,6 @@ #include "VulkanConstants.h" #include "VulkanContext.h" -#include "VulkanDriver.h" #include #include diff --git a/filament/backend/src/vulkan/VulkanCommands.h b/filament/backend/src/vulkan/VulkanCommands.h index 811796c31da..4461f7fbe9f 100644 --- a/filament/backend/src/vulkan/VulkanCommands.h +++ b/filament/backend/src/vulkan/VulkanCommands.h @@ -19,6 +19,8 @@ #include +#include "DriverBase.h" + #include "VulkanConstants.h" #include diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 14215434975..f506ae59be6 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -148,7 +148,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext const& contex mAllocator(createAllocator(mPlatform->getInstance(), mPlatform->getPhysicalDevice(), mPlatform->getDevice())), mContext(context), - mHandleAllocator("Handles", driverConfig.handleArenaSize), + mHandleAllocator(driverConfig.handleArenaSize), mBlitter(mStagePool, mPipelineCache, mFramebufferCache, mSamplerCache), mReadPixels(mPlatform->getDevice()) { @@ -300,36 +300,36 @@ void VulkanDriver::finish(int dummy) { } void VulkanDriver::createSamplerGroupR(Handle sbh, uint32_t count) { - construct(sbh, count); + mHandleAllocator.construct(sbh, count); } void VulkanDriver::createRenderPrimitiveR(Handle rph, Handle vbh, Handle ibh, PrimitiveType pt, uint32_t offset, uint32_t minIndex, uint32_t maxIndex, uint32_t count) { - construct(rph); + mHandleAllocator.construct(rph); VulkanDriver::setRenderPrimitiveBuffer(rph, vbh, ibh); VulkanDriver::setRenderPrimitiveRange(rph, pt, offset, minIndex, maxIndex, count); } void VulkanDriver::destroyRenderPrimitive(Handle rph) { if (rph) { - destruct(rph); + mHandleAllocator.destruct(rph); } } void VulkanDriver::createVertexBufferR(Handle vbh, uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount, AttributeArray attributes) { - auto vertexBuffer = construct(vbh, mContext, mStagePool, + auto vertexBuffer = mHandleAllocator.construct(vbh, mContext, mStagePool, bufferCount, attributeCount, elementCount, attributes); - mDisposer.createDisposable(vertexBuffer, [this, vbh] () { - destruct(vbh); + mDisposer.createDisposable(vertexBuffer, [this, vbh]() { + mHandleAllocator.destruct(vbh); }); } void VulkanDriver::destroyVertexBuffer(Handle vbh) { if (vbh) { - auto vertexBuffer = handle_cast(vbh); + auto vertexBuffer = mHandleAllocator.handle_cast(vbh); mDisposer.removeReference(vertexBuffer); } } @@ -337,30 +337,30 @@ void VulkanDriver::destroyVertexBuffer(Handle vbh) { void VulkanDriver::createIndexBufferR(Handle ibh, ElementType elementType, uint32_t indexCount, BufferUsage usage) { auto elementSize = (uint8_t) getElementTypeSize(elementType); - auto indexBuffer = construct(ibh, mAllocator, mCommands.get(), mStagePool, - elementSize, indexCount); + auto indexBuffer = mHandleAllocator.construct(ibh, mAllocator, + mCommands.get(), mStagePool, elementSize, indexCount); mDisposer.createDisposable(indexBuffer, - [this, ibh]() { destructBuffer(ibh); }); + [this, ibh]() { mHandleAllocator.destruct(ibh); }); } void VulkanDriver::destroyIndexBuffer(Handle ibh) { if (ibh) { - auto indexBuffer = handle_cast(ibh); + auto indexBuffer = mHandleAllocator.handle_cast(ibh); mDisposer.removeReference(indexBuffer); } } void VulkanDriver::createBufferObjectR(Handle boh, uint32_t byteCount, BufferObjectBinding bindingType, BufferUsage usage) { - auto bufferObject = construct(boh, mAllocator, mCommands.get(), mStagePool, - byteCount, bindingType, usage); + auto bufferObject = mHandleAllocator.construct(boh, mAllocator, + mCommands.get(), mStagePool, byteCount, bindingType, usage); mDisposer.createDisposable(bufferObject, - [this, boh]() { destructBuffer(boh); }); + [this, boh]() { mHandleAllocator.destruct(boh); }); } void VulkanDriver::destroyBufferObject(Handle boh) { if (boh) { - auto bufferObject = handle_cast(boh); + auto bufferObject = mHandleAllocator.handle_cast(boh); if (bufferObject->bindingType == BufferObjectBinding::UNIFORM) { mPipelineCache.unbindUniformBuffer(bufferObject->buffer.getGpuBuffer()); // Decrement the refcount of the uniform buffer, but schedule it for destruction a few @@ -375,10 +375,11 @@ void VulkanDriver::destroyBufferObject(Handle boh) { void VulkanDriver::createTextureR(Handle th, SamplerType target, uint8_t levels, TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth, TextureUsage usage) { - auto vktexture = construct(th, mPlatform->getDevice(), + auto vktexture = mHandleAllocator.construct(th, mPlatform->getDevice(), mPlatform->getPhysicalDevice(), mContext, mAllocator, mCommands.get(), target, levels, format, samples, w, h, depth, usage, mStagePool); - mDisposer.createDisposable(vktexture, [this, th]() { destruct(th); }); + mDisposer.createDisposable(vktexture, + [this, th]() { mHandleAllocator.destruct(th); }); } void VulkanDriver::createTextureSwizzledR(Handle th, SamplerType target, uint8_t levels, @@ -387,11 +388,11 @@ void VulkanDriver::createTextureSwizzledR(Handle th, SamplerType targ TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) { TextureSwizzle swizzleArray[] = {r, g, b, a}; const VkComponentMapping swizzleMap = getSwizzleMap(swizzleArray); - auto vktexture = construct(th, mPlatform->getDevice(), + auto vktexture = mHandleAllocator.construct(th, mPlatform->getDevice(), mPlatform->getPhysicalDevice(), mContext, mAllocator, mCommands.get(), target, levels, format, samples, w, h, depth, usage, mStagePool, swizzleMap); mDisposer.createDisposable(vktexture, [this, th]() { - destruct(th); + mHandleAllocator.destruct(th); }); } @@ -404,31 +405,31 @@ void VulkanDriver::importTextureR(Handle th, intptr_t id, void VulkanDriver::destroyTexture(Handle th) { if (th) { - auto texture = handle_cast(th); + auto texture = mHandleAllocator.handle_cast(th); mPipelineCache.unbindImageView(texture->getPrimaryImageView()); mDisposer.removeReference(texture); } } void VulkanDriver::createProgramR(Handle ph, Program&& program) { - auto vkprogram = construct(ph, mPlatform->getDevice(), program); + auto vkprogram = mHandleAllocator.construct(ph, mPlatform->getDevice(), program); mDisposer.createDisposable(vkprogram, [this, ph] () { - destruct(ph); + mHandleAllocator.destruct(ph); }); } void VulkanDriver::destroyProgram(Handle ph) { if (ph) { - mDisposer.removeReference(handle_cast(ph)); + mDisposer.removeReference(mHandleAllocator.handle_cast(ph)); } } void VulkanDriver::createDefaultRenderTargetR(Handle rth, int) { assert_invariant(mDefaultRenderTarget == nullptr); - VulkanRenderTarget* renderTarget = construct(rth); + VulkanRenderTarget* renderTarget = mHandleAllocator.construct(rth); mDefaultRenderTarget = renderTarget; mDisposer.createDisposable(renderTarget, [this, rth] () { - destruct(rth); + mHandleAllocator.destruct(rth); }); } @@ -443,7 +444,7 @@ void VulkanDriver::createRenderTargetR(Handle rth, for (int i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) { if (color[i].handle) { colorTargets[i] = { - .texture = handle_cast(color[i].handle), + .texture = mHandleAllocator.handle_cast(color[i].handle), .level = color[i].level, .layer = color[i].layer, }; @@ -457,7 +458,7 @@ void VulkanDriver::createRenderTargetR(Handle rth, VulkanAttachment depthStencil[2] = {}; if (depth.handle) { depthStencil[0] = { - .texture = handle_cast(depth.handle), + .texture = mHandleAllocator.handle_cast(depth.handle), .level = depth.level, .layer = depth.layer, }; @@ -469,7 +470,7 @@ void VulkanDriver::createRenderTargetR(Handle rth, if (stencil.handle) { depthStencil[1] = { - .texture = handle_cast(stencil.handle), + .texture = mHandleAllocator.handle_cast(stencil.handle), .level = stencil.level, .layer = stencil.layer, }; @@ -485,15 +486,16 @@ void VulkanDriver::createRenderTargetR(Handle rth, assert_invariant(tmin == tmax); assert_invariant(tmin.x >= width && tmin.y >= height); - auto renderTarget = construct(rth, mPlatform->getDevice(), + auto renderTarget = mHandleAllocator.construct(rth, mPlatform->getDevice(), mPlatform->getPhysicalDevice(), mContext, mAllocator, mCommands.get(), width, height, samples, colorTargets, depthStencil, mStagePool); - mDisposer.createDisposable(renderTarget, [this, rth]() { destruct(rth); }); + mDisposer.createDisposable(renderTarget, + [this, rth]() { mHandleAllocator.destruct(rth); }); } void VulkanDriver::destroyRenderTarget(Handle rth) { if (rth) { - VulkanRenderTarget* rt = handle_cast(rth); + VulkanRenderTarget* rt = mHandleAllocator.handle_cast(rth); if (UTILS_UNLIKELY(rt == mDefaultRenderTarget)) { mDefaultRenderTarget = nullptr; } @@ -503,18 +505,17 @@ void VulkanDriver::destroyRenderTarget(Handle rth) { void VulkanDriver::createFenceR(Handle fh, int) { VulkanCommandBuffer const& commandBuffer = mCommands->get(); - construct(fh, commandBuffer.fence); + mHandleAllocator.construct(fh, commandBuffer.fence); } void VulkanDriver::createSwapChainR(Handle sch, void* nativeWindow, uint64_t flags) { - if ((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0 && - !isSRGBSwapChainSupported()) { + if ((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0 && !isSRGBSwapChainSupported()) { utils::slog.w << "sRGB swapchain requested, but Platform does not support it" << utils::io::endl; flags = flags | ~(backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE); } - construct(sch, mPlatform, mContext, mAllocator, mCommands.get(), mStagePool, - nativeWindow, flags); + mHandleAllocator.construct(sch, mPlatform, mContext, mAllocator, + mCommands.get(), mStagePool, nativeWindow, flags); } void VulkanDriver::createSwapChainHeadlessR(Handle sch, uint32_t width, @@ -526,8 +527,8 @@ void VulkanDriver::createSwapChainHeadlessR(Handle sch, uint32_t wi flags = flags | ~(backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE); } assert_invariant(width > 0 && height > 0 && "Vulkan requires non-zero swap chain dimensions."); - construct(sch, mPlatform, mContext, mAllocator, mCommands.get(), mStagePool, - nullptr, flags, VkExtent2D{width, height}); + mHandleAllocator.construct(sch, mPlatform, mContext, mAllocator, + mCommands.get(), mStagePool, nullptr, flags, VkExtent2D{width, height}); } void VulkanDriver::createTimerQueryR(Handle tqh, int) { @@ -535,68 +536,69 @@ void VulkanDriver::createTimerQueryR(Handle tqh, int) { } Handle VulkanDriver::createVertexBufferS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createIndexBufferS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createBufferObjectS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createTextureS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createTextureSwizzledS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::importTextureS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createSamplerGroupS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createRenderPrimitiveS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createProgramS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createDefaultRenderTargetS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createRenderTargetS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createFenceS() noexcept { - return initHandle(); + return mHandleAllocator.initHandle(); } Handle VulkanDriver::createSwapChainS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createSwapChainHeadlessS() noexcept { - return allocHandle(); + return mHandleAllocator.allocHandle(); } Handle VulkanDriver::createTimerQueryS() noexcept { // The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen // before createTimerQueryR is executed. - Handle tqh = initHandle(mTimestamps->getNextQuery()); - auto query = handle_cast(tqh); + Handle tqh + = mHandleAllocator.initHandle(mTimestamps->getNextQuery()); + auto query = mHandleAllocator.handle_cast(tqh); mDisposer.createDisposable(query, [this, tqh] () { - destruct(tqh); + mHandleAllocator.destruct(tqh); }); return tqh; } @@ -607,23 +609,23 @@ void VulkanDriver::destroySamplerGroup(Handle sbh) { // not map to any Vulkan objects. To handle destruction, the only thing we need to do is // ensure that the next draw call doesn't try to access a zombie sampler buffer. Therefore, // simply replace all weak references with null. - auto* hwsb = handle_cast(sbh); + auto* hwsb = mHandleAllocator.handle_cast(sbh); for (auto& binding : mSamplerBindings) { if (binding == hwsb) { binding = nullptr; } } - destruct(sbh); + mHandleAllocator.destruct(sbh); } } void VulkanDriver::destroySwapChain(Handle sch) { if (sch) { - VulkanSwapChain& swapChain = *handle_cast(sch); + VulkanSwapChain& swapChain = *mHandleAllocator.handle_cast(sch); if (mCurrentSwapChain == &swapChain) { mCurrentSwapChain = nullptr; } - destruct(sch); + mHandleAllocator.destruct(sch); } } @@ -632,7 +634,7 @@ void VulkanDriver::destroyStream(Handle sh) { void VulkanDriver::destroyTimerQuery(Handle tqh) { if (tqh) { - mDisposer.removeReference(handle_cast(tqh)); + mDisposer.removeReference(mHandleAllocator.handle_cast(tqh)); } } @@ -659,11 +661,11 @@ void VulkanDriver::updateStreams(CommandStream* driver) { } void VulkanDriver::destroyFence(Handle fh) { - destruct(fh); + mHandleAllocator.destruct(fh); } FenceStatus VulkanDriver::wait(Handle fh, uint64_t timeout) { - auto& cmdfence = handle_cast(fh)->fence; + auto& cmdfence = mHandleAllocator.handle_cast(fh)->fence; if (!cmdfence) { // If wait is called before a fence actually exists, we return timeout. This matches the // current behavior in OpenGLDriver, but we should eventually reconsider a different error @@ -836,15 +838,15 @@ size_t VulkanDriver::getMaxUniformBufferSize() { void VulkanDriver::setVertexBufferObject(Handle vbh, uint32_t index, Handle boh) { - auto& vb = *handle_cast(vbh); - auto& bo = *handle_cast(boh); + auto& vb = *mHandleAllocator.handle_cast(vbh); + auto& bo = *mHandleAllocator.handle_cast(boh); assert_invariant(bo.bindingType == BufferObjectBinding::VERTEX); vb.buffers[index] = &bo.buffer; } void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& p, uint32_t byteOffset) { - auto ib = handle_cast(ibh); + auto ib = mHandleAllocator.handle_cast(ibh); ib->buffer.loadFromCpu(p.buffer, byteOffset, p.size); mDisposer.acquire(ib); scheduleDestroy(std::move(p)); @@ -852,7 +854,7 @@ void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor void VulkanDriver::updateBufferObject(Handle boh, BufferDescriptor&& bd, uint32_t byteOffset) { - auto bo = handle_cast(boh); + auto bo = mHandleAllocator.handle_cast(boh); bo->buffer.loadFromCpu(bd.buffer, byteOffset, bd.size); mDisposer.acquire(bo); scheduleDestroy(std::move(bd)); @@ -860,7 +862,7 @@ void VulkanDriver::updateBufferObject(Handle boh, BufferDescript void VulkanDriver::updateBufferObjectUnsynchronized(Handle boh, BufferDescriptor&& bd, uint32_t byteOffset) { - auto bo = handle_cast(boh); + auto bo = mHandleAllocator.handle_cast(boh); // TODO: implement unsynchronized version bo->buffer.loadFromCpu(bd.buffer, byteOffset, bd.size); mDisposer.acquire(bo); @@ -877,15 +879,13 @@ void VulkanDriver::resetBufferObject(Handle boh) { } void VulkanDriver::setMinMaxLevels(Handle th, uint32_t minLevel, uint32_t maxLevel) { - handle_cast(th)->setPrimaryRange(minLevel, maxLevel); + mHandleAllocator.handle_cast(th)->setPrimaryRange(minLevel, maxLevel); } -void VulkanDriver::update3DImage( - Handle th, - uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t zoffset, - uint32_t width, uint32_t height, uint32_t depth, +void VulkanDriver::update3DImage(Handle th, uint32_t level, uint32_t xoffset, + uint32_t yoffset, uint32_t zoffset, uint32_t width, uint32_t height, uint32_t depth, PixelBufferDescriptor&& data) { - handle_cast(th)->updateImage(data, width, height, depth, + mHandleAllocator.handle_cast(th)->updateImage(data, width, height, depth, xoffset, yoffset, zoffset, level); scheduleDestroy(std::move(data)); } @@ -894,7 +894,7 @@ void VulkanDriver::setupExternalImage(void* image) { } bool VulkanDriver::getTimerQueryValue(Handle tqh, uint64_t* elapsedTime) { - VulkanTimerQuery* vtq = handle_cast(tqh); + VulkanTimerQuery* vtq = mHandleAllocator.handle_cast(tqh); if (!vtq->isCompleted()) { return false; } @@ -938,7 +938,7 @@ bool VulkanDriver::canGenerateMipmaps() { void VulkanDriver::updateSamplerGroup(Handle sbh, BufferDescriptor&& data) { - auto* sb = handle_cast(sbh); + auto* sb = mHandleAllocator.handle_cast(sbh); // FIXME: we shouldn't be using SamplerGroup here, instead the backend should create // a descriptor or any internal data-structure that represents the textures/samplers. @@ -960,7 +960,7 @@ void VulkanDriver::compilePrograms(CompilerPriorityQueue priority, } void VulkanDriver::beginRenderPass(Handle rth, const RenderPassParams& params) { - VulkanRenderTarget* const rt = handle_cast(rth); + VulkanRenderTarget* const rt = mHandleAllocator.handle_cast(rth); const VkExtent2D extent = rt->getExtent(); assert_invariant(extent.width > 0 && extent.height > 0); @@ -1002,7 +1002,8 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP for (size_t i = 0; i < sb->getSize(); i++) { SamplerDescriptor const* boundSampler = sb->data() + i; if (UTILS_LIKELY(boundSampler->t)) { - VulkanTexture* texture = handle_cast(boundSampler->t); + VulkanTexture* texture + = mHandleAllocator.handle_cast(boundSampler->t); if (!any(texture->usage & TextureUsage::DEPTH_ATTACHMENT)) { continue; } @@ -1279,15 +1280,15 @@ void VulkanDriver::nextSubpass(int) { void VulkanDriver::setRenderPrimitiveBuffer(Handle rph, Handle vbh, Handle ibh) { - auto primitive = handle_cast(rph); - primitive->setBuffers(handle_cast(vbh), - handle_cast(ibh)); + auto primitive = mHandleAllocator.handle_cast(rph); + primitive->setBuffers(mHandleAllocator.handle_cast(vbh), + mHandleAllocator.handle_cast(ibh)); } void VulkanDriver::setRenderPrimitiveRange(Handle rph, PrimitiveType pt, uint32_t offset, uint32_t minIndex, uint32_t maxIndex, uint32_t count) { - auto& primitive = *handle_cast(rph); + auto& primitive = *mHandleAllocator.handle_cast(rph); primitive.setPrimitiveType(pt); primitive.offset = offset * primitive.indexBuffer->elementSize; primitive.count = count; @@ -1298,7 +1299,7 @@ void VulkanDriver::setRenderPrimitiveRange(Handle rph, void VulkanDriver::makeCurrent(Handle drawSch, Handle readSch) { ASSERT_PRECONDITION_NON_FATAL(drawSch == readSch, "Vulkan driver does not support distinct draw/read swap chains."); - VulkanSwapChain* swapChain = mCurrentSwapChain = handle_cast(drawSch); + VulkanSwapChain* swapChain = mCurrentSwapChain = mHandleAllocator.handle_cast(drawSch); bool resized = false; swapChain->acquire(resized); @@ -1313,7 +1314,7 @@ void VulkanDriver::makeCurrent(Handle drawSch, Handle } void VulkanDriver::commit(Handle sch) { - VulkanSwapChain* swapChain = handle_cast(sch); + VulkanSwapChain* swapChain = mHandleAllocator.handle_cast(sch); if (mCommands->flush()) { collectGarbage(); @@ -1324,7 +1325,7 @@ void VulkanDriver::commit(Handle sch) { } void VulkanDriver::bindUniformBuffer(uint32_t index, Handle boh) { - auto* bo = handle_cast(boh); + auto* bo = mHandleAllocator.handle_cast(boh); const VkDeviceSize offset = 0; const VkDeviceSize size = VK_WHOLE_SIZE; mPipelineCache.bindUniformBuffer((uint32_t) index, bo->buffer.getGpuBuffer(), offset, size); @@ -1338,7 +1339,7 @@ void VulkanDriver::bindBufferRange(BufferObjectBinding bindingType, uint32_t ind // TODO: implement BufferObjectBinding::SHADER_STORAGE case - auto* bo = handle_cast(boh); + auto* bo = mHandleAllocator.handle_cast(boh); mPipelineCache.bindUniformBuffer((uint32_t)index, bo->buffer.getGpuBuffer(), offset, size); } @@ -1347,7 +1348,7 @@ void VulkanDriver::unbindBuffer(BufferObjectBinding bindingType, uint32_t index) } void VulkanDriver::bindSamplers(uint32_t index, Handle sbh) { - auto* hwsb = handle_cast(sbh); + auto* hwsb = mHandleAllocator.handle_cast(sbh); mSamplerBindings[index] = hwsb; } @@ -1378,7 +1379,7 @@ void VulkanDriver::stopCapture(int) {} void VulkanDriver::readPixels(Handle src, uint32_t x, uint32_t y, uint32_t width, uint32_t height, PixelBufferDescriptor&& pbd) { - VulkanRenderTarget* srcTarget = handle_cast(src); + VulkanRenderTarget* srcTarget = mHandleAllocator.handle_cast(src); mCommands->flush(); mReadPixels.run( srcTarget, x, y, width, height, mPlatform->getGraphicsQueueFamilyIndex(), @@ -1410,8 +1411,8 @@ void VulkanDriver::blit(TargetBufferFlags buffers, Handle dst, V return; } - VulkanRenderTarget* dstTarget = handle_cast(dst); - VulkanRenderTarget* srcTarget = handle_cast(src); + VulkanRenderTarget* dstTarget = mHandleAllocator.handle_cast(dst); + VulkanRenderTarget* srcTarget = mHandleAllocator.handle_cast(src); VkFilter vkfilter = filter == SamplerMagFilter::NEAREST ? VK_FILTER_NEAREST : VK_FILTER_LINEAR; @@ -1444,14 +1445,14 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r const uint32_t instanceCount) { VulkanCommandBuffer const* commands = &mCommands->get(); VkCommandBuffer cmdbuffer = commands->cmdbuffer; - const VulkanRenderPrimitive& prim = *handle_cast(rph); + const VulkanRenderPrimitive& prim = *mHandleAllocator.handle_cast(rph); Handle programHandle = pipelineState.program; RasterState rasterState = pipelineState.rasterState; PolygonOffset depthOffset = pipelineState.polygonOffset; const Viewport& scissorBox = pipelineState.scissor; - auto* program = handle_cast(programHandle); + auto* program = mHandleAllocator.handle_cast(programHandle); mDisposer.acquire(program); mDisposer.acquire(prim.indexBuffer); mDisposer.acquire(prim.vertexBuffer); @@ -1565,7 +1566,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r samplerIdx++; if (UTILS_LIKELY(boundSampler->t)) { - VulkanTexture* texture = handle_cast(boundSampler->t); + VulkanTexture* texture = mHandleAllocator.handle_cast(boundSampler->t); mDisposer.acquire(texture); // TODO: can this uninitialized check be checked in a higher layer? @@ -1652,12 +1653,12 @@ void VulkanDriver::dispatchCompute(Handle program, math::uint3 workGr } void VulkanDriver::beginTimerQuery(Handle tqh) { - VulkanTimerQuery* vtq = handle_cast(tqh); + VulkanTimerQuery* vtq = mHandleAllocator.handle_cast(tqh); mTimestamps->beginQuery(&(mCommands->get()), vtq); } void VulkanDriver::endTimerQuery(Handle tqh) { - VulkanTimerQuery* vtq = handle_cast(tqh); + VulkanTimerQuery* vtq = mHandleAllocator.handle_cast(tqh); mTimestamps->endQuery(&(mCommands->get()), vtq); } diff --git a/filament/backend/src/vulkan/VulkanDriver.h b/filament/backend/src/vulkan/VulkanDriver.h index 75673f6ec86..0b2d441d2ab 100644 --- a/filament/backend/src/vulkan/VulkanDriver.h +++ b/filament/backend/src/vulkan/VulkanDriver.h @@ -17,37 +17,92 @@ #ifndef TNT_FILAMENT_BACKEND_VULKANDRIVER_H #define TNT_FILAMENT_BACKEND_VULKANDRIVER_H -#include "VulkanPipelineCache.h" #include "VulkanBlitter.h" -#include "VulkanDisposer.h" #include "VulkanConstants.h" #include "VulkanContext.h" +#include "VulkanDisposer.h" #include "VulkanFboCache.h" +#include "VulkanHandles.h" +#include "VulkanPipelineCache.h" #include "VulkanReadPixels.h" #include "VulkanSamplerCache.h" #include "VulkanStagePool.h" #include "VulkanUtility.h" +#include "DriverBase.h" #include "private/backend/Driver.h" #include "private/backend/HandleAllocator.h" -#include "DriverBase.h" -#include #include +#include namespace filament::backend { class VulkanPlatform; struct VulkanSamplerGroup; +class VulkanHandleAllocator { +public: + VulkanHandleAllocator(size_t arenaSize) + : mHandleAllocatorImpl("Handles", arenaSize) {} + + template + inline Handle initHandle(ARGS&&... args) noexcept { + return mHandleAllocatorImpl.allocateAndConstruct(std::forward(args)...); + } + + template + inline Handle allocHandle() noexcept { + return mHandleAllocatorImpl.allocate(); + } + + template + inline typename std::enable_if::value, D>::type* construct( + Handle const& handle, ARGS&&... args) noexcept { + return mHandleAllocatorImpl.construct(handle, std::forward(args)...); + } + + template::value, D>::type> + inline void destruct(Handle handle, D const* p) noexcept { + return mHandleAllocatorImpl.deallocate(handle, p); + } + + template + inline typename std::enable_if_t< + std::is_pointer_v && std::is_base_of_v>, Dp> + handle_cast(Handle& handle) noexcept { + return mHandleAllocatorImpl.handle_cast(handle); + } + + template + inline typename std::enable_if_t< + std::is_pointer_v && std::is_base_of_v>, Dp> + handle_cast(Handle const& handle) noexcept { + return mHandleAllocatorImpl.handle_cast(handle); + } + + template + inline void destruct(Handle handle) noexcept { + if constexpr (std::is_base_of_v + || std::is_base_of_v) { + auto ptr = handle_cast(handle); + ptr->terminate(); + } + destruct(handle, handle_cast(handle)); + } + + HandleAllocatorVK mHandleAllocatorImpl; +}; + class VulkanDriver final : public DriverBase { public: static Driver* create(VulkanPlatform* platform, VulkanContext const& context, Platform::DriverConfig const& driverConfig) noexcept; private: - - void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept override; + void debugCommandBegin(CommandStream* cmds, bool synchronous, + const char* methodName) noexcept override; inline VulkanDriver(VulkanPlatform* platform, VulkanContext const& context, Platform::DriverConfig const& driverConfig) noexcept; @@ -61,77 +116,24 @@ class VulkanDriver final : public DriverBase { template friend class ConcreteDispatcher; -#define DECL_DRIVER_API(methodName, paramsDecl, params) \ +#define DECL_DRIVER_API(methodName, paramsDecl, params) \ UTILS_ALWAYS_INLINE inline void methodName(paramsDecl); -#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params) \ +#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params) \ RetType methodName(paramsDecl) override; -#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \ - RetType methodName##S() noexcept override; \ +#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \ + RetType methodName##S() noexcept override; \ UTILS_ALWAYS_INLINE inline void methodName##R(RetType, paramsDecl); #include "private/backend/DriverAPI.inc" VulkanDriver(VulkanDriver const&) = delete; - VulkanDriver& operator = (VulkanDriver const&) = delete; + VulkanDriver& operator=(VulkanDriver const&) = delete; private: - - template - Handle initHandle(ARGS&& ... args) noexcept { - return mHandleAllocator.allocateAndConstruct(std::forward(args) ...); - } - - template - Handle allocHandle() noexcept { - return mHandleAllocator.allocate(); - } - - template - typename std::enable_if::value, D>::type* - construct(Handle const& handle, ARGS&& ... args) noexcept { - return mHandleAllocator.construct(handle, std::forward(args) ...); - } - - template::value, D>::type> - void destruct(Handle handle, D const* p) noexcept { - return mHandleAllocator.deallocate(handle, p); - } - - template - typename std::enable_if_t< - std::is_pointer_v && - std::is_base_of_v>, Dp> - handle_cast(Handle& handle) noexcept { - return mHandleAllocator.handle_cast(handle); - } - - template - inline typename std::enable_if_t< - std::is_pointer_v && - std::is_base_of_v>, Dp> - handle_cast(Handle const& handle) noexcept { - return mHandleAllocator.handle_cast(handle); - } - - template - void destruct(Handle handle) noexcept { - destruct(handle, handle_cast(handle)); - } - - // This version of destruct takes a VulkanContext and calls a terminate(VulkanContext&) - // on the handle before calling the dtor - template - void destructBuffer(Handle handle) noexcept { - auto ptr = handle_cast(handle); - ptr->terminate(); - mHandleAllocator.deallocate(handle, ptr); - } - - inline void setRenderPrimitiveBuffer(Handle rph, - Handle vbh, Handle ibh); + inline void setRenderPrimitiveBuffer(Handle rph, Handle vbh, + Handle ibh); inline void setRenderPrimitiveRange(Handle rph, PrimitiveType pt, uint32_t offset, uint32_t minIndex, uint32_t maxIndex, uint32_t count); @@ -151,7 +153,7 @@ class VulkanDriver final : public DriverBase { VkDebugUtilsMessengerEXT mDebugMessenger = VK_NULL_HANDLE; VulkanContext mContext = {}; - HandleAllocatorVK mHandleAllocator; + VulkanHandleAllocator mHandleAllocator; VulkanPipelineCache mPipelineCache; VulkanDisposer mDisposer; VulkanStagePool mStagePool; diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index fe5fc2227e0..5f2d2ee5bd9 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -14,10 +14,12 @@ * limitations under the License. */ - #ifndef TNT_FILAMENT_BACKEND_VULKANHANDLES_H - #define TNT_FILAMENT_BACKEND_VULKANHANDLES_H +#ifndef TNT_FILAMENT_BACKEND_VULKANHANDLES_H +#define TNT_FILAMENT_BACKEND_VULKANHANDLES_H + +// This needs to be at the top +#include "DriverBase.h" -#include "VulkanDriver.h" #include "VulkanPipelineCache.h" #include "VulkanBuffer.h" #include "VulkanSwapChain.h" @@ -26,7 +28,7 @@ #include "private/backend/SamplerGroup.h" -#include "utils/Mutex.h" +#include namespace filament::backend { diff --git a/filament/backend/src/vulkan/VulkanSwapChain.h b/filament/backend/src/vulkan/VulkanSwapChain.h index e89d75f5985..681f4a1e1dc 100644 --- a/filament/backend/src/vulkan/VulkanSwapChain.h +++ b/filament/backend/src/vulkan/VulkanSwapChain.h @@ -17,8 +17,9 @@ #ifndef TNT_FILAMENT_BACKEND_VULKANSWAPCHAIN_H #define TNT_FILAMENT_BACKEND_VULKANSWAPCHAIN_H +#include "DriverBase.h" + #include "VulkanContext.h" -#include "VulkanDriver.h" #include diff --git a/filament/backend/src/vulkan/VulkanTexture.h b/filament/backend/src/vulkan/VulkanTexture.h index 05eafae6b58..d56f2f3539d 100644 --- a/filament/backend/src/vulkan/VulkanTexture.h +++ b/filament/backend/src/vulkan/VulkanTexture.h @@ -17,7 +17,8 @@ #ifndef TNT_FILAMENT_BACKEND_VULKANTEXTURE_H #define TNT_FILAMENT_BACKEND_VULKANTEXTURE_H -#include "VulkanDriver.h" +#include "DriverBase.h" + #include "VulkanBuffer.h" #include "VulkanImageUtility.h"