mirror of
				https://github.com/PancakeTAS/lsfg-vk.git
				synced 2025-10-30 07:01:10 +00:00 
			
		
		
		
	feat(test): write main test
This commit is contained in:
		
							parent
							
								
									a90593fdc1
								
							
						
					
					
						commit
						405733d50e
					
				
					 4 changed files with 185 additions and 10 deletions
				
			
		|  | @ -48,6 +48,21 @@ namespace LSFG::Core { | ||||||
|         Image(const Core::Device& device, VkExtent2D extent, VkFormat format, |         Image(const Core::Device& device, VkExtent2D extent, VkFormat format, | ||||||
|             VkImageUsageFlags usage, VkImageAspectFlags aspectFlags, int fd); |             VkImageUsageFlags usage, VkImageAspectFlags aspectFlags, int fd); | ||||||
| 
 | 
 | ||||||
|  |         ///
 | ||||||
|  |         /// Create the image and export the backing fd
 | ||||||
|  |         ///
 | ||||||
|  |         /// @param device Vulkan device
 | ||||||
|  |         /// @param extent Extent of the image in pixels.
 | ||||||
|  |         /// @param format Vulkan format of the image
 | ||||||
|  |         /// @param usage Usage flags for the image
 | ||||||
|  |         /// @param aspectFlags Aspect flags for the image view
 | ||||||
|  |         /// @param fd Pointer to an integer where the file descriptor will be stored.
 | ||||||
|  |         ///
 | ||||||
|  |         /// @throws LSFG::vulkan_error if object creation fails.
 | ||||||
|  |         ///
 | ||||||
|  |         Image(const Core::Device& device, VkExtent2D extent, VkFormat format, | ||||||
|  |             VkImageUsageFlags usage, VkImageAspectFlags aspectFlags, int* fd); | ||||||
|  | 
 | ||||||
|         /// Get the Vulkan handle.
 |         /// Get the Vulkan handle.
 | ||||||
|         [[nodiscard]] auto handle() const { return *this->image; } |         [[nodiscard]] auto handle() const { return *this->image; } | ||||||
|         /// Get the Vulkan device memory handle.
 |         /// Get the Vulkan device memory handle.
 | ||||||
|  |  | ||||||
|  | @ -240,3 +240,136 @@ Image::Image(const Core::Device& device, VkExtent2D extent, VkFormat format, | ||||||
|         } |         } | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // second shared memory constructors
 | ||||||
|  | 
 | ||||||
