diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index e9e4062ac6..a880fd6d00 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -28,8 +28,6 @@ #include "generated/vkshaders/vkshaders.h" -#define FILAMENT_VULKAN_CHECK_BLIT_FORMAT 0 - using namespace bluevk; using namespace utils; @@ -69,7 +67,7 @@ inline void blitFast(const VkCommandBuffer cmdbuffer, VkImageAspectFlags aspect, .layerCount = 1, }; - if constexpr (FILAMENT_VULKAN_VERBOSE) { + if constexpr (FVK_ENABLED(FVK_DEBUG_BLITTER)) { utils::slog.d << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level << "layout=" << src.getLayout() << " to=" << dst.texture->getVkImage() << ",level=" << (int) dst.level @@ -132,7 +130,7 @@ void VulkanBlitter::blitColor(BlitArgs args) { const VulkanAttachment dst = args.dstTarget->getColor(0); const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; -#if FILAMENT_VULKAN_CHECK_BLIT_FORMAT +#if FVK_ENABLED(FVK_DEBUG_BLIT_FORMAT) VkPhysicalDevice const gpu = mPhysicalDevice; VkFormatProperties info; vkGetPhysicalDeviceFormatProperties(gpu, src.getFormat(), &info); @@ -160,7 +158,7 @@ void VulkanBlitter::blitDepth(BlitArgs args) { const VulkanAttachment dst = args.dstTarget->getDepth(); const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_DEPTH_BIT; -#if FILAMENT_VULKAN_CHECK_BLIT_FORMAT +#if FVK_ENABLED(FVK_DEBUG_BLIT_FORMAT) VkPhysicalDevice const gpu = mPhysicalDevice; VkFormatProperties info; vkGetPhysicalDeviceFormatProperties(gpu, src.getFormat(), &info); @@ -241,7 +239,7 @@ void VulkanBlitter::lazyInit() noexcept { mDepthResolveProgram->samplerGroupInfo[0].samplers.reserve(1); mDepthResolveProgram->samplerGroupInfo[0].samplers.resize(1); - if constexpr (FILAMENT_VULKAN_VERBOSE) { + if constexpr (FVK_ENABLED(FVK_DEBUG_BLITTER)) { utils::slog.d << "Created Shader Module for VulkanBlitter " << "shaders = (" << vertexShader << ", " << fragmentShader << ")" << utils::io::endl; diff --git a/filament/backend/src/vulkan/VulkanCommands.cpp b/filament/backend/src/vulkan/VulkanCommands.cpp index 8a2b2c61a7..960b93ac95 100644 --- a/filament/backend/src/vulkan/VulkanCommands.cpp +++ b/filament/backend/src/vulkan/VulkanCommands.cpp @@ -33,7 +33,9 @@ using namespace utils; namespace filament::backend { +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) using Timestamp = VulkanGroupMarkers::Timestamp; +#endif VulkanCmdFence::VulkanCmdFence(VkFence ifence) : fence(ifence) { @@ -63,20 +65,21 @@ CommandBufferObserver::~CommandBufferObserver() {} static VkCommandPool createPool(VkDevice device, uint32_t queueFamilyIndex) { 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 = queueFamilyIndex, + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT + | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, + .queueFamilyIndex = queueFamilyIndex, }; VkCommandPool pool; vkCreateCommandPool(device, &createInfo, VKALLOC, &pool); return pool; - } +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) void VulkanGroupMarkers::push(std::string const& marker, Timestamp start) noexcept { mMarkers.push_back(marker); -#if FILAMENT_VULKAN_VERBOSE + +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) mTimestamps.push_back(start.time_since_epoch().count() > 0.0 ? start : std::chrono::high_resolution_clock::now()); @@ -87,7 +90,7 @@ std::pair VulkanGroupMarkers::pop() noexcept { auto const marker = mMarkers.back(); mMarkers.pop_back(); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) auto const timestamp = mTimestamps.back(); mTimestamps.pop_back(); return std::make_pair(marker, timestamp); @@ -100,7 +103,7 @@ std::pair VulkanGroupMarkers::pop_bottom() noexcept { auto const marker = mMarkers.front(); mMarkers.pop_front(); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) auto const timestamp = mTimestamps.front(); mTimestamps.pop_front(); return std::make_pair(marker, timestamp); @@ -112,7 +115,7 @@ std::pair VulkanGroupMarkers::pop_bottom() noexcept { std::pair VulkanGroupMarkers::top() const { assert_invariant(!empty()); auto const marker = mMarkers.back(); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) auto const topTimestamp = mTimestamps.front(); return std::make_pair(marker, topTimestamp); #else @@ -124,6 +127,8 @@ bool VulkanGroupMarkers::empty() const noexcept { return mMarkers.empty(); } +#endif // FVK_DEBUG_GROUP_MARKERS + VulkanCommands::VulkanCommands(VkDevice device, VkQueue queue, uint32_t queueFamilyIndex, VulkanContext* context, VulkanResourceAllocator* allocator) : mDevice(device), @@ -144,6 +149,10 @@ VulkanCommands::VulkanCommands(VkDevice device, VkQueue queue, uint32_t queueFam for (size_t i = 0; i < CAPACITY; ++i) { mStorage[i] = std::make_unique(allocator, mDevice, mPool); } + +#if !FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) + (void) mContext; +#endif } VulkanCommands::~VulkanCommands() { @@ -167,7 +176,7 @@ VulkanCommandBuffer& VulkanCommands::get() { // It occurs only when Filament invokes commit() or endFrame() a large number of times without // presenting the swap chain or waiting on a fence. while (mAvailableBufferCount == 0) { -#if VK_REPORT_STALLS +#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER) slog.i << "VulkanCommands has stalled. " << "If this occurs frequently, consider increasing VK_MAX_COMMAND_BUFFERS." << io::endl; @@ -207,12 +216,14 @@ VulkanCommandBuffer& VulkanCommands::get() { mObserver->onCommandBuffer(*currentbuf); } +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) // We push the current markers onto a temporary stack. This must be placed after currentbuf is // set to the new command buffer since pushGroupMarker also calls get(). while (mCarriedOverMarkers && !mCarriedOverMarkers->empty()) { auto [marker, time] = mCarriedOverMarkers->pop(); pushGroupMarker(marker.c_str(), time); } +#endif return *currentbuf; } @@ -224,6 +235,7 @@ bool VulkanCommands::flush() { // Before actually submitting, we need to pop any leftover group markers. // Note that this needs to occur before vkEndCommandBuffer. +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) while (mGroupMarkers && !mGroupMarkers->empty()) { if (!mCarriedOverMarkers) { mCarriedOverMarkers = std::make_unique(); @@ -233,7 +245,7 @@ bool VulkanCommands::flush() { // We still need to call through to vkCmdEndDebugUtilsLabelEXT. popGroupMarker(); } - +#endif int8_t const index = mCurrentCommandBufferIndex; VulkanCommandBuffer const* currentbuf = mStorage[index].get(); @@ -283,7 +295,7 @@ bool VulkanCommands::flush() { submitInfo.pWaitSemaphores = VK_NULL_HANDLE; } -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER) slog.i << "Submitting cmdbuffer=" << cmdbuffer << " wait=(" << signals[0] << ", " << signals[1] << ") " << " signal=" << renderingFinished @@ -297,7 +309,7 @@ bool VulkanCommands::flush() { cmdfence->condition.notify_all(); lock.unlock(); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER) if (result != VK_SUCCESS) { utils::slog.d << "Failed command buffer submission result: " << result << utils::io::endl; } @@ -313,8 +325,8 @@ bool VulkanCommands::flush() { VkSemaphore VulkanCommands::acquireFinishedSignal() { VkSemaphore semaphore = mSubmissionSignal; mSubmissionSignal = VK_NULL_HANDLE; -#if FILAMENT_VULKAN_VERBOSE - slog.i << "Acquiring " << semaphore << " (e.g. for vkQueuePresentKHR)" << io::endl; +#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER) + slog.i << "Acquiring " << semaphore << " (e.g. for vkQueuePresentKHR)" << io::endl; #endif return semaphore; } @@ -322,7 +334,7 @@ VkSemaphore VulkanCommands::acquireFinishedSignal() { void VulkanCommands::injectDependency(VkSemaphore next) { assert_invariant(mInjectedSignal == VK_NULL_HANDLE); mInjectedSignal = next; -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER) slog.i << "Injecting " << next << " (e.g. due to vkAcquireNextImageKHR)" << io::endl; #endif } @@ -344,6 +356,9 @@ void VulkanCommands::wait() { } void VulkanCommands::gc() { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("commands::gc"); + VkFence fences[CAPACITY]; size_t count = 0; @@ -365,6 +380,7 @@ void VulkanCommands::gc() { if (count > 0) { vkResetFences(mDevice, count, fences); } + FVK_SYSTRACE_END(); } void VulkanCommands::updateFences() { @@ -381,8 +397,10 @@ void VulkanCommands::updateFences() { } } +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) + void VulkanCommands::pushGroupMarker(char const* str, VulkanGroupMarkers::Timestamp timestamp) { -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) // If the timestamp is not 0, then we are carrying over a marker across buffer submits. // If it is 0, then this is a normal marker push and we should just print debug line as usual. if (timestamp.time_since_epoch().count() == 0.0) { @@ -420,7 +438,7 @@ void VulkanCommands::popGroupMarker() { if (!mGroupMarkers->empty()) { VkCommandBuffer const cmdbuffer = get().buffer(); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) auto const [marker, startTime] = mGroupMarkers->pop(); auto const endTime = std::chrono::high_resolution_clock::now(); std::chrono::duration diff = endTime - startTime; @@ -429,7 +447,6 @@ void VulkanCommands::popGroupMarker() { #else mGroupMarkers->pop(); #endif - if (mContext->isDebugUtilsSupported()) { vkCmdEndDebugUtilsLabelEXT(cmdbuffer); } else if (mContext->isDebugMarkersSupported()) { @@ -468,8 +485,9 @@ std::string VulkanCommands::getTopGroupMarker() const { } return std::get<0>(mGroupMarkers->top()); } +#endif // FVK_DEBUG_GROUP_MARKERS -}// namespace filament::backend +} // namespace filament::backend #if defined(_MSC_VER) #pragma warning( pop ) diff --git a/filament/backend/src/vulkan/VulkanCommands.h b/filament/backend/src/vulkan/VulkanCommands.h index 15605cfef8..660e3e106c 100644 --- a/filament/backend/src/vulkan/VulkanCommands.h +++ b/filament/backend/src/vulkan/VulkanCommands.h @@ -39,6 +39,7 @@ namespace filament::backend { struct VulkanContext; +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) class VulkanGroupMarkers { public: using Timestamp = std::chrono::time_point; @@ -51,11 +52,13 @@ public: private: std::list mMarkers; -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) std::list mTimestamps; #endif }; +#endif // FVK_DEBUG_GROUP_MARKERS + // Wrapper to enable use of shared_ptr for implementing shared ownership of low-level Vulkan fences. struct VulkanCmdFence { VulkanCmdFence(VkFence ifence); @@ -170,6 +173,7 @@ class VulkanCommands { // The observer's event handler can only be called during get(). void setObserver(CommandBufferObserver* observer) { mObserver = observer; } +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) void pushGroupMarker(char const* str, VulkanGroupMarkers::Timestamp timestamp = {}); void popGroupMarker(); @@ -177,9 +181,10 @@ class VulkanCommands { void insertEventMarker(char const* string, uint32_t len); std::string getTopGroupMarker() const; +#endif private: - static constexpr int CAPACITY = VK_MAX_COMMAND_BUFFERS; + static constexpr int CAPACITY = FVK_MAX_COMMAND_BUFFERS; VkDevice const mDevice; VkQueue const mQueue; VkCommandPool const mPool; @@ -196,8 +201,10 @@ class VulkanCommands { uint8_t mAvailableBufferCount = CAPACITY; CommandBufferObserver* mObserver = nullptr; +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) std::unique_ptr mGroupMarkers; std::unique_ptr mCarriedOverMarkers; +#endif }; } // namespace filament::backend diff --git a/filament/backend/src/vulkan/VulkanConstants.h b/filament/backend/src/vulkan/VulkanConstants.h index 7692366fd3..429060535d 100644 --- a/filament/backend/src/vulkan/VulkanConstants.h +++ b/filament/backend/src/vulkan/VulkanConstants.h @@ -19,13 +19,6 @@ #include -#define FILAMENT_VULKAN_VERBOSE 0 -#define FILAMENT_VULKAN_DUMP_API 0 - -#ifndef FILAMENT_VULKAN_HANDLE_ARENA_SIZE_IN_MB -#define FILAMENT_VULKAN_HANDLE_ARENA_SIZE_IN_MB 8 -#endif - // In debug builds, we enable validation layers and set up a debug callback. // // To enable validation layers in Android, also be sure to set the jniLibs property in the gradle @@ -43,21 +36,80 @@ // ndkVersion "23.1.7779620" // // Also consider changing the root `gradle.properties` to point to a debug build, although this is -// not required for validation if you change the definition of VK_ENABLE_VALIDATION below. -#if defined(NDEBUG) -#define VK_ENABLE_VALIDATION 0 +// not required for validation. + +// FVK is short for Filament Vulkan +#define FVK_DEBUG_SYSTRACE 0x00000001 +#define FVK_DEBUG_GROUP_MARKERS 0x00000002 +#define FVK_DEBUG_TEXTURE 0x00000004 +#define FVK_DEBUG_LAYOUT_TRANSITION 0x00000008 +#define FVK_DEBUG_COMMAND_BUFFER 0x00000010 +#define FVK_DEBUG_DUMP_API 0x00000020 +#define FVK_DEBUG_VALIDATION 0x00000040 +#define FVK_DEBUG_PRINT_GROUP_MARKERS 0x00000080 +#define FVK_DEBUG_BLIT_FORMAT 0x00000100 +#define FVK_DEBUG_BLITTER 0x00000200 +#define FVK_DEBUG_FBO_CACHE 0x00000400 +#define FVK_DEBUG_SHADER_MODULE 0x00000800 +#define FVK_DEBUG_READ_PIXELS 0x00001000 +#define FVK_DEBUG_PIPELINE_CACHE 0x00002000 +#define FVK_DEBUG_ALLOCATION 0x00004000 + +// Usefaul default combinations +#define FVK_DEBUG_EVERYTHING 0xFFFFFFFF +#define FVK_DEBUG_PERFORMANCE \ + FVK_DEBUG_SYSTRACE | \ + FVK_DEBUG_GROUP_MARKERS + +#define FVK_DEBUG_CORRECTNESS \ + FVK_DEBUG_VALIDATION | \ + FVK_DEBUG_SHADER_MODULE | \ + FVK_DEBUG_TEXTURE | \ + FVK_DEBUG_LAYOUT_TRANSITION + +#define FVK_DEBUG_RENDER_PASSES \ + FVK_DEBUG_GROUP_MARKERS | \ + FVK_DEBUG_PRINT_GROUP_MARKERS + +#ifndef NDEBUG +#define FVK_DEBUG_FLAGS FVK_DEBUG_PERFORMANCE #else -#define VK_ENABLE_VALIDATION 1 +#define FVK_DEBUG_FLAGS 0 #endif -#define VK_REPORT_STALLS 0 +#define FVK_ENABLED(flags) ((FVK_DEBUG_FLAGS) & (flags)) +#define FVK_ENABLED_BOOL(flags) ((bool) FVK_ENABLED(flags)) + +// Ensure dependencies are met between debug options +#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS) +static_assert(FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS)); +#endif + +// end dependcy checks + +#if FVK_ENABLED(FVK_DEBUG_SYSTRACE) + +#include + +#define FVK_SYSTRACE_CONTEXT() SYSTRACE_CONTEXT() +#define FVK_SYSTRACE_START(marker) SYSTRACE_NAME_BEGIN(marker) +#define FVK_SYSTRACE_END() SYSTRACE_NAME_END() +#else +#define FVK_SYSTRACE_CONTEXT() +#define FVK_SYSTRACE_START(marker) +#define FVK_SYSTRACE_END() +#endif + +#ifndef FVK_HANDLE_ARENA_SIZE_IN_MB +#define FVK_HANDLE_ARENA_SIZE_IN_MB 8 +#endif // All vkCreate* functions take an optional allocator. For now we select the default allocator by // passing in a null pointer, and we highlight the argument by using the VKALLOC constant. constexpr struct VkAllocationCallbacks* VKALLOC = nullptr; -constexpr static const int VK_REQUIRED_VERSION_MAJOR = 1; -constexpr static const int VK_REQUIRED_VERSION_MINOR = 1; +constexpr static const int FVK_REQUIRED_VERSION_MAJOR = 1; +constexpr static const int FVK_REQUIRED_VERSION_MINOR = 1; // Maximum number of VkCommandBuffer handles managed simultaneously by VulkanCommands. // @@ -65,18 +117,18 @@ constexpr static const int VK_REQUIRED_VERSION_MINOR = 1; // buffers that have been submitted but have not yet finished rendering. Note that Filament can // issue multiple commit calls in a single frame, and that we use a triple buffered swap chain on // some platforms. -constexpr static const int VK_MAX_COMMAND_BUFFERS = 10; +constexpr static const int FVK_MAX_COMMAND_BUFFERS = 10; // Number of command buffer submissions that should occur before an unused pipeline is removed // from the cache. // // If this number is low, VkPipeline construction will occur frequently, which can // be extremely slow. If this number is high, the memory footprint will be large. -constexpr static const int VK_MAX_PIPELINE_AGE = 10; +constexpr static const int FVK_MAX_PIPELINE_AGE = 10; // VulkanPipelineCache does not track which command buffers contain references to which pipelines, -// instead it simply waits for at least VK_MAX_COMMAND_BUFFERS submissions to occur before +// instead it simply waits for at least FVK_MAX_COMMAND_BUFFERS submissions to occur before // destroying any unused pipeline object. -static_assert(VK_MAX_PIPELINE_AGE >= VK_MAX_COMMAND_BUFFERS); +static_assert(FVK_MAX_PIPELINE_AGE >= FVK_MAX_COMMAND_BUFFERS); #endif diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 40cb457c8c..116451763e 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -30,10 +30,9 @@ #include #include #include -#include #ifndef NDEBUG -#include +#include // For VulkanDriver::debugCommandBegin #endif using namespace bluevk; @@ -101,7 +100,7 @@ VulkanTexture* createEmptyTexture(VkDevice device, VkPhysicalDevice physicalDevi return emptyTexture; } -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { @@ -136,7 +135,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsCallback(VkDebugUtilsMessageSeverityFla utils::slog.e << utils::io::endl; return VK_FALSE; } -#endif// VK_ENABLE_VALIDATION +#endif // FVK_EANBLED(FVK_DEBUG_VALIDATION) } // anonymous namespace @@ -159,7 +158,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext const& contex mBlitter(mStagePool, mPipelineCache, mFramebufferCache, mSamplerCache), mReadPixels(mPlatform->getDevice()) { -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) UTILS_UNUSED const PFN_vkCreateDebugReportCallbackEXT createDebugReportCallback = vkCreateDebugReportCallbackEXT; VkResult result; @@ -214,7 +213,7 @@ UTILS_NOINLINE Driver* VulkanDriver::create(VulkanPlatform* platform, VulkanContext const& context, Platform::DriverConfig const& driverConfig) noexcept { assert_invariant(platform); - size_t defaultSize = FILAMENT_VULKAN_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U; + size_t defaultSize = FVK_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U; Platform::DriverConfig validConfig{ .handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize)}; return new VulkanDriver(platform, context, validConfig); @@ -266,24 +265,15 @@ void VulkanDriver::tick(int) { // rather than the wall clock, because we must wait 3 frames after a DriverAPI-level resource has // been destroyed for safe destruction, due to outstanding command buffers and triple buffering. void VulkanDriver::collectGarbage() { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("gc"); // Command buffers need to be submitted and completed before other resources can be gc'd. And // its gc() function carrys out the *wait*. - SYSTRACE_CONTEXT(); - SYSTRACE_NAME_BEGIN("gc"); - mCommands->gc(); - - SYSTRACE_NAME_BEGIN("stagepool-gc"); mStagePool.gc(); - SYSTRACE_NAME_END(); - - SYSTRACE_NAME_BEGIN("framebuffercache-gc"); mFramebufferCache.gc(); - SYSTRACE_NAME_END(); - - SYSTRACE_NAME_END(); // "gc" + FVK_SYSTRACE_END(); } - void VulkanDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) { // Do nothing. } @@ -306,14 +296,21 @@ void VulkanDriver::endFrame(uint32_t frameId) { } void VulkanDriver::flush(int) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("flush"); mCommands->flush(); + FVK_SYSTRACE_END(); } void VulkanDriver::finish(int dummy) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("finish"); + mCommands->flush(); mCommands->wait(); mReadPixels.runUntilComplete(); + FVK_SYSTRACE_END(); } void VulkanDriver::createSamplerGroupR(Handle sbh, uint32_t count) { @@ -990,6 +987,9 @@ void VulkanDriver::compilePrograms(CompilerPriorityQueue priority, } void VulkanDriver::beginRenderPass(Handle rth, const RenderPassParams& params) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("beginRenderPass"); + VulkanRenderTarget* const rt = mResourceAllocator.handle_cast(rth); const VkExtent2D extent = rt->getExtent(); assert_invariant(extent.width > 0 && extent.height > 0); @@ -1008,7 +1008,8 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP } VulkanAttachment depth = rt->getSamples() == 1 ? rt->getDepth() : rt->getMsaaDepth(); -#if FILAMENT_VULKAN_VERBOSE + +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) if (depth.texture) { depth.texture->print(); } @@ -1153,6 +1154,7 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP VkFramebuffer vkfb = mFramebufferCache.getFramebuffer(fbkey); // Assign a label to the framebuffer for debugging purposes. + #if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) if (UTILS_UNLIKELY(mContext.isDebugUtilsSupported())) { auto const topMarker = mCommands->getTopGroupMarker(); if (!topMarker.empty()) { @@ -1166,6 +1168,7 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP vkSetDebugUtilsObjectNameEXT(mPlatform->getDevice(), &info); } } + #endif // The current command buffer now owns a reference to the render target and its attachments. // Note that we must acquire parent textures, not sidecars. @@ -1242,9 +1245,13 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP .params = params, .currentSubpass = 0, }; + FVK_SYSTRACE_END(); } void VulkanDriver::endRenderPass(int) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("endRenderPass"); + VulkanCommandBuffer& commands = mCommands->get(); VkCommandBuffer cmdbuffer = commands.buffer(); vkCmdEndRenderPass(cmdbuffer); @@ -1288,6 +1295,7 @@ void VulkanDriver::endRenderPass(int) { } mCurrentRenderPass.renderTarget = nullptr; mCurrentRenderPass.renderPass = VK_NULL_HANDLE; + FVK_SYSTRACE_END(); } void VulkanDriver::nextSubpass(int) { @@ -1334,6 +1342,9 @@ void VulkanDriver::setRenderPrimitiveRange(Handle rph, } void VulkanDriver::makeCurrent(Handle drawSch, Handle readSch) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("makeCurrent"); + ASSERT_PRECONDITION_NON_FATAL(drawSch == readSch, "Vulkan driver does not support distinct draw/read swap chains."); VulkanSwapChain* swapChain = mCurrentSwapChain @@ -1349,9 +1360,14 @@ void VulkanDriver::makeCurrent(Handle drawSch, Handle if (UTILS_LIKELY(mDefaultRenderTarget)) { mDefaultRenderTarget->bindToSwapChain(*swapChain); } + + FVK_SYSTRACE_END(); } void VulkanDriver::commit(Handle sch) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("commit"); + VulkanSwapChain* swapChain = mResourceAllocator.handle_cast(sch); if (mCommands->flush()) { @@ -1360,6 +1376,7 @@ void VulkanDriver::commit(Handle sch) { // Present the backbuffer after the most recent command buffer submission has finished. swapChain->present(); + FVK_SYSTRACE_END(); } void VulkanDriver::bindUniformBuffer(uint32_t index, Handle boh) { @@ -1391,24 +1408,26 @@ void VulkanDriver::bindSamplers(uint32_t index, Handle sbh) { } void VulkanDriver::insertEventMarker(char const* string, uint32_t len) { +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) mCommands->insertEventMarker(string, len); +#endif } void VulkanDriver::pushGroupMarker(char const* string, uint32_t) { // Turns out all the markers are 0-terminated, so we can just pass it without len. +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) mCommands->pushGroupMarker(string); - { - SYSTRACE_CONTEXT(); - SYSTRACE_NAME_BEGIN(string); - } +#endif + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START(string); } void VulkanDriver::popGroupMarker(int) { +#if FVK_ENABLED(FVK_DEBUG_GROUP_MARKERS) mCommands->popGroupMarker(); - { - SYSTRACE_CONTEXT(); - SYSTRACE_NAME_END(); - } +#endif + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_END(); } void VulkanDriver::startCapture(int) {} @@ -1439,6 +1458,9 @@ void VulkanDriver::readBufferSubData(backend::BufferObjectHandle boh, void VulkanDriver::blit(TargetBufferFlags buffers, Handle dst, Viewport dstRect, Handle src, Viewport srcRect, SamplerMagFilter filter) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("blit"); + assert_invariant(mCurrentRenderPass.renderPass == VK_NULL_HANDLE); // blit operation only support COLOR0 color buffer @@ -1478,10 +1500,14 @@ void VulkanDriver::blit(TargetBufferFlags buffers, Handle dst, V if (any(buffers & TargetBufferFlags::COLOR0)) { mBlitter.blitColor({ dstTarget, dstOffsets, srcTarget, srcOffsets, vkfilter, int(0) }); } + FVK_SYSTRACE_END(); } void VulkanDriver::draw(PipelineState pipelineState, Handle rph, const uint32_t instanceCount) { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("draw"); + VulkanCommandBuffer* commands = &mCommands->get(); VkCommandBuffer cmdbuffer = commands->buffer(); const VulkanRenderPrimitive& prim = *mResourceAllocator.handle_cast(rph); @@ -1497,7 +1523,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r commands->acquire(prim.vertexBuffer); // If this is a debug build, validate the current shader. -#if !defined(NDEBUG) +#if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE) if (program->bundle.vertex == VK_NULL_HANDLE || program->bundle.fragment == VK_NULL_HANDLE) { utils::slog.e << "Binding missing shader: " << program->name.c_str() << utils::io::endl; } @@ -1613,7 +1639,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r // This fallback path is very flaky because the dummy texture might not have // matching characteristics. (e.g. if the missing texture is a 3D texture) if (UTILS_UNLIKELY(texture->getPrimaryImageLayout() == VulkanLayout::UNDEFINED)) { -#ifndef NDEBUG +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) utils::slog.w << "Uninitialized texture bound to '" << sampler.name.c_str() << "'"; utils::slog.w << " in material '" << program->name.c_str() << "'"; utils::slog.w << " at binding point " << +sampler.binding << utils::io::endl; @@ -1687,6 +1713,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r const uint32_t firstInstId = 0; vkCmdDrawIndexed(cmdbuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstId); + FVK_SYSTRACE_END(); } void VulkanDriver::dispatchCompute(Handle program, math::uint3 workGroupCount) { diff --git a/filament/backend/src/vulkan/VulkanFboCache.cpp b/filament/backend/src/vulkan/VulkanFboCache.cpp index 1943dce87a..0546ffd04f 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.cpp +++ b/filament/backend/src/vulkan/VulkanFboCache.cpp @@ -23,7 +23,7 @@ // If any VkRenderPass or VkFramebuffer is unused for more than TIME_BEFORE_EVICTION frames, it // is evicted from the cache. -static constexpr uint32_t TIME_BEFORE_EVICTION = VK_MAX_COMMAND_BUFFERS; +static constexpr uint32_t TIME_BEFORE_EVICTION = FVK_MAX_COMMAND_BUFFERS; using namespace bluevk; @@ -97,7 +97,7 @@ VkFramebuffer VulkanFboCache::getFramebuffer(FboKey config) noexcept { attachments[attachmentCount++] = config.depth; } - #if FILAMENT_VULKAN_VERBOSE + #if FVK_ENABLED(FVK_DEBUG_FBO_CACHE) utils::slog.d << "Creating framebuffer " << config.width << "x" << config.height << " " << "for render pass " << config.renderPass << ", " << "samples = " << int(config.samples) << ", " @@ -312,7 +312,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept { ASSERT_POSTCONDITION(!error, "Unable to create render pass."); mRenderPassCache[config] = {renderPass, mCurrentTime}; - #if FILAMENT_VULKAN_VERBOSE + #if FVK_ENABLED(FVK_DEBUG_FBO_CACHE) utils::slog.d << "Created render pass " << renderPass << " with " << "samples = " << int(config.samples) << ", " << "depth = " << (hasDepth ? 1 : 0) << ", " @@ -338,6 +338,9 @@ void VulkanFboCache::reset() noexcept { // Frees up old framebuffers and render passes, then nulls out their key. Doesn't bother removing // the actual map entry since it is fairly small. void VulkanFboCache::gc() noexcept { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("fbocache::gc"); + // If this is one of the first few frames, return early to avoid wrapping unsigned integers. if (++mCurrentTime <= TIME_BEFORE_EVICTION) { return; @@ -359,6 +362,7 @@ void VulkanFboCache::gc() noexcept { iter.value().handle = VK_NULL_HANDLE; } } + FVK_SYSTRACE_END(); } } // namespace filament::backend diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 3d8d5b6da9..5ab3365d02 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -114,10 +114,10 @@ VulkanProgram::VulkanProgram(VkDevice device, const Program& builder) noexcept // Make a copy of the binding map samplerGroupInfo = builder.getSamplerGroupInfo(); - if constexpr (FILAMENT_VULKAN_VERBOSE) { + #if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE) utils::slog.d << "Created VulkanProgram " << builder << ", shaders = (" << bundle.vertex << ", " << bundle.fragment << ")" << utils::io::endl; - } + #endif } VulkanProgram::VulkanProgram(VkDevice device, VkShaderModule vs, VkShaderModule fs) noexcept diff --git a/filament/backend/src/vulkan/VulkanImageUtility.cpp b/filament/backend/src/vulkan/VulkanImageUtility.cpp index 5615b889e7..186771778c 100644 --- a/filament/backend/src/vulkan/VulkanImageUtility.cpp +++ b/filament/backend/src/vulkan/VulkanImageUtility.cpp @@ -218,7 +218,7 @@ bool operator<(const VkImageSubresourceRange& a, const VkImageSubresourceRange& return false; } -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION | FVK_DEBUG_TEXTURE) #define CASE(VALUE) \ case filament::backend::VulkanLayout::VALUE: { \ out << #VALUE; \ diff --git a/filament/backend/src/vulkan/VulkanPipelineCache.cpp b/filament/backend/src/vulkan/VulkanPipelineCache.cpp index e69cfae9a5..233bef3a32 100644 --- a/filament/backend/src/vulkan/VulkanPipelineCache.cpp +++ b/filament/backend/src/vulkan/VulkanPipelineCache.cpp @@ -481,10 +481,10 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::createPipeline() n PipelineCacheEntry cacheEntry = {}; - if constexpr (FILAMENT_VULKAN_VERBOSE) { + #if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE) utils::slog.d << "vkCreateGraphicsPipelines with shaders = (" << shaderStages[0].module << ", " << shaderStages[1].module << ")" << utils::io::endl; - } + #endif VkResult error = vkCreateGraphicsPipelines(mDevice, VK_NULL_HANDLE, 1, &pipelineCreateInfo, VKALLOC, &cacheEntry.handle); assert_invariant(error == VK_SUCCESS); @@ -681,7 +681,7 @@ void VulkanPipelineCache::terminate() noexcept { void VulkanPipelineCache::onCommandBuffer(const VulkanCommandBuffer& commands) { // The timestamp associated with a given cache entry represents "time" as a count of flush // events since the cache was constructed. If any cache entry was most recently used over - // VK_MAX_PIPELINE_AGE flush events in the past, then we can be sure that it is no longer + // FVK_MAX_PIPELINE_AGE flush events in the past, then we can be sure that it is no longer // being used by the GPU, and is therefore safe to destroy or reclaim. ++mCurrentTime; @@ -698,7 +698,7 @@ void VulkanPipelineCache::onCommandBuffer(const VulkanCommandBuffer& commands) { using ConstDescIterator = decltype(mDescriptorSets)::const_iterator; for (ConstDescIterator iter = mDescriptorSets.begin(); iter != mDescriptorSets.end();) { const DescriptorCacheEntry& cacheEntry = iter.value(); - if (cacheEntry.lastUsed + VK_MAX_PIPELINE_AGE < mCurrentTime) { + if (cacheEntry.lastUsed + FVK_MAX_PIPELINE_AGE < mCurrentTime) { auto& arenas = mPipelineLayouts[cacheEntry.pipelineLayout].descriptorSetArenas; for (uint32_t i = 0; i < DESCRIPTOR_TYPE_COUNT; ++i) { arenas[i].push_back(cacheEntry.handles[i]); @@ -712,11 +712,11 @@ void VulkanPipelineCache::onCommandBuffer(const VulkanCommandBuffer& commands) { } // Evict any pipelines that have not been used in a while. - // Any pipeline older than VK_MAX_COMMAND_BUFFERS can be safely destroyed. + // Any pipeline older than FVK_MAX_COMMAND_BUFFERS can be safely destroyed. using ConstPipeIterator = decltype(mPipelines)::const_iterator; for (ConstPipeIterator iter = mPipelines.begin(); iter != mPipelines.end();) { const PipelineCacheEntry& cacheEntry = iter.value(); - if (cacheEntry.lastUsed + VK_MAX_PIPELINE_AGE < mCurrentTime) { + if (cacheEntry.lastUsed + FVK_MAX_PIPELINE_AGE < mCurrentTime) { vkDestroyPipeline(mDevice, iter->second.handle, VKALLOC); iter = mPipelines.erase(iter); } else { @@ -728,15 +728,15 @@ void VulkanPipelineCache::onCommandBuffer(const VulkanCommandBuffer& commands) { using ConstLayoutIterator = decltype(mPipelineLayouts)::const_iterator; for (ConstLayoutIterator iter = mPipelineLayouts.begin(); iter != mPipelineLayouts.end();) { const PipelineLayoutCacheEntry& cacheEntry = iter.value(); - if (cacheEntry.lastUsed + VK_MAX_PIPELINE_AGE < mCurrentTime) { + if (cacheEntry.lastUsed + FVK_MAX_PIPELINE_AGE < mCurrentTime) { vkDestroyPipelineLayout(mDevice, iter->second.handle, VKALLOC); for (auto setLayout : iter->second.descriptorSetLayouts) { -#ifndef NDEBUG + #if FVK_ENABLED(FVK_DEBUG_PIPELINE_CACHE) PipelineLayoutKey key = iter.key(); for (auto& pair : mDescriptorSets) { assert_invariant(pair.second.pipelineLayout != key); } -#endif + #endif vkDestroyDescriptorSetLayout(mDevice, setLayout, VKALLOC); } auto& arenas = iter->second.descriptorSetArenas; @@ -755,7 +755,7 @@ void VulkanPipelineCache::onCommandBuffer(const VulkanCommandBuffer& commands) { // destroy the extinct pools, which implicitly frees their associated descriptor sets. bool canPurgeExtinctPools = true; for (auto& bundle : mExtinctDescriptorBundles) { - if (bundle.lastUsed + VK_MAX_PIPELINE_AGE >= mCurrentTime) { + if (bundle.lastUsed + FVK_MAX_PIPELINE_AGE >= mCurrentTime) { canPurgeExtinctPools = false; break; } @@ -799,7 +799,7 @@ VkDescriptorPool VulkanPipelineCache::createDescriptorPool(uint32_t size) const void VulkanPipelineCache::destroyLayoutsAndDescriptors() noexcept { // Our current descriptor set strategy can cause the # of descriptor sets to explode in certain // situations, so it's interesting to report the number that get stuffed into the cache. - #ifndef NDEBUG + #if FVK_ENABLED(FVK_DEBUG_PIPELINE_CACHE) utils::slog.d << "Destroying " << mDescriptorSets.size() << " bundles of descriptor sets." << utils::io::endl; #endif @@ -808,7 +808,7 @@ void VulkanPipelineCache::destroyLayoutsAndDescriptors() noexcept { // Our current layout bundle strategy can cause the # of layout bundles to explode in certain // situations, so it's interesting to report the number that get stuffed into the cache. - #ifndef NDEBUG + #if FVK_ENABLED(FVK_DEBUG_PIPELINE_CACHE) utils::slog.d << "Destroying " << mPipelineLayouts.size() << " pipeline layouts." << utils::io::endl; #endif diff --git a/filament/backend/src/vulkan/VulkanPipelineCache.h b/filament/backend/src/vulkan/VulkanPipelineCache.h index a54e6bccd1..2c9bf09350 100644 --- a/filament/backend/src/vulkan/VulkanPipelineCache.h +++ b/filament/backend/src/vulkan/VulkanPipelineCache.h @@ -340,7 +340,7 @@ private: // The timestamp associated with a given cache entry represents time as a count of flush // events since the cache was constructed. If any cache entry was most recently used over - // VK_MAX_PIPELINE_AGE flushes in the past, then we can be sure that it is no longer + // FVK_MAX_PIPELINE_AGE flushes in the past, then we can be sure that it is no longer // being used by the GPU, and is therefore safe to destroy or reclaim. using Timestamp = uint64_t; Timestamp mCurrentTime = 0; diff --git a/filament/backend/src/vulkan/VulkanReadPixels.cpp b/filament/backend/src/vulkan/VulkanReadPixels.cpp index fd51344b83..83e341c276 100644 --- a/filament/backend/src/vulkan/VulkanReadPixels.cpp +++ b/filament/backend/src/vulkan/VulkanReadPixels.cpp @@ -167,7 +167,7 @@ void VulkanReadPixels::run(VulkanRenderTarget const* srcTarget, uint32_t const x VkImage stagingImage; vkCreateImage(device, &imageInfo, VKALLOC, &stagingImage); -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_READ_PIXELS) utils::slog.d << "readPixels created image=" << stagingImage << " to copy from image=" << srcTexture->getVkImage() << " src-layout=" << srcTexture->getLayout(0, 0) << utils::io::endl; diff --git a/filament/backend/src/vulkan/VulkanStagePool.cpp b/filament/backend/src/vulkan/VulkanStagePool.cpp index a8934d242b..93f434d4af 100644 --- a/filament/backend/src/vulkan/VulkanStagePool.cpp +++ b/filament/backend/src/vulkan/VulkanStagePool.cpp @@ -22,7 +22,7 @@ #include -static constexpr uint32_t TIME_BEFORE_EVICTION = VK_MAX_COMMAND_BUFFERS; +static constexpr uint32_t TIME_BEFORE_EVICTION = FVK_MAX_COMMAND_BUFFERS; namespace filament::backend { @@ -59,7 +59,7 @@ VulkanStage const* VulkanStagePool::acquireStage(uint32_t numBytes) { UTILS_UNUSED_IN_RELEASE VkResult result = vmaCreateBuffer(mAllocator, &bufferInfo, &allocInfo, &stage->buffer, &stage->memory, nullptr); -#ifndef NDEBUG +#if FVK_ENABLED(FVK_DEBUG_ALLOCATION) if (result != VK_SUCCESS) { utils::slog.e << "Allocation error: " << result << utils::io::endl; } @@ -129,6 +129,9 @@ VulkanStageImage const* VulkanStagePool::acquireImage(PixelDataFormat format, Pi } void VulkanStagePool::gc() noexcept { + FVK_SYSTRACE_CONTEXT(); + FVK_SYSTRACE_START("stagepool::gc"); + // If this is one of the first few frames, return early to avoid wrapping unsigned integers. if (++mCurrentFrame <= TIME_BEFORE_EVICTION) { return; @@ -182,6 +185,7 @@ void VulkanStagePool::gc() noexcept { mUsedImages.insert(image); } } + FVK_SYSTRACE_END(); } void VulkanStagePool::terminate() noexcept { diff --git a/filament/backend/src/vulkan/VulkanTexture.cpp b/filament/backend/src/vulkan/VulkanTexture.cpp index 140c697f87..c40f6f779c 100644 --- a/filament/backend/src/vulkan/VulkanTexture.cpp +++ b/filament/backend/src/vulkan/VulkanTexture.cpp @@ -106,7 +106,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, if (any(usage & TextureUsage::SAMPLEABLE)) { -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) // Validate that the format is actually sampleable. VkFormatProperties props; vkGetPhysicalDeviceFormatProperties(physicalDevice, mVkFormat, &props); @@ -160,7 +160,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, imageInfo.samples = (VkSampleCountFlagBits) samples; VkResult error = vkCreateImage(mDevice, &imageInfo, VKALLOC, &mTextureImage); - if (error || FILAMENT_VULKAN_VERBOSE) { + if (error || FVK_ENABLED_BOOL(FVK_DEBUG_TEXTURE)) { utils::slog.d << "vkCreateImage: " << "image = " << mTextureImage << ", " << "result = " << error << ", " @@ -417,7 +417,7 @@ void VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, const VkImageSubres VulkanLayout newLayout) { VulkanLayout oldLayout = getLayout(range.baseArrayLayer, range.baseMipLevel); - #if FILAMENT_VULKAN_VERBOSE + #if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION) utils::slog.i << "transition layout of " << mTextureImage << ",layer=" << range.baseArrayLayer << ",level=" << range.baseMipLevel << " from=" << oldLayout << " to=" << newLayout << " format=" << mVkFormat @@ -463,7 +463,7 @@ VulkanLayout VulkanTexture::getLayout(uint32_t layer, uint32_t level) const { return mSubresourceLayouts.get(key); } -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) void VulkanTexture::print() const { const uint32_t firstLayer = 0; const uint32_t lastLayer = firstLayer + mPrimaryViewRange.layerCount; diff --git a/filament/backend/src/vulkan/VulkanTexture.h b/filament/backend/src/vulkan/VulkanTexture.h index b4b71a9065..d3a84067c8 100644 --- a/filament/backend/src/vulkan/VulkanTexture.h +++ b/filament/backend/src/vulkan/VulkanTexture.h @@ -84,7 +84,7 @@ struct VulkanTexture : public HwTexture, VulkanResource { // For now this always returns either DEPTH or COLOR. VkImageAspectFlags getImageAspect() const; -#if FILAMENT_VULKAN_VERBOSE +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) void print() const; #endif diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index 23c513734c..153946a3f8 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -45,11 +45,11 @@ constexpr uint32_t const INVALID_VK_INDEX = 0xFFFFFFFF; typedef std::unordered_set ExtensionSet; -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) // These strings need to be allocated outside a function stack const std::string_view DESIRED_LAYERS[] = { "VK_LAYER_KHRONOS_validation", -#if FILAMENT_VULKAN_DUMP_API +#if FVK_ENABLED(FVK_DEBUG_DUMP_API) "VK_LAYER_LUNARG_api_dump", #endif #if defined(ENABLE_RENDERDOC) @@ -75,7 +75,7 @@ FixedCapacityVector getEnabledLayers() { } return enabledLayers; } -#endif +#endif // FVK_EANBLED(FVK_DEBUG_VALIDATION) void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) { // Print some driver or MoltenVK information if it is available. @@ -129,27 +129,27 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) { << minor << ")" << utils::io::endl; } +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) void printDepthFormats(VkPhysicalDevice device) { // For diagnostic purposes, print useful information about available depth formats. // Note that Vulkan is more constrained than OpenGL ES 3.1 in this area. - if constexpr (VK_ENABLE_VALIDATION && FILAMENT_VULKAN_VERBOSE) { - const VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT + const VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; - utils::slog.i << "Sampleable depth formats: "; - for (VkFormat format = (VkFormat) 1;;) { - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(device, format, &props); - if ((props.optimalTilingFeatures & required) == required) { - utils::slog.i << format << " "; - } - if (format == VK_FORMAT_ASTC_12x12_SRGB_BLOCK) { - utils::slog.i << utils::io::endl; - break; - } - format = (VkFormat) (1 + (int) format); + utils::slog.i << "Sampleable depth formats: "; + for (VkFormat format = (VkFormat) 1;;) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(device, format, &props); + if ((props.optimalTilingFeatures & required) == required) { + utils::slog.i << format << " "; } + if (format == VK_FORMAT_ASTC_12x12_SRGB_BLOCK) { + utils::slog.i << utils::io::endl; + break; + } + format = (VkFormat) (1 + (int) format); } } +#endif ExtensionSet getInstanceExtensions() { std::string_view const TARGET_EXTS[] = { @@ -161,7 +161,7 @@ ExtensionSet getInstanceExtensions() { VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) VK_EXT_DEBUG_REPORT_EXTENSION_NAME, #endif }; @@ -207,7 +207,7 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { VkInstanceCreateInfo instanceCreateInfo = {}; bool validationFeaturesSupported = false; -#if VK_ENABLE_VALIDATION +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) auto const enabledLayers = getEnabledLayers(); if (!enabledLayers.empty()) { // If layers are supported, Check if VK_EXT_validation_features is supported. @@ -229,9 +229,10 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { #else utils::slog.d << "Validation layer not available; did you install the Vulkan SDK?\n" << "Please ensure that VK_LAYER_PATH is set correctly." << utils::io::endl; -#endif +#endif // __ANDROID__ + } -#endif// VK_ENABLE_VALIDATION +#endif // FVK_ENABLED(FVK_DEBUG_VALIDATION) // The Platform class can require 1 or 2 instance extensions, plus we'll request at most 5 // instance extensions here in the common code. So that's a max of 7. @@ -252,7 +253,7 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { VkApplicationInfo appInfo = {}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.apiVersion - = VK_MAKE_API_VERSION(0, VK_REQUIRED_VERSION_MAJOR, VK_REQUIRED_VERSION_MINOR, 0); + = VK_MAKE_API_VERSION(0, FVK_REQUIRED_VERSION_MAJOR, FVK_REQUIRED_VERSION_MINOR, 0); instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.pApplicationInfo = &appInfo; instanceCreateInfo.enabledExtensionCount = enabledExtensionCount; @@ -274,12 +275,8 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { } VkResult result = vkCreateInstance(&instanceCreateInfo, VKALLOC, &instance); -#ifndef NDEBUG - if (result != VK_SUCCESS) { - utils::slog.e << "Unable to create instance: " << result << utils::io::endl; - } -#endif - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create Vulkan instance."); + ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create Vulkan instance. Result=%d", + result); return instance; } @@ -443,10 +440,10 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, int const minor = VK_VERSION_MINOR(targetDeviceProperties.apiVersion); // Does the device support the required Vulkan level? - if (major < VK_REQUIRED_VERSION_MAJOR) { + if (major < FVK_REQUIRED_VERSION_MAJOR) { continue; } - if (major == VK_REQUIRED_VERSION_MAJOR && minor < VK_REQUIRED_VERSION_MINOR) { + if (major == FVK_REQUIRED_VERSION_MAJOR && minor < FVK_REQUIRED_VERSION_MINOR) { continue; } @@ -667,7 +664,9 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, // just yet, since that would require a corollary change to the "aspect" flags for the VkImage. context.mDepthFormat = findSupportedFormat(mImpl->mPhysicalDevice); +#if FVK_ENABLED(FVK_DEBUG_VALIDATION) printDepthFormats(mImpl->mPhysicalDevice); +#endif // Keep a copy of context for swapchains. mImpl->mContext = context;