diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be7240d38..a0e760f7a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ option(IGL_WITH_TRACY "Enable Tracy profiler" ON) option(IGL_DEPLOY_DEPS "Deploy dependencies via CMake" ON) # cmake-format: on +include(cmake/CommonMacros.txt) + if(DEFINED ENV{VULKAN_SDK}) message(STATUS "VULKAN_SDK=$ENV{VULKAN_SDK}") if(NOT EXISTS $ENV{VULKAN_SDK}) @@ -73,6 +75,9 @@ if(IGL_WITH_TRACY) igl_set_folder(TracyClient "third-party") endif() +# temporary +find_package(Vulkan REQUIRED) + include_directories(.) add_subdirectory(src/igl) diff --git a/cmake/CommonMacros.txt b/cmake/CommonMacros.txt new file mode 100644 index 0000000000..995f2fd835 --- /dev/null +++ b/cmake/CommonMacros.txt @@ -0,0 +1,26 @@ +# +# based on https://github.com/PacktPublishing/3D-Graphics-Rendering-Cookbook/blob/master/CMake/CommonMacros.txt +# + +cmake_minimum_required(VERSION 3.16) + +macro(lvk_setup_groups src_files) + foreach(FILE ${src_files}) + get_filename_component(PARENT_DIR "${FILE}" PATH) + + # skip src or include and changes /'s to \\'s + set(GROUP "${PARENT_DIR}") + string(REPLACE "/" "\\" GROUP "${GROUP}") + + source_group("${GROUP}" FILES "${FILE}") + endforeach() +endmacro() + +macro(lvk_set_folder target folder_name) + set_property(TARGET ${target} PROPERTY FOLDER ${folder_name}) +endmacro() + +macro(lvk_setup_target target) + set_property(TARGET ${target} PROPERTY CXX_STANDARD 20) + set_property(TARGET ${target} PROPERTY CXX_STANDARD_REQUIRED ON) +endmacro() diff --git a/lvk/CMakeLists.txt b/lvk/CMakeLists.txt index bb2b0c1ed3..cf85755e04 100644 --- a/lvk/CMakeLists.txt +++ b/lvk/CMakeLists.txt @@ -12,10 +12,13 @@ file(GLOB HEADER_FILES LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DI add_library(LVKLibrary ${SRC_FILES} ${HEADER_FILES}) +lvk_setup_groups("${SRC_FILES}") +lvk_setup_groups("${HEADER_FILES}") + target_include_directories(LVKLibrary PUBLIC "${IGL_ROOT_DIR}/lvk") -igl_set_cxxstd(LVKLibrary 20) -igl_set_folder(LVKLibrary "LVK") +lvk_setup_target(LVKLibrary) +lvk_set_folder(LVKLibrary "LVK") add_subdirectory(vulkan) diff --git a/lvk/LVK.h b/lvk/LVK.h index d6b9dbe9dd..ce5da5cec8 100644 --- a/lvk/LVK.h +++ b/lvk/LVK.h @@ -747,11 +747,15 @@ class IDevice { virtual std::shared_ptr getCurrentSwapchainTexture() = 0; - virtual ShaderStages createShaderStages(const char* vs, - const char* debugNameVS, - const char* fs, - const char* debugNameFS, - Result* outResult = nullptr); + ShaderStages createShaderStages(const char* vs, + const char* debugNameVS, + const char* fs, + const char* debugNameFS, + Result* outResult = nullptr) { + auto VS = createShaderModule(igl::ShaderModuleDesc(vs, Stage_Vertex, debugNameVS), outResult); + auto FS = createShaderModule(igl::ShaderModuleDesc(fs, Stage_Fragment, debugNameFS), outResult); + return igl::ShaderStages(VS, FS); + } protected: IDevice() = default; diff --git a/lvk/vulkan/CMakeLists.txt b/lvk/vulkan/CMakeLists.txt index 11f8492abf..4c0bd8b61d 100644 --- a/lvk/vulkan/CMakeLists.txt +++ b/lvk/vulkan/CMakeLists.txt @@ -12,12 +12,34 @@ file(GLOB HEADER_FILES LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DI add_library(LVKVulkan ${SRC_FILES} ${HEADER_FILES}) -igl_set_cxxstd(LVKVulkan 20) -igl_set_folder(LVKVulkan "LVK") +lvk_setup_target(LVKVulkan) +lvk_set_folder(LVKVulkan "LVK") + +lvk_setup_groups("${SRC_FILES}") +lvk_setup_groups("${HEADER_FILES}") + +# glslang +# cmake-format: off +set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "") +set(ENABLE_HLSL OFF CACHE BOOL "") +set(ENABLE_CTEST OFF CACHE BOOL "") +set(ENABLE_OPT OFF CACHE BOOL "") +set(ENABLE_SPVREMAPPER OFF CACHE BOOL "") +set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "") +add_subdirectory(${IGL_ROOT_DIR}/third-party/deps/src/glslang "glslang") +lvk_set_folder(GenericCodeGen "third-party/glslang") +lvk_set_folder(glslang "third-party/glslang") +lvk_set_folder(MachineIndependent "third-party/glslang") +lvk_set_folder(OGLCompiler "third-party/glslang") +lvk_set_folder(OSDependent "third-party/glslang") +lvk_set_folder(SPIRV "third-party/glslang") +lvk_set_folder(glslang-default-resource-limits "third-party/glslang") +# cmake-format: on find_package(Vulkan REQUIRED) target_link_libraries(LVKVulkan PRIVATE IGLLibrary) +target_link_libraries(LVKVulkan PUBLIC glslang SPIRV glslang-default-resource-limits) target_link_libraries(LVKVulkan PUBLIC Vulkan::Vulkan) target_include_directories(LVKVulkan PUBLIC "${IGL_ROOT_DIR}/third-party/deps/src/volk") diff --git a/lvk/vulkan/VulkanUtils.cpp b/lvk/vulkan/VulkanUtils.cpp index 67b3bdaffe..6bb9a7826a 100644 --- a/lvk/vulkan/VulkanUtils.cpp +++ b/lvk/vulkan/VulkanUtils.cpp @@ -10,6 +10,29 @@ #include #include +VkSemaphore lvk::createSemaphore(VkDevice device, const char* debugName) { + const VkSemaphoreCreateInfo ci = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .flags = 0, + }; + VkSemaphore semaphore = VK_NULL_HANDLE; + VK_ASSERT(vkCreateSemaphore(device, &ci, nullptr, &semaphore)); + VK_ASSERT( + ivkSetDebugObjectName(device, VK_OBJECT_TYPE_SEMAPHORE, (uint64_t)semaphore, debugName)); + return semaphore; +} + +VkFence lvk::createFence(VkDevice device, const char* debugName) { + const VkFenceCreateInfo ci = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .flags = 0, + }; + VkFence fence = VK_NULL_HANDLE; + VK_ASSERT(vkCreateFence(device, &ci, nullptr, &fence)); + VK_ASSERT(ivkSetDebugObjectName(device, VK_OBJECT_TYPE_FENCE, (uint64_t)fence, debugName)); + return fence; +} + uint32_t lvk::findQueueFamilyIndex(VkPhysicalDevice physDev, VkQueueFlags flags) { using igl::vulkan::DeviceQueues; @@ -97,3 +120,116 @@ VmaAllocator lvk::createVmaAllocator(VkPhysicalDevice physDev, VK_ASSERT(vmaCreateAllocator(&ci, &vma)); return vma; } + +glslang_resource_t lvk::getGlslangResource(const VkPhysicalDeviceLimits& limits) { + const glslang_resource_t resource = { + .max_lights = 32, + .max_clip_planes = 6, + .max_texture_units = 32, + .max_texture_coords = 32, + .max_vertex_attribs = (int)limits.maxVertexInputAttributes, + .max_vertex_uniform_components = 4096, + .max_varying_floats = 64, + .max_vertex_texture_image_units = 32, + .max_combined_texture_image_units = 80, + .max_texture_image_units = 32, + .max_fragment_uniform_components = 4096, + .max_draw_buffers = 32, + .max_vertex_uniform_vectors = 128, + .max_varying_vectors = 8, + .max_fragment_uniform_vectors = 16, + .max_vertex_output_vectors = 16, + .max_fragment_input_vectors = 15, + .min_program_texel_offset = -8, + .max_program_texel_offset = 7, + .max_clip_distances = (int)limits.maxClipDistances, + .max_compute_work_group_count_x = (int)limits.maxComputeWorkGroupCount[0], + .max_compute_work_group_count_y = (int)limits.maxComputeWorkGroupCount[1], + .max_compute_work_group_count_z = (int)limits.maxComputeWorkGroupCount[2], + .max_compute_work_group_size_x = (int)limits.maxComputeWorkGroupSize[0], + .max_compute_work_group_size_y = (int)limits.maxComputeWorkGroupSize[1], + .max_compute_work_group_size_z = (int)limits.maxComputeWorkGroupSize[2], + .max_compute_uniform_components = 1024, + .max_compute_texture_image_units = 16, + .max_compute_image_uniforms = 8, + .max_compute_atomic_counters = 8, + .max_compute_atomic_counter_buffers = 1, + .max_varying_components = 60, + .max_vertex_output_components = (int)limits.maxVertexOutputComponents, + .max_geometry_input_components = (int)limits.maxGeometryInputComponents, + .max_geometry_output_components = (int)limits.maxGeometryOutputComponents, + .max_fragment_input_components = (int)limits.maxFragmentInputComponents, + .max_image_units = 8, + .max_combined_image_units_and_fragment_outputs = 8, + .max_combined_shader_output_resources = 8, + .max_image_samples = 0, + .max_vertex_image_uniforms = 0, + .max_tess_control_image_uniforms = 0, + .max_tess_evaluation_image_uniforms = 0, + .max_geometry_image_uniforms = 0, + .max_fragment_image_uniforms = 8, + .max_combined_image_uniforms = 8, + .max_geometry_texture_image_units = 16, + .max_geometry_output_vertices = (int)limits.maxGeometryOutputVertices, + .max_geometry_total_output_components = (int)limits.maxGeometryTotalOutputComponents, + .max_geometry_uniform_components = 1024, + .max_geometry_varying_components = 64, + .max_tess_control_input_components = + (int)limits.maxTessellationControlPerVertexInputComponents, + .max_tess_control_output_components = + (int)limits.maxTessellationControlPerVertexOutputComponents, + .max_tess_control_texture_image_units = 16, + .max_tess_control_uniform_components = 1024, + .max_tess_control_total_output_components = 4096, + .max_tess_evaluation_input_components = (int)limits.maxTessellationEvaluationInputComponents, + .max_tess_evaluation_output_components = + (int)limits.maxTessellationEvaluationOutputComponents, + .max_tess_evaluation_texture_image_units = 16, + .max_tess_evaluation_uniform_components = 1024, + .max_tess_patch_components = 120, + .max_patch_vertices = 32, + .max_tess_gen_level = 64, + .max_viewports = (int)limits.maxViewports, + .max_vertex_atomic_counters = 0, + .max_tess_control_atomic_counters = 0, + .max_tess_evaluation_atomic_counters = 0, + .max_geometry_atomic_counters = 0, + .max_fragment_atomic_counters = 8, + .max_combined_atomic_counters = 8, + .max_atomic_counter_bindings = 1, + .max_vertex_atomic_counter_buffers = 0, + .max_tess_control_atomic_counter_buffers = 0, + .max_tess_evaluation_atomic_counter_buffers = 0, + .max_geometry_atomic_counter_buffers = 0, + .max_fragment_atomic_counter_buffers = 1, + .max_combined_atomic_counter_buffers = 1, + .max_atomic_counter_buffer_size = 16384, + .max_transform_feedback_buffers = 4, + .max_transform_feedback_interleaved_components = 64, + .max_cull_distances = (int)limits.maxCullDistances, + .max_combined_clip_and_cull_distances = (int)limits.maxCombinedClipAndCullDistances, + .max_samples = 4, + .max_mesh_output_vertices_nv = 256, + .max_mesh_output_primitives_nv = 512, + .max_mesh_work_group_size_x_nv = 32, + .max_mesh_work_group_size_y_nv = 1, + .max_mesh_work_group_size_z_nv = 1, + .max_task_work_group_size_x_nv = 32, + .max_task_work_group_size_y_nv = 1, + .max_task_work_group_size_z_nv = 1, + .max_mesh_view_count_nv = 4, + .maxDualSourceDrawBuffersEXT = 1, + .limits = { + .non_inductive_for_loops = true, + .while_loops = true, + .do_while_loops = true, + .general_uniform_indexing = true, + .general_attribute_matrix_vector_indexing = true, + .general_varying_indexing = true, + .general_sampler_indexing = true, + .general_variable_indexing = true, + .general_constant_matrix_vector_indexing = true, + }}; + + return resource; +} diff --git a/lvk/vulkan/VulkanUtils.h b/lvk/vulkan/VulkanUtils.h index 8f6a017f8e..a14031016c 100644 --- a/lvk/vulkan/VulkanUtils.h +++ b/lvk/vulkan/VulkanUtils.h @@ -17,13 +17,18 @@ #include #include +#include namespace lvk { +VkSemaphore createSemaphore(VkDevice device, const char* debugName); +VkFence createFence(VkDevice device, const char* debugName); VmaAllocator createVmaAllocator(VkPhysicalDevice physDev, VkDevice device, VkInstance instance, uint32_t apiVersion); uint32_t findQueueFamilyIndex(VkPhysicalDevice physDev, VkQueueFlags flags); +glslang_resource_t getGlslangResource(const VkPhysicalDeviceLimits& limits); + } // namespace lvk diff --git a/src/igl/IGL.cpp b/src/igl/IGL.cpp index 50e7aa75c5..a46abad123 100644 --- a/src/igl/IGL.cpp +++ b/src/igl/IGL.cpp @@ -155,14 +155,4 @@ uint32_t calcNumMipLevels(uint32_t width, uint32_t height) { return levels; } -ShaderStages IDevice::createShaderStages(const char* vs, - const char* debugNameVS, - const char* fs, - const char* debugNameFS, - Result* outResult) { - auto VS = createShaderModule(igl::ShaderModuleDesc(vs, Stage_Vertex, debugNameVS), outResult); - auto FS = createShaderModule(igl::ShaderModuleDesc(fs, Stage_Fragment, debugNameFS), outResult); - return igl::ShaderStages(VS, FS); -} - } // namespace igl diff --git a/src/igl/vulkan/CMakeLists.txt b/src/igl/vulkan/CMakeLists.txt index c33d843f38..989abaaf33 100644 --- a/src/igl/vulkan/CMakeLists.txt +++ b/src/igl/vulkan/CMakeLists.txt @@ -16,26 +16,6 @@ add_library(IGLVulkan ${SRC_FILES} ${HEADER_FILES}) igl_set_cxxstd(IGLVulkan 20) igl_set_folder(IGLVulkan "IGL") -# glslang -# cmake-format: off -set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "") -set(ENABLE_HLSL OFF CACHE BOOL "") -set(ENABLE_CTEST OFF CACHE BOOL "") -set(ENABLE_OPT OFF CACHE BOOL "") -set(ENABLE_SPVREMAPPER OFF CACHE BOOL "") -set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "") -add_subdirectory(${IGL_ROOT_DIR}/third-party/deps/src/glslang "glslang") -igl_set_folder(GenericCodeGen "third-party/glslang") -igl_set_folder(glslang "third-party/glslang") -igl_set_folder(MachineIndependent "third-party/glslang") -igl_set_folder(OGLCompiler "third-party/glslang") -igl_set_folder(OSDependent "third-party/glslang") -igl_set_folder(SPIRV "third-party/glslang") -igl_set_folder(glslang-default-resource-limits "third-party/glslang") -# cmake-format: on - -find_package(Vulkan REQUIRED) - target_link_libraries(IGLVulkan PRIVATE IGLLibrary) target_link_libraries(IGLVulkan PUBLIC glslang SPIRV glslang-default-resource-limits) target_link_libraries(IGLVulkan PUBLIC Vulkan::Vulkan) @@ -43,6 +23,9 @@ target_link_libraries(IGLVulkan PUBLIC Vulkan::Vulkan) target_include_directories(IGLVulkan PUBLIC "${IGL_ROOT_DIR}/third-party/deps/src/volk") target_include_directories(IGLVulkan PUBLIC "${IGL_ROOT_DIR}/third-party/deps/src/vma/include") +target_link_libraries(IGLVulkan PRIVATE LVKLibrary) +target_link_libraries(IGLVulkan PRIVATE LVKVulkan) + if(WIN32) add_definitions("-DVK_USE_PLATFORM_WIN32_KHR=1") add_definitions("-DNOMINMAX") diff --git a/src/igl/vulkan/Device.cpp b/src/igl/vulkan/Device.cpp index 9d272c5209..73f2e1b255 100644 --- a/src/igl/vulkan/Device.cpp +++ b/src/igl/vulkan/Device.cpp @@ -90,7 +90,7 @@ void Device::submit(const igl::ICommandBuffer& commandBuffer, // Submit to the graphics queue. const bool shouldPresent = isGraphicsQueue && ctx.hasSwapchain() && present; if (shouldPresent) { - ctx.immediate_->waitSemaphore(ctx.swapchain_->acquireSemaphore_->vkSemaphore_); + ctx.immediate_->waitSemaphore(ctx.swapchain_->acquireSemaphore_); } vkCmdBuffer->lastSubmitHandle_ = ctx.immediate_->submit(vkCmdBuffer->wrapper_); @@ -293,8 +293,8 @@ std::shared_ptr Device::createShaderModule(ShaderStage stage source = sourcePatched.c_str(); } - glslang_resource_t glslangResource; - ivkGlslangResource(&glslangResource, &ctx_->getVkPhysicalDeviceProperties()); + const glslang_resource_t glslangResource = + lvk::getGlslangResource(ctx_->getVkPhysicalDeviceProperties().limits); VkShaderModule vkShaderModule = VK_NULL_HANDLE; const Result result = diff --git a/src/igl/vulkan/Device.h b/src/igl/vulkan/Device.h index bc2f6ef975..9897d6b453 100644 --- a/src/igl/vulkan/Device.h +++ b/src/igl/vulkan/Device.h @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/src/igl/vulkan/VulkanContext.cpp b/src/igl/vulkan/VulkanContext.cpp index 7f2811e6b3..98af895361 100644 --- a/src/igl/vulkan/VulkanContext.cpp +++ b/src/igl/vulkan/VulkanContext.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -530,9 +529,8 @@ igl::Result VulkanContext::initContext(const HWDeviceDesc& desc) { // Create Vulkan Memory Allocator if (IGL_VULKAN_USE_VMA) { - pimpl_->vma_ = - lvk::createVmaAllocator(vkPhysicalDevice_, vkDevice_, vkInstance_, apiVersion); - IGL_ASSERT(pimpl_->vma_ != VK_NULL_HANDLE); + pimpl_->vma_ = lvk::createVmaAllocator(vkPhysicalDevice_, vkDevice_, vkInstance_, apiVersion); + IGL_ASSERT(pimpl_->vma_ != VK_NULL_HANDLE); } // The staging device will use VMA to allocate a buffer, so this needs diff --git a/src/igl/vulkan/VulkanContext.h b/src/igl/vulkan/VulkanContext.h index ec8b80616b..8220b337da 100644 --- a/src/igl/vulkan/VulkanContext.h +++ b/src/igl/vulkan/VulkanContext.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace igl { namespace vulkan { @@ -30,7 +31,6 @@ class VulkanImage; class VulkanImageView; class VulkanPipelineLayout; class VulkanSampler; -class VulkanSemaphore; class VulkanSwapchain; class VulkanTexture; diff --git a/src/igl/vulkan/VulkanFence.cpp b/src/igl/vulkan/VulkanFence.cpp deleted file mode 100644 index d6a1728c26..0000000000 --- a/src/igl/vulkan/VulkanFence.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "VulkanFence.h" - -#include -#include // std::swap - -namespace igl { -namespace vulkan { - -VulkanFence::VulkanFence(VkDevice device, VkFlags flags, const char* debugName) : device_(device) { - IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_CREATE); - - const VkFenceCreateInfo ci = { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .flags = flags, - }; - VK_ASSERT(vkCreateFence(device_, &ci, nullptr, &vkFence_)); - VK_ASSERT(ivkSetDebugObjectName(device_, VK_OBJECT_TYPE_FENCE, (uint64_t)vkFence_, debugName)); -} - -VulkanFence ::~VulkanFence() { - IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_DESTROY); - - if (device_ != VK_NULL_HANDLE) { - // lifetimes of all VkFence objects are managed explicitly - // we do not use deferredTask() for them - vkDestroyFence(device_, vkFence_, nullptr); - } -} - -VulkanFence::VulkanFence(VulkanFence&& other) noexcept { - std::swap(device_, other.device_); - std::swap(vkFence_, other.vkFence_); -} - -VulkanFence& VulkanFence::operator=(VulkanFence&& other) noexcept { - VulkanFence tmp(std::move(other)); - std::swap(device_, tmp.device_); - std::swap(vkFence_, tmp.vkFence_); - return *this; -} - -} // namespace vulkan -} // namespace igl diff --git a/src/igl/vulkan/VulkanFence.h b/src/igl/vulkan/VulkanFence.h deleted file mode 100644 index f128bb8f4d..0000000000 --- a/src/igl/vulkan/VulkanFence.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include -#include - -namespace igl { -namespace vulkan { - -/** - * @brief Fences are used to synchronize CPU-GPU tasks. The VulkanFence class encapsulates the - * creation and destruction of a vulkan fence object (VkFence). It stores an opaque handle for a - * newly created fence object and for a device object. - */ -class VulkanFence final { - public: - VulkanFence(VkDevice device, VkFlags flags, const char* debugName = nullptr); - ~VulkanFence(); - - VulkanFence(VulkanFence&& other) noexcept; - VulkanFence& operator=(VulkanFence&& other) noexcept; - - VulkanFence(const VulkanFence&) = delete; - VulkanFence operator=(const VulkanFence&) = delete; - - public: - VkDevice device_ = VK_NULL_HANDLE; - VkFence vkFence_ = VK_NULL_HANDLE; -}; - -} // namespace vulkan -} // namespace igl diff --git a/src/igl/vulkan/VulkanHelpers.c b/src/igl/vulkan/VulkanHelpers.c index 98e1339eb5..e84b8d7c4b 100644 --- a/src/igl/vulkan/VulkanHelpers.c +++ b/src/igl/vulkan/VulkanHelpers.c @@ -912,122 +912,3 @@ VkImageCopy ivkGetImageCopy2D(VkOffset2D srcDstOffset, }; return copy; } - -void ivkGlslangResource(glslang_resource_t* glslangResource, - const VkPhysicalDeviceProperties* deviceProperties) { - const VkPhysicalDeviceLimits* limits = deviceProperties ? &deviceProperties->limits : NULL; - - const glslang_resource_t resource = { - .max_lights = 32, - .max_clip_planes = 6, - .max_texture_units = 32, - .max_texture_coords = 32, - .max_vertex_attribs = limits ? (int)limits->maxVertexInputAttributes : 64, - .max_vertex_uniform_components = 4096, - .max_varying_floats = 64, - .max_vertex_texture_image_units = 32, - .max_combined_texture_image_units = 80, - .max_texture_image_units = 32, - .max_fragment_uniform_components = 4096, - .max_draw_buffers = 32, - .max_vertex_uniform_vectors = 128, - .max_varying_vectors = 8, - .max_fragment_uniform_vectors = 16, - .max_vertex_output_vectors = 16, - .max_fragment_input_vectors = 15, - .min_program_texel_offset = -8, - .max_program_texel_offset = 7, - .max_clip_distances = limits ? (int)limits->maxClipDistances : 8, - .max_compute_work_group_count_x = limits ? (int)limits->maxComputeWorkGroupCount[0] : 65535, - .max_compute_work_group_count_y = limits ? (int)limits->maxComputeWorkGroupCount[1] : 65535, - .max_compute_work_group_count_z = limits ? (int)limits->maxComputeWorkGroupCount[2] : 65535, - .max_compute_work_group_size_x = limits ? (int)limits->maxComputeWorkGroupSize[0] : 1024, - .max_compute_work_group_size_y = limits ? (int)limits->maxComputeWorkGroupSize[1] : 1024, - .max_compute_work_group_size_z = limits ? (int)limits->maxComputeWorkGroupSize[2] : 64, - .max_compute_uniform_components = 1024, - .max_compute_texture_image_units = 16, - .max_compute_image_uniforms = 8, - .max_compute_atomic_counters = 8, - .max_compute_atomic_counter_buffers = 1, - .max_varying_components = 60, - .max_vertex_output_components = limits ? (int)limits->maxVertexOutputComponents : 64, - .max_geometry_input_components = limits ? (int)limits->maxGeometryInputComponents : 64, - .max_geometry_output_components = limits ? (int)limits->maxGeometryOutputComponents : 128, - .max_fragment_input_components = limits ? (int)limits->maxFragmentInputComponents : 128, - .max_image_units = 8, - .max_combined_image_units_and_fragment_outputs = 8, - .max_combined_shader_output_resources = 8, - .max_image_samples = 0, - .max_vertex_image_uniforms = 0, - .max_tess_control_image_uniforms = 0, - .max_tess_evaluation_image_uniforms = 0, - .max_geometry_image_uniforms = 0, - .max_fragment_image_uniforms = 8, - .max_combined_image_uniforms = 8, - .max_geometry_texture_image_units = 16, - .max_geometry_output_vertices = limits ? (int)limits->maxGeometryOutputVertices : 256, - .max_geometry_total_output_components = limits ? (int)limits->maxGeometryTotalOutputComponents - : 1024, - .max_geometry_uniform_components = 1024, - .max_geometry_varying_components = 64, - .max_tess_control_input_components = - limits ? (int)limits->maxTessellationControlPerVertexInputComponents : 128, - .max_tess_control_output_components = - limits ? (int)limits->maxTessellationControlPerVertexOutputComponents : 128, - .max_tess_control_texture_image_units = 16, - .max_tess_control_uniform_components = 1024, - .max_tess_control_total_output_components = 4096, - .max_tess_evaluation_input_components = - limits ? (int)limits->maxTessellationEvaluationInputComponents : 128, - .max_tess_evaluation_output_components = - limits ? (int)limits->maxTessellationEvaluationOutputComponents : 128, - .max_tess_evaluation_texture_image_units = 16, - .max_tess_evaluation_uniform_components = 1024, - .max_tess_patch_components = 120, - .max_patch_vertices = 32, - .max_tess_gen_level = 64, - .max_viewports = limits ? (int)limits->maxViewports : 16, - .max_vertex_atomic_counters = 0, - .max_tess_control_atomic_counters = 0, - .max_tess_evaluation_atomic_counters = 0, - .max_geometry_atomic_counters = 0, - .max_fragment_atomic_counters = 8, - .max_combined_atomic_counters = 8, - .max_atomic_counter_bindings = 1, - .max_vertex_atomic_counter_buffers = 0, - .max_tess_control_atomic_counter_buffers = 0, - .max_tess_evaluation_atomic_counter_buffers = 0, - .max_geometry_atomic_counter_buffers = 0, - .max_fragment_atomic_counter_buffers = 1, - .max_combined_atomic_counter_buffers = 1, - .max_atomic_counter_buffer_size = 16384, - .max_transform_feedback_buffers = 4, - .max_transform_feedback_interleaved_components = 64, - .max_cull_distances = limits ? (int)limits->maxCullDistances : 8, - .max_combined_clip_and_cull_distances = limits ? (int)limits->maxCombinedClipAndCullDistances - : 8, - .max_samples = 4, - .max_mesh_output_vertices_nv = 256, - .max_mesh_output_primitives_nv = 512, - .max_mesh_work_group_size_x_nv = 32, - .max_mesh_work_group_size_y_nv = 1, - .max_mesh_work_group_size_z_nv = 1, - .max_task_work_group_size_x_nv = 32, - .max_task_work_group_size_y_nv = 1, - .max_task_work_group_size_z_nv = 1, - .max_mesh_view_count_nv = 4, - .maxDualSourceDrawBuffersEXT = 1, - .limits = { - .non_inductive_for_loops = true, - .while_loops = true, - .do_while_loops = true, - .general_uniform_indexing = true, - .general_attribute_matrix_vector_indexing = true, - .general_varying_indexing = true, - .general_sampler_indexing = true, - .general_variable_indexing = true, - .general_constant_matrix_vector_indexing = true, - }}; - - *glslangResource = resource; -} diff --git a/src/igl/vulkan/VulkanHelpers.h b/src/igl/vulkan/VulkanHelpers.h index 91a4b9839e..6f667de9e4 100644 --- a/src/igl/vulkan/VulkanHelpers.h +++ b/src/igl/vulkan/VulkanHelpers.h @@ -250,9 +250,6 @@ void ivkCmdInsertDebugUtilsLabel(VkCommandBuffer buffer, void ivkCmdEndDebugUtilsLabel(VkCommandBuffer buffer); -void ivkGlslangResource(glslang_resource_t* glslangResource, - const VkPhysicalDeviceProperties* deviceProperties); - #ifdef __cplusplus } #endif diff --git a/src/igl/vulkan/VulkanImmediateCommands.cpp b/src/igl/vulkan/VulkanImmediateCommands.cpp index 65b39c2ee7..f1c9cb88a2 100644 --- a/src/igl/vulkan/VulkanImmediateCommands.cpp +++ b/src/igl/vulkan/VulkanImmediateCommands.cpp @@ -8,6 +8,7 @@ #include "VulkanImmediateCommands.h" #include +#include #include @@ -28,25 +29,31 @@ VulkanImmediateCommands::VulkanImmediateCommands(VkDevice device, vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue_); - buffers_.reserve(kMaxCommandBuffers); - for (uint32_t i = 0; i != kMaxCommandBuffers; i++) { + auto& buf = buffers_[i]; char fenceName[256] = {0}; char semaphoreName[256] = {0}; if (debugName) { snprintf(fenceName, sizeof(fenceName) - 1, "Fence: %s (cmdbuf %u)", debugName, i); snprintf(semaphoreName, sizeof(semaphoreName) - 1, "Semaphore: %s (cmdbuf %u)", debugName, i); } - buffers_.emplace_back(VulkanFence(device_, VkFenceCreateFlagBits{}, fenceName), - VulkanSemaphore(device, semaphoreName)); - VK_ASSERT(ivkAllocateCommandBuffer( - device_, commandPool_.getVkCommandPool(), &buffers_[i].cmdBufAllocated_)); + buf.semaphore_ = lvk::createSemaphore(device, semaphoreName); + buf.fence_ = lvk::createFence(device, fenceName); + VK_ASSERT( + ivkAllocateCommandBuffer(device_, commandPool_.getVkCommandPool(), &buf.cmdBufAllocated_)); buffers_[i].handle_.bufferIndex_ = i; } } VulkanImmediateCommands::~VulkanImmediateCommands() { waitAll(); + + for (auto& buf : buffers_) { + // lifetimes of all VkFence objects are managed explicitly + // we do not use deferredTask() for them + vkDestroyFence(device_, buf.fence_, nullptr); + vkDestroySemaphore(device_, buf.semaphore_, nullptr); + } } void VulkanImmediateCommands::purge() { @@ -57,11 +64,11 @@ void VulkanImmediateCommands::purge() { continue; } - const VkResult result = vkWaitForFences(device_, 1, &buf.fence_.vkFence_, VK_TRUE, 0); + const VkResult result = vkWaitForFences(device_, 1, &buf.fence_, VK_TRUE, 0); if (result == VK_SUCCESS) { VK_ASSERT(vkResetCommandBuffer(buf.cmdBuf_, VkCommandBufferResetFlags{0})); - VK_ASSERT(vkResetFences(device_, 1, &buf.fence_.vkFence_)); + VK_ASSERT(vkResetFences(device_, 1, &buf.fence_)); buf.cmdBuf_ = VK_NULL_HANDLE; numAvailableCommandBuffers_++; } else { @@ -128,8 +135,8 @@ void VulkanImmediateCommands::wait(const SubmitHandle handle) { return; } - VK_ASSERT(vkWaitForFences( - device_, 1, &buffers_[handle.bufferIndex_].fence_.vkFence_, VK_TRUE, UINT64_MAX)); + VK_ASSERT( + vkWaitForFences(device_, 1, &buffers_[handle.bufferIndex_].fence_, VK_TRUE, UINT64_MAX)); purge(); } @@ -144,7 +151,7 @@ void VulkanImmediateCommands::waitAll() { for (const auto& buf : buffers_) { if (buf.cmdBuf_ != VK_NULL_HANDLE && !buf.isEncoding_) { - fences[numFences++] = buf.fence_.vkFence_; + fences[numFences++] = buf.fence_; } } @@ -181,7 +188,7 @@ bool VulkanImmediateCommands::isReady(const SubmitHandle handle, bool fastCheckN return false; } - return vkWaitForFences(device_, 1, &buf.fence_.vkFence_, VK_TRUE, 0) == VK_SUCCESS; + return vkWaitForFences(device_, 1, &buf.fence_, VK_TRUE, 0) == VK_SUCCESS; } VulkanImmediateCommands::SubmitHandle VulkanImmediateCommands::submit( @@ -213,12 +220,12 @@ VulkanImmediateCommands::SubmitHandle VulkanImmediateCommands::submit( .commandBufferCount = 1u, .pCommandBuffers = &wrapper.cmdBuf_, .signalSemaphoreCount = 1u, - .pSignalSemaphores = &wrapper.semaphore_.vkSemaphore_, + .pSignalSemaphores = &wrapper.semaphore_, }; - VK_ASSERT(vkQueueSubmit(queue_, 1u, &si, wrapper.fence_.vkFence_)); + VK_ASSERT(vkQueueSubmit(queue_, 1u, &si, wrapper.fence_)); IGL_PROFILER_ZONE_END(); - lastSubmitSemaphore_ = wrapper.semaphore_.vkSemaphore_; + lastSubmitSemaphore_ = wrapper.semaphore_; lastSubmitHandle_ = wrapper.handle_; waitSemaphore_ = VK_NULL_HANDLE; diff --git a/src/igl/vulkan/VulkanImmediateCommands.h b/src/igl/vulkan/VulkanImmediateCommands.h index 9fa17fa8f3..3cbd9a2986 100644 --- a/src/igl/vulkan/VulkanImmediateCommands.h +++ b/src/igl/vulkan/VulkanImmediateCommands.h @@ -7,13 +7,9 @@ #pragma once -#include - #include #include -#include #include -#include namespace igl { namespace vulkan { @@ -48,13 +44,11 @@ class VulkanImmediateCommands final { static_assert(sizeof(SubmitHandle) == sizeof(uint64_t)); struct CommandBufferWrapper { - CommandBufferWrapper(VulkanFence&& fence, VulkanSemaphore&& semaphore) : - fence_(std::move(fence)), semaphore_(std::move(semaphore)) {} VkCommandBuffer cmdBuf_ = VK_NULL_HANDLE; VkCommandBuffer cmdBufAllocated_ = VK_NULL_HANDLE; SubmitHandle handle_ = {}; - VulkanFence fence_; - VulkanSemaphore semaphore_; + VkFence fence_ = VK_NULL_HANDLE; + VkSemaphore semaphore_ = VK_NULL_HANDLE; bool isEncoding_ = false; }; @@ -76,7 +70,7 @@ class VulkanImmediateCommands final { VkQueue queue_ = VK_NULL_HANDLE; VulkanCommandPool commandPool_; const char* debugName_ = ""; - std::vector buffers_; + CommandBufferWrapper buffers_[kMaxCommandBuffers]; SubmitHandle lastSubmitHandle_ = SubmitHandle(); VkSemaphore lastSubmitSemaphore_ = VK_NULL_HANDLE; VkSemaphore waitSemaphore_ = VK_NULL_HANDLE; diff --git a/src/igl/vulkan/VulkanSemaphore.cpp b/src/igl/vulkan/VulkanSemaphore.cpp deleted file mode 100644 index 64b2ec09e2..0000000000 --- a/src/igl/vulkan/VulkanSemaphore.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "VulkanSemaphore.h" - -#include - -namespace igl::vulkan { - -VulkanSemaphore::VulkanSemaphore(VkDevice device, const char* debugName) : device_(device) { - IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_CREATE); - - const VkSemaphoreCreateInfo ci = { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .flags = 0, - }; - VK_ASSERT(vkCreateSemaphore(device, &ci, nullptr, &vkSemaphore_)); - VK_ASSERT( - ivkSetDebugObjectName(device_, VK_OBJECT_TYPE_SEMAPHORE, (uint64_t)vkSemaphore_, debugName)); -} - -VulkanSemaphore ::~VulkanSemaphore() { - IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_DESTROY); - - if (device_ != VK_NULL_HANDLE) { - // lifetimes of all VkSemaphore objects are managed explicitly - // we do not use deferredTask() for them - vkDestroySemaphore(device_, vkSemaphore_, nullptr); - } -} - -VulkanSemaphore::VulkanSemaphore(VulkanSemaphore&& other) noexcept { - std::swap(device_, other.device_); - std::swap(vkSemaphore_, other.vkSemaphore_); -} - -VulkanSemaphore& VulkanSemaphore::operator=(VulkanSemaphore&& other) noexcept { - VulkanSemaphore tmp(std::move(other)); - std::swap(device_, tmp.device_); - std::swap(vkSemaphore_, tmp.vkSemaphore_); - return *this; -} - -} // namespace igl::vulkan diff --git a/src/igl/vulkan/VulkanSemaphore.h b/src/igl/vulkan/VulkanSemaphore.h deleted file mode 100644 index b3acaf0c82..0000000000 --- a/src/igl/vulkan/VulkanSemaphore.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include -#include - -namespace igl { -namespace vulkan { - -/** - * @brief Semaphores are used to synchronize GPU-GPU tasks. The VulkanSemaphore class encapsulates - * the creation and destruction of a vulkan semaphore object (VkSemaphore). It stores an opaque - * handle for a newly created semaphore object and for a device object. - */ -class VulkanSemaphore final { - public: - explicit VulkanSemaphore(VkDevice device, const char* debugName = nullptr); - ~VulkanSemaphore(); - - VulkanSemaphore(VulkanSemaphore&& other) noexcept; - VulkanSemaphore& operator=(VulkanSemaphore&& other) noexcept; - - VulkanSemaphore(const VulkanSemaphore&) = delete; - VulkanSemaphore& operator=(const VulkanSemaphore&) = delete; - - public: - VkDevice device_ = VK_NULL_HANDLE; - VkSemaphore vkSemaphore_ = VK_NULL_HANDLE; -}; - -} // namespace vulkan -} // namespace igl diff --git a/src/igl/vulkan/VulkanShaderModule.h b/src/igl/vulkan/VulkanShaderModule.h index 72b36e391b..b1d151b3fd 100644 --- a/src/igl/vulkan/VulkanShaderModule.h +++ b/src/igl/vulkan/VulkanShaderModule.h @@ -12,6 +12,8 @@ #include #include +#include + namespace igl { namespace vulkan { diff --git a/src/igl/vulkan/VulkanSwapchain.cpp b/src/igl/vulkan/VulkanSwapchain.cpp index 5690dacc18..57430f47ea 100644 --- a/src/igl/vulkan/VulkanSwapchain.cpp +++ b/src/igl/vulkan/VulkanSwapchain.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -137,8 +137,7 @@ VulkanSwapchain::VulkanSwapchain(VulkanContext& ctx, uint32_t width, uint32_t he surfaceFormat_ = chooseSwapSurfaceFormat(ctx.deviceSurfaceFormats_, ctx.config_.swapChainColorSpace); - acquireSemaphore_ = - std::make_unique(device_, "Semaphore: swapchain-acquire"); + acquireSemaphore_ = lvk::createSemaphore(device_, "Semaphore: swapchain-acquire"); IGL_ASSERT_MSG( ctx.vkSurface_ != VK_NULL_HANDLE, @@ -221,18 +220,15 @@ VulkanSwapchain::VulkanSwapchain(VulkanContext& ctx, uint32_t width, uint32_t he VulkanSwapchain::~VulkanSwapchain() { vkDestroySwapchainKHR(device_, swapchain_, nullptr); + vkDestroySemaphore(device_, acquireSemaphore_, nullptr); } std::shared_ptr VulkanSwapchain::getCurrentTexture() { IGL_PROFILER_FUNCTION(); if (getNextImage_) { // when timeout is set to UINT64_MAX, we wait until the next image has been acquired - VK_ASSERT(vkAcquireNextImageKHR(device_, - swapchain_, - UINT64_MAX, - acquireSemaphore_->vkSemaphore_, - VK_NULL_HANDLE, - ¤tImageIndex_)); + VK_ASSERT(vkAcquireNextImageKHR( + device_, swapchain_, UINT64_MAX, acquireSemaphore_, VK_NULL_HANDLE, ¤tImageIndex_)); // increase the frame number every time we acquire a new swapchain image frameNumber_++; getNextImage_ = false; diff --git a/src/igl/vulkan/VulkanSwapchain.h b/src/igl/vulkan/VulkanSwapchain.h index 5f34afc230..54773a6988 100644 --- a/src/igl/vulkan/VulkanSwapchain.h +++ b/src/igl/vulkan/VulkanSwapchain.h @@ -18,7 +18,6 @@ namespace igl::vulkan { class VulkanContext; -class VulkanSemaphore; class VulktanTexture; class VulkanSwapchain final { @@ -74,7 +73,7 @@ class VulkanSwapchain final { } public: - std::unique_ptr acquireSemaphore_; + VkSemaphore acquireSemaphore_ = VK_NULL_HANDLE; private: VulkanContext& ctx_;