|  | Image::Image(const Core::Device& device, VkExtent2D extent, VkFormat format, | ||||||
|  |         VkImageUsageFlags usage, VkImageAspectFlags aspectFlags, int* fd) | ||||||
|  |         : extent(extent), format(format), aspectFlags(aspectFlags) { | ||||||
|  |     // create image
 | ||||||
|  |     const VkExternalMemoryImageCreateInfo externalInfo{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, | ||||||
|  |         .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | ||||||
|  |     }; | ||||||
|  |     const VkImageCreateInfo desc{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, | ||||||
|  |         .pNext = &externalInfo, | ||||||
|  |         .imageType = VK_IMAGE_TYPE_2D, | ||||||
|  |         .format = format, | ||||||
|  |         .extent = { | ||||||
|  |             .width = extent.width, | ||||||
|  |             .height = extent.height, | ||||||
|  |             .depth = 1 | ||||||
|  |         }, | ||||||
|  |         .mipLevels = 1, | ||||||
|  |         .arrayLayers = 1, | ||||||
|  |         .samples = VK_SAMPLE_COUNT_1_BIT, | ||||||
|  |         .usage = usage, | ||||||
|  |         .sharingMode = VK_SHARING_MODE_EXCLUSIVE | ||||||
|  |     }; | ||||||
|  |     VkImage imageHandle{}; | ||||||
|  |     auto res = vkCreateImage(device.handle(), &desc, nullptr, &imageHandle); | ||||||
|  |     if (res != VK_SUCCESS || imageHandle == VK_NULL_HANDLE) | ||||||
|  |         throw LSFG::vulkan_error(res, "Failed to create Vulkan image"); | ||||||
|  | 
 | ||||||
|  |     // find memory type
 | ||||||
|  |     VkPhysicalDeviceMemoryProperties memProps; | ||||||
|  |     vkGetPhysicalDeviceMemoryProperties(device.getPhysicalDevice(), &memProps); | ||||||
|  | 
 | ||||||
|  |     VkMemoryRequirements memReqs; | ||||||
|  |     vkGetImageMemoryRequirements(device.handle(), imageHandle, &memReqs); | ||||||
|  | 
 | ||||||
|  | #pragma clang diagnostic push | ||||||
|  | #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" | ||||||
|  |     std::optional<uint32_t> memType{}; | ||||||
|  |     for (uint32_t i = 0; i < memProps.memoryTypeCount; ++i) { | ||||||
|  |         if ((memReqs.memoryTypeBits & (1 << i)) && // NOLINTBEGIN
 | ||||||
|  |             (memProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) { | ||||||
|  |             memType.emplace(i); | ||||||
|  |             break; | ||||||
|  |         } // NOLINTEND
 | ||||||
|  |     } | ||||||
|  |     if (!memType.has_value()) | ||||||
|  |         throw LSFG::vulkan_error(VK_ERROR_UNKNOWN, "Unable to find memory type for image"); | ||||||
|  | #pragma clang diagnostic pop | ||||||
|  | 
 | ||||||
|  |     // allocate and bind memory
 | ||||||
|  |     const VkMemoryDedicatedAllocateInfoKHR dedicatedInfo{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, | ||||||
|  |         .image = imageHandle, | ||||||
|  |     }; | ||||||
|  |     const VkExportMemoryAllocateInfo exportInfo{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, | ||||||
|  |         .pNext = &dedicatedInfo, | ||||||
|  |         .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | ||||||
|  |     }; | ||||||
|  |     const VkMemoryAllocateInfo allocInfo{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | ||||||
|  |         .pNext = &exportInfo, | ||||||
|  |         .allocationSize = memReqs.size, | ||||||
|  |         .memoryTypeIndex = memType.value() | ||||||
|  |     }; | ||||||
|  |     VkDeviceMemory memoryHandle{}; | ||||||
|  |     res = vkAllocateMemory(device.handle(), &allocInfo, nullptr, &memoryHandle); | ||||||
|  |     if (res != VK_SUCCESS || memoryHandle == VK_NULL_HANDLE) | ||||||
|  |         throw LSFG::vulkan_error(res, "Failed to allocate memory for Vulkan image"); | ||||||
|  | 
 | ||||||
|  |     res = vkBindImageMemory(device.handle(), imageHandle, memoryHandle, 0); | ||||||
|  |     if (res != VK_SUCCESS) | ||||||
|  |         throw LSFG::vulkan_error(res, "Failed to bind memory to Vulkan image"); | ||||||
|  | 
 | ||||||
|  |     // obtain the sharing fd
 | ||||||
|  |     const VkMemoryGetFdInfoKHR fdInfo{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, | ||||||
|  |         .memory = memoryHandle, | ||||||
|  |         .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, | ||||||
|  |     }; | ||||||
|  |     res = vkGetMemoryFdKHR(device.handle(), &fdInfo, fd); | ||||||
|  |     if (res != VK_SUCCESS || *fd < 0) | ||||||
|  |         throw LSFG::vulkan_error(res, "Failed to obtain sharing fd for Vulkan image"); | ||||||
|  | 
 | ||||||
|  |     // create image view
 | ||||||
|  |     const VkImageViewCreateInfo viewDesc{ | ||||||
|  |         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | ||||||
|  |         .image = imageHandle, | ||||||
|  |         .viewType = VK_IMAGE_VIEW_TYPE_2D, | ||||||
|  |         .format = format, | ||||||
|  |         .components = { | ||||||
|  |             .r = VK_COMPONENT_SWIZZLE_IDENTITY, | ||||||
|  |             .g = VK_COMPONENT_SWIZZLE_IDENTITY, | ||||||
|  |             .b = VK_COMPONENT_SWIZZLE_IDENTITY, | ||||||
|  |             .a = VK_COMPONENT_SWIZZLE_IDENTITY | ||||||
|  |         }, | ||||||
|  |         .subresourceRange = { | ||||||
|  |             .aspectMask = aspectFlags, | ||||||
|  |             .levelCount = 1, | ||||||
|  |             .layerCount = 1 | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     VkImageView viewHandle{}; | ||||||
|  |     res = vkCreateImageView(device.handle(), &viewDesc, nullptr, &viewHandle); | ||||||
|  |     if (res != VK_SUCCESS || viewHandle == VK_NULL_HANDLE) | ||||||
|  |         throw LSFG::vulkan_error(res, "Failed to create image view"); | ||||||
|  | 
 | ||||||
|  |     // store objects in shared ptr
 | ||||||
|  |     this->layout = std::make_shared<VkImageLayout>(VK_IMAGE_LAYOUT_UNDEFINED); | ||||||
|  |     this->image = std::shared_ptr<VkImage>( | ||||||
|  |         new VkImage(imageHandle), | ||||||
|  |         [dev = device.handle()](VkImage* img) { | ||||||
|  |             vkDestroyImage(dev, *img, nullptr); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  |     this->memory = std::shared_ptr<VkDeviceMemory>( | ||||||
|  |         new VkDeviceMemory(memoryHandle), | ||||||
|  |         [dev = device.handle()](VkDeviceMemory* mem) { | ||||||
|  |             vkFreeMemory(dev, *mem, nullptr); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  |     this->view = std::shared_ptr<VkImageView>( | ||||||
|  |         new VkImageView(viewHandle), | ||||||
|  |         [dev = device.handle()](VkImageView* imgView) { | ||||||
|  |             vkDestroyImageView(dev, *imgView, nullptr); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -22,7 +22,8 @@ set_target_properties(lsfg-vk-test PROPERTIES | ||||||
| target_include_directories(lsfg-vk-test | target_include_directories(lsfg-vk-test | ||||||
|     PRIVATE include) |     PRIVATE include) | ||||||
| target_link_libraries(lsfg-vk-test PUBLIC | target_link_libraries(lsfg-vk-test PUBLIC | ||||||
|     vulkan lsfg-vk) |     lsfg-vk lsfg-vk-framegen | ||||||
|  |     vulkan) | ||||||
| 
 | 
 | ||||||
| # diagnostics | # diagnostics | ||||||
| if(CMAKE_BUILD_TYPE STREQUAL "Debug") | if(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||||||
|  |  | ||||||
|  | @ -1,13 +1,16 @@ | ||||||
|  | #include "common/utils.hpp" | ||||||
|  | #include "core/commandpool.hpp" | ||||||
| #include "core/device.hpp" | #include "core/device.hpp" | ||||||
|  | #include "core/image.hpp" | ||||||
| #include "core/instance.hpp" | #include "core/instance.hpp" | ||||||
| #include "extract/extract.hpp" | #include "extract/extract.hpp" | ||||||
| #include "mini/image.hpp" |  | ||||||
| #include "utils.hpp" |  | ||||||
| 
 | 
 | ||||||
| #include <vulkan/vulkan_core.h> | #include <vulkan/vulkan_core.h> | ||||||
| #include <renderdoc_app.h> | #include <renderdoc_app.h> | ||||||
|  | #include <unistd.h> | ||||||
| #include <dlfcn.h> | #include <dlfcn.h> | ||||||
| 
 | 
 | ||||||
|  | #include <utility> | ||||||
| #include <cstddef> | #include <cstddef> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <string> | #include <string> | ||||||
|  | @ -20,6 +23,7 @@ using namespace LSFG; | ||||||
| 
 | 
 | ||||||
| const VkExtent2D SRC_EXTENT = { 2560 , 1440 }; | const VkExtent2D SRC_EXTENT = { 2560 , 1440 }; | ||||||
| const VkFormat SRC_FORMAT = VK_FORMAT_R8G8B8A8_UNORM; | const VkFormat SRC_FORMAT = VK_FORMAT_R8G8B8A8_UNORM; | ||||||
|  | const std::string EMPTY_FILE = "test/empty.dds"; | ||||||
| const std::array<std::string, 2> SRC_FILES = { | const std::array<std::string, 2> SRC_FILES = { | ||||||
|     "test/f0.dds", |     "test/f0.dds", | ||||||
|     "test/f1.dds" |     "test/f1.dds" | ||||||
|  | @ -53,26 +57,28 @@ namespace { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Create images for frame generation
 |     /// Create images for frame generation
 | ||||||
|     void create_images(const Core::Device& device, |     std::pair<Core::Image, Core::Image> create_images(const Core::Device& device, | ||||||
|             std::array<int, 2>& fds, |             std::array<int, 2>& fds, | ||||||
|             std::vector<int>& outFds, std::vector<Mini::Image>& out_n) { |             std::vector<int>& outFds, std::vector<Core::Image>& out_n) { | ||||||
|         const Mini::Image frame_0{device.handle(), device.getPhysicalDevice(), |         const Core::Image frame_0{device, | ||||||
|             SRC_EXTENT, SRC_FORMAT, |             SRC_EXTENT, SRC_FORMAT, | ||||||
|             VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT, |             VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT, | ||||||
|             &fds.at(0) |             &fds.at(0) | ||||||
|         }; |         }; | ||||||
|         const Mini::Image frame_1{device.handle(), device.getPhysicalDevice(), |         const Core::Image frame_1{device, | ||||||
|             SRC_EXTENT, SRC_FORMAT, |             SRC_EXTENT, SRC_FORMAT, | ||||||
|             VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT, |             VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_ASPECT_COLOR_BIT, | ||||||
|             &fds.at(1) |             &fds.at(1) | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         for (size_t i = 0; i < (MULTIPLIER - 1); i++) |         for (size_t i = 0; i < (MULTIPLIER - 1); i++) | ||||||
|             out_n.at(i) = Mini::Image{device.handle(), device.getPhysicalDevice(), |             out_n.at(i) = Core::Image{device, | ||||||
|                 SRC_EXTENT, SRC_FORMAT, |                 SRC_EXTENT, SRC_FORMAT, | ||||||
|                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_ASPECT_COLOR_BIT, |                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_ASPECT_COLOR_BIT, | ||||||
|                 &outFds.at(i) |                 &outFds.at(i) | ||||||
|             }; |             }; | ||||||
|  | 
 | ||||||
|  |         return { frame_0, frame_1 }; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Create the LSFG context.
 |     /// Create the LSFG context.
 | ||||||
|  | @ -99,7 +105,8 @@ namespace { | ||||||
| namespace { | namespace { | ||||||
|     std::array<int, 2> fds{}; |     std::array<int, 2> fds{}; | ||||||
|     std::vector<int> outFds(MULTIPLIER - 1); |     std::vector<int> outFds(MULTIPLIER - 1); | ||||||
|     std::vector<Mini::Image> out_n(MULTIPLIER - 1); |     std::pair<Core::Image, Core::Image> frames{}; | ||||||
|  |     std::vector<Core::Image> out_n(MULTIPLIER - 1); | ||||||
|     int32_t lsfg_id{}; |     int32_t lsfg_id{}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -107,14 +114,33 @@ int main() { | ||||||
|     // initialize host Vulkan
 |     // initialize host Vulkan
 | ||||||
|     const Core::Instance instance{}; |     const Core::Instance instance{}; | ||||||
|     const Core::Device device{instance, 0x1463ABAC}; |     const Core::Device device{instance, 0x1463ABAC}; | ||||||
|  |     const Core::CommandPool commandPool{device}; | ||||||
| 
 | 
 | ||||||
|     // setup test
 |     // setup test
 | ||||||
|     setup_renderdoc(); |     setup_renderdoc(); | ||||||
|     create_images(device, fds, outFds, out_n); |     frames = create_images(device, fds, outFds, out_n); | ||||||
|     lsfg_id = create_lsfg(fds, outFds); |     lsfg_id = create_lsfg(fds, outFds); | ||||||
| 
 | 
 | ||||||
|  |     Utils::clearImage(device, frames.first); | ||||||
|  |     Utils::clearImage(device, frames.second); | ||||||
|  | 
 | ||||||
|     // run
 |     // run
 | ||||||
|     for (size_t fc = 0; fc < SRC_FILES.size(); fc++) { |     for (size_t fc = 0; fc < SRC_FILES.size(); fc++) { | ||||||
|  |         if (fc % 2 == 0) | ||||||
|  |             Utils::uploadImage(device, commandPool, frames.first, SRC_FILES.at(fc)); | ||||||
|  |         else | ||||||
|  |             Utils::uploadImage(device, commandPool, frames.second, SRC_FILES.at(fc)); | ||||||
|  | 
 | ||||||
|  |         if (rdoc) rdoc->StartFrameCapture(nullptr, nullptr); | ||||||
|  | 
 | ||||||
|  |         // run the present
 | ||||||
|  |         const std::vector<int> null_sems(MULTIPLIER - 1, -1); | ||||||
|  |         presentContext(lsfg_id, -1, null_sems); | ||||||
|  | 
 | ||||||
|  |         // wait until the present is done
 | ||||||
|  |         usleep(1000 * 100); | ||||||
|  | 
 | ||||||
|  |         if (rdoc) rdoc->EndFrameCapture(nullptr, nullptr); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // destroy test
 |     // destroy test
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 PancakeTAS
						PancakeTAS