mirror of
				https://github.com/PancakeTAS/lsfg-vk.git
				synced 2025-10-30 07:01:10 +00:00 
			
		
		
		
	reorganize utils
This commit is contained in:
		
							parent
							
								
									10ac493312
								
							
						
					
					
						commit
						0345ec9e69
					
				
					 28 changed files with 285 additions and 332 deletions
				
			
		| 
						 | 
				
			
			@ -19,7 +19,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 | 
			
		|||
file(GLOB SOURCES
 | 
			
		||||
    "src/core/*.cpp"
 | 
			
		||||
    "src/shaderchains/*.cpp"
 | 
			
		||||
    "src/utils/*.cpp"
 | 
			
		||||
    "src/*.cpp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										0
									
								
								include/shaderchains/alpha.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								include/shaderchains/alpha.hpp
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										106
									
								
								include/utils.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								include/utils.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
#ifndef UTILS_HPP
 | 
			
		||||
#define UTILS_HPP
 | 
			
		||||
 | 
			
		||||
#include "core/commandbuffer.hpp"
 | 
			
		||||
#include "core/image.hpp"
 | 
			
		||||
#include "core/sampler.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
namespace Vulkan::Utils {
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
    /// Insert memory barriers for images in a command buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param buffer Command buffer to insert barriers into
 | 
			
		||||
    /// @param r2wImages Images that are being read and will be written to
 | 
			
		||||
    /// @param w2rImages Images that are being written to and will be read from
 | 
			
		||||
    ///
 | 
			
		||||
    /// @throws std::logic_error if the command buffer is not in Recording state
 | 
			
		||||
    ///
 | 
			
		||||
    void insertBarrier(
 | 
			
		||||
        const Vulkan::Core::CommandBuffer& buffer,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> r2wImages,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> w2rImages);
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
    /// Upload a DDS file to a Vulkan image.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param device The Vulkan device
 | 
			
		||||
    /// @param commandPool The command pool
 | 
			
		||||
    /// @param image The Vulkan image to upload to
 | 
			
		||||
    /// @param path The path to the DDS file.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @throws std::system_error If the file cannot be opened or read.
 | 
			
		||||
    /// @throws ls:vulkan_error If the Vulkan image cannot be created or updated.
 | 
			
		||||
    ///
 | 
			
		||||
    void uploadImage(const Vulkan::Device& device,
 | 
			
		||||
        const Vulkan::Core::CommandPool& commandPool,
 | 
			
		||||
        Vulkan::Core::Image& image, const std::string& path);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Vulkan::Globals {
 | 
			
		||||
 | 
			
		||||
    /// Global sampler with address mode set to clamp to border.
 | 
			
		||||
    extern Core::Sampler samplerClampBorder;
 | 
			
		||||
    /// Global sampler with address mode set to clamp to edge.
 | 
			
		||||
    extern Core::Sampler samplerClampEdge;
 | 
			
		||||
 | 
			
		||||
    /// Commonly used constant buffer structure for shaders.
 | 
			
		||||
    struct FgBuffer {
 | 
			
		||||
        std::array<uint32_t, 2> inputOffset;
 | 
			
		||||
        uint32_t firstIter;
 | 
			
		||||
        uint32_t firstIterS;
 | 
			
		||||
        uint32_t advancedColorKind;
 | 
			
		||||
        uint32_t hdrSupport;
 | 
			
		||||
        float resolutionInvScale;
 | 
			
		||||
        float timestamp;
 | 
			
		||||
        float uiThreshold;
 | 
			
		||||
        std::array<uint32_t, 3> pad;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Default instance of the FgBuffer.
 | 
			
		||||
    extern FgBuffer fgBuffer;
 | 
			
		||||
 | 
			
		||||
    static_assert(sizeof(FgBuffer) == 48, "FgBuffer must be 48 bytes in size.");
 | 
			
		||||
 | 
			
		||||
    /// Initialize global resources.
 | 
			
		||||
    void initializeGlobals(const Device& device);
 | 
			
		||||
 | 
			
		||||
    /// Uninitialize global resources.
 | 
			
		||||
    void uninitializeGlobals() noexcept;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace ls {
 | 
			
		||||
 | 
			
		||||
    /// Simple exception class for Vulkan errors.
 | 
			
		||||
    class vulkan_error : public std::runtime_error {
 | 
			
		||||
    public:
 | 
			
		||||
        ///
 | 
			
		||||
        /// Construct a vulkan_error with a message and a Vulkan result code.
 | 
			
		||||
        ///
 | 
			
		||||
        /// @param result The Vulkan result code associated with the error.
 | 
			
		||||
        /// @param message The error message.
 | 
			
		||||
        ///
 | 
			
		||||
        explicit vulkan_error(VkResult result, const std::string& message);
 | 
			
		||||
 | 
			
		||||
        /// Get the Vulkan result code associated with this error.
 | 
			
		||||
        [[nodiscard]] VkResult error() const { return this->result; }
 | 
			
		||||
 | 
			
		||||
        // Trivially copyable, moveable and destructible
 | 
			
		||||
        vulkan_error(const vulkan_error&) = default;
 | 
			
		||||
        vulkan_error(vulkan_error&&) = default;
 | 
			
		||||
        vulkan_error& operator=(const vulkan_error&) = default;
 | 
			
		||||
        vulkan_error& operator=(vulkan_error&&) = default;
 | 
			
		||||
        ~vulkan_error() noexcept override;
 | 
			
		||||
    private:
 | 
			
		||||
        VkResult result;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // UTILS_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -1,29 +0,0 @@
 | 
			
		|||
#ifndef BARRIERS_HPP
 | 
			
		||||
#define BARRIERS_HPP
 | 
			
		||||
 | 
			
		||||
#include "core/commandbuffer.hpp"
 | 
			
		||||
#include "core/image.hpp"
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <vulkan/vulkan_core.h>
 | 
			
		||||
 | 
			
		||||
namespace Barriers {
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
    /// Insert memory barriers for images in a command buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param buffer Command buffer to insert barriers into
 | 
			
		||||
    /// @param r2wImages Images that are being read and will be written to
 | 
			
		||||
    /// @param w2rImages Images that are being written to and will be read from
 | 
			
		||||
    ///
 | 
			
		||||
    /// @throws std::logic_error if the command buffer is not in Recording state
 | 
			
		||||
    ///
 | 
			
		||||
    void insertBarrier(
 | 
			
		||||
        const Vulkan::Core::CommandBuffer& buffer,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> r2wImages,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> w2rImages);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // BARRIERS_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
#ifndef EXCEPTIONS_HPP
 | 
			
		||||
#define EXCEPTIONS_HPP
 | 
			
		||||
 | 
			
		||||
#include <vulkan/vulkan_core.h>
 | 
			
		||||
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace ls {
 | 
			
		||||
 | 
			
		||||
    /// Simple exception class for Vulkan errors.
 | 
			
		||||
    class vulkan_error : public std::runtime_error {
 | 
			
		||||
    public:
 | 
			
		||||
        ///
 | 
			
		||||
        /// Construct a vulkan_error with a message and a Vulkan result code.
 | 
			
		||||
        ///
 | 
			
		||||
        /// @param result The Vulkan result code associated with the error.
 | 
			
		||||
        /// @param message The error message.
 | 
			
		||||
        ///
 | 
			
		||||
        explicit vulkan_error(VkResult result, const std::string& message);
 | 
			
		||||
 | 
			
		||||
        /// Get the Vulkan result code associated with this error.
 | 
			
		||||
        [[nodiscard]] VkResult error() const { return this->result; }
 | 
			
		||||
 | 
			
		||||
        // Trivially copyable, moveable and destructible
 | 
			
		||||
        vulkan_error(const vulkan_error&) = default;
 | 
			
		||||
        vulkan_error(vulkan_error&&) = default;
 | 
			
		||||
        vulkan_error& operator=(const vulkan_error&) = default;
 | 
			
		||||
        vulkan_error& operator=(vulkan_error&&) = default;
 | 
			
		||||
        ~vulkan_error() noexcept override;
 | 
			
		||||
    private:
 | 
			
		||||
        VkResult result;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // EXCEPTIONS_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -1,41 +0,0 @@
 | 
			
		|||
#ifndef GLOBAL_HPP
 | 
			
		||||
#define GLOBAL_HPP
 | 
			
		||||
 | 
			
		||||
#include "core/sampler.hpp"
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
namespace Vulkan::Globals {
 | 
			
		||||
 | 
			
		||||
    /// Global sampler with address mode set to clamp to border.
 | 
			
		||||
    extern Core::Sampler samplerClampBorder;
 | 
			
		||||
    /// Global sampler with address mode set to clamp to edge.
 | 
			
		||||
    extern Core::Sampler samplerClampEdge;
 | 
			
		||||
 | 
			
		||||
    /// Commonly used constant buffer structure for shaders.
 | 
			
		||||
    struct FgBuffer {
 | 
			
		||||
        std::array<uint32_t, 2> inputOffset;
 | 
			
		||||
        uint32_t firstIter;
 | 
			
		||||
        uint32_t firstIterS;
 | 
			
		||||
        uint32_t advancedColorKind;
 | 
			
		||||
        uint32_t hdrSupport;
 | 
			
		||||
        float resolutionInvScale;
 | 
			
		||||
        float timestamp;
 | 
			
		||||
        float uiThreshold;
 | 
			
		||||
        std::array<uint32_t, 3> pad;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Default instance of the FgBuffer.
 | 
			
		||||
    extern FgBuffer fgBuffer;
 | 
			
		||||
 | 
			
		||||
    static_assert(sizeof(FgBuffer) == 48, "FgBuffer must be 48 bytes in size.");
 | 
			
		||||
 | 
			
		||||
    /// Initialize global resources.
 | 
			
		||||
    void initializeGlobals(const Device& device);
 | 
			
		||||
 | 
			
		||||
    /// Uninitialize global resources.
 | 
			
		||||
    void uninitializeGlobals() noexcept;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // GLOBAL_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -1,28 +0,0 @@
 | 
			
		|||
#ifndef UPLOAD_HPP
 | 
			
		||||
#define UPLOAD_HPP
 | 
			
		||||
 | 
			
		||||
#include "core/commandpool.hpp"
 | 
			
		||||
#include "core/image.hpp"
 | 
			
		||||
#include "device.hpp"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
namespace Upload {
 | 
			
		||||
 | 
			
		||||
    ///
 | 
			
		||||
    /// Upload a DDS file to a Vulkan image.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param device The Vulkan device
 | 
			
		||||
    /// @param commandPool The command pool
 | 
			
		||||
    /// @param image The Vulkan image to upload to
 | 
			
		||||
    /// @param path The path to the DDS file.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @throws std::system_error If the file cannot be opened or read.
 | 
			
		||||
    /// @throws ls:vulkan_error If the Vulkan image cannot be created or updated.
 | 
			
		||||
    ///
 | 
			
		||||
    void upload(const Vulkan::Device& device, const Vulkan::Core::CommandPool& commandPool,
 | 
			
		||||
        Vulkan::Core::Image& image, const std::string& path);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // UPLOAD_HPP
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/buffer.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <optional>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/commandbuffer.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/commandpool.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/descriptorpool.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/descriptorset.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/fence.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/image.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/pipeline.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/sampler.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/semaphore.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Core;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "core/shadermodule.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "device.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include <vector>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
#include "instance.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,8 +6,7 @@
 | 
			
		|||
#include "device.hpp"
 | 
			
		||||
#include "instance.hpp"
 | 
			
		||||
#include "shaderchains/downsample.hpp"
 | 
			
		||||
#include "utils/global.hpp"
 | 
			
		||||
#include "utils/upload.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +47,7 @@ int main() {
 | 
			
		|||
        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
 | 
			
		||||
        VK_IMAGE_ASPECT_COLOR_BIT
 | 
			
		||||
    );
 | 
			
		||||
    Upload::upload(device, commandPool, inputImage, "rsc/images/source.dds");
 | 
			
		||||
    Utils::uploadImage(device, commandPool, inputImage, "rsc/images/source.dds");
 | 
			
		||||
 | 
			
		||||
    // create the shaderchains
 | 
			
		||||
    Shaderchains::Downsample downsample(device, descriptorPool, inputImage);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										0
									
								
								src/shaderchains/alpha.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/shaderchains/alpha.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
#include "shaderchains/downsample.hpp"
 | 
			
		||||
#include "utils/global.hpp"
 | 
			
		||||
#include "utils/barriers.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan::Shaderchains;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +42,7 @@ void Downsample::Dispatch(const Core::CommandBuffer& buf) {
 | 
			
		|||
    const uint32_t threadsX = (extent.width + 63) >> 6;
 | 
			
		||||
    const uint32_t threadsY = (extent.height + 63) >> 6;
 | 
			
		||||
 | 
			
		||||
    Barriers::insertBarrier(
 | 
			
		||||
    Utils::insertBarrier(
 | 
			
		||||
        buf,
 | 
			
		||||
        this->outImages,
 | 
			
		||||
        { this->inImage }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										162
									
								
								src/utils.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/utils.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,162 @@
 | 
			
		|||
#include "utils.hpp"
 | 
			
		||||
#include "core/buffer.hpp"
 | 
			
		||||
 | 
			
		||||
#include <format>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan;
 | 
			
		||||
 | 
			
		||||
void Utils::insertBarrier(
 | 
			
		||||
        const Core::CommandBuffer& buffer,
 | 
			
		||||
        std::vector<Core::Image> r2wImages,
 | 
			
		||||
        std::vector<Core::Image> w2rImages) {
 | 
			
		||||
    std::vector<VkImageMemoryBarrier2> barriers(r2wImages.size() + w2rImages.size());
 | 
			
		||||
 | 
			
		||||
    size_t index = 0;
 | 
			
		||||
    for (auto& image : r2wImages) {
 | 
			
		||||
        barriers[index++] = {
 | 
			
		||||
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
 | 
			
		||||
            .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
 | 
			
		||||
            .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
 | 
			
		||||
            .oldLayout = image.getLayout(),
 | 
			
		||||
            .newLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
			
		||||
            .image = image.handle(),
 | 
			
		||||
            .subresourceRange = {
 | 
			
		||||
                .aspectMask = image.getAspectFlags(),
 | 
			
		||||
                .levelCount = 1,
 | 
			
		||||
                .layerCount = 1
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
    for (auto& image : w2rImages) {
 | 
			
		||||
        barriers[index++] = {
 | 
			
		||||
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
 | 
			
		||||
            .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
 | 
			
		||||
            .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
 | 
			
		||||
            .oldLayout = image.getLayout(),
 | 
			
		||||
            .newLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
			
		||||
            .image = image.handle(),
 | 
			
		||||
            .subresourceRange = {
 | 
			
		||||
                .aspectMask = image.getAspectFlags(),
 | 
			
		||||
                .levelCount = 1,
 | 
			
		||||
                .layerCount = 1
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
    const VkDependencyInfo dependencyInfo = {
 | 
			
		||||
        .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
 | 
			
		||||
        .imageMemoryBarrierCount = static_cast<uint32_t>(barriers.size()),
 | 
			
		||||
        .pImageMemoryBarriers = barriers.data()
 | 
			
		||||
    };
 | 
			
		||||
    vkCmdPipelineBarrier2(buffer.handle(), &dependencyInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Utils::uploadImage(const Device& device, const Core::CommandPool& commandPool,
 | 
			
		||||
        Core::Image& image, const std::string& path) {
 | 
			
		||||
    // read image bytecode
 | 
			
		||||
    std::ifstream file(path, std::ios::ate | std::ios::binary);
 | 
			
		||||
    if (!file)
 | 
			
		||||
        throw std::system_error(errno, std::generic_category(), "Failed to open image: " + path);
 | 
			
		||||
 | 
			
		||||
    std::streamsize size = file.tellg();
 | 
			
		||||
    size -= 124 - 4; // dds header and magic bytes
 | 
			
		||||
    std::vector<uint8_t> code(static_cast<size_t>(size));
 | 
			
		||||
 | 
			
		||||
    file.seekg(0, std::ios::beg);
 | 
			
		||||
    if (!file.read(reinterpret_cast<char*>(code.data()), size))
 | 
			
		||||
        throw std::system_error(errno, std::generic_category(), "Failed to read image: " + path);
 | 
			
		||||
 | 
			
		||||
    file.close();
 | 
			
		||||
 | 
			
		||||
    // copy data to buffer
 | 
			
		||||
    const Core::Buffer stagingBuffer(
 | 
			
		||||
        device, code.data(), static_cast<uint32_t>(code.size()),
 | 
			
		||||
        VK_BUFFER_USAGE_TRANSFER_SRC_BIT
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // perform the upload
 | 
			
		||||
    Core::CommandBuffer commandBuffer(device, commandPool);
 | 
			
		||||
    commandBuffer.begin();
 | 
			
		||||
 | 
			
		||||
    const VkImageMemoryBarrier barrier{
 | 
			
		||||
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
			
		||||
        .srcAccessMask = VK_ACCESS_NONE,
 | 
			
		||||
        .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
			
		||||
        .oldLayout = image.getLayout(),
 | 
			
		||||
        .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
			
		||||
        .image = image.handle(),
 | 
			
		||||
        .subresourceRange = {
 | 
			
		||||
            .aspectMask = image.getAspectFlags(),
 | 
			
		||||
            .levelCount = 1,
 | 
			
		||||
            .layerCount = 1
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    image.setLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 | 
			
		||||
    vkCmdPipelineBarrier(
 | 
			
		||||
        commandBuffer.handle(),
 | 
			
		||||
        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
 | 
			
		||||
        0, 0, nullptr, 0, nullptr, 1, &barrier
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    auto extent = image.getExtent();
 | 
			
		||||
    const VkBufferImageCopy region{
 | 
			
		||||
        .bufferImageHeight = 0,
 | 
			
		||||
        .imageSubresource = {
 | 
			
		||||
            .aspectMask = image.getAspectFlags(),
 | 
			
		||||
            .layerCount = 1
 | 
			
		||||
        },
 | 
			
		||||
        .imageExtent = { extent.width, extent.height, 1 }
 | 
			
		||||
    };
 | 
			
		||||
    vkCmdCopyBufferToImage(
 | 
			
		||||
        commandBuffer.handle(),
 | 
			
		||||
        stagingBuffer.handle(), image.handle(),
 | 
			
		||||
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    commandBuffer.end();
 | 
			
		||||
 | 
			
		||||
    Core::Fence fence(device);
 | 
			
		||||
    commandBuffer.submit(device.getComputeQueue(), fence);
 | 
			
		||||
 | 
			
		||||
    // wait for the upload to complete
 | 
			
		||||
    if (!fence.wait(device))
 | 
			
		||||
        throw ls::vulkan_error(VK_TIMEOUT, "Upload operation timed out");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Core::Sampler Globals::samplerClampBorder;
 | 
			
		||||
Core::Sampler Globals::samplerClampEdge;
 | 
			
		||||
Globals::FgBuffer Globals::fgBuffer;
 | 
			
		||||
 | 
			
		||||
void Globals::initializeGlobals(const Device& device) {
 | 
			
		||||
    // initialize global samplers
 | 
			
		||||
    samplerClampBorder = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
 | 
			
		||||
    samplerClampEdge =   Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
 | 
			
		||||
    // initialize global constant buffer
 | 
			
		||||
    fgBuffer = {
 | 
			
		||||
        .inputOffset = { 0, 29 },
 | 
			
		||||
        .resolutionInvScale = 1.0F,
 | 
			
		||||
        .timestamp = 0.5F,
 | 
			
		||||
        .uiThreshold = 0.1F,
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Globals::uninitializeGlobals() noexcept {
 | 
			
		||||
    // uninitialize global samplers
 | 
			
		||||
    samplerClampBorder = Core::Sampler();
 | 
			
		||||
    samplerClampEdge = Core::Sampler();
 | 
			
		||||
 | 
			
		||||
    // uninitialize global constant buffer
 | 
			
		||||
    fgBuffer = Globals::FgBuffer();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ls::vulkan_error::vulkan_error(VkResult result, const std::string& message)
 | 
			
		||||
    : std::runtime_error(std::format("{} (error {})", message, static_cast<uint32_t>(result))), result(result) {}
 | 
			
		||||
 | 
			
		||||
ls::vulkan_error::~vulkan_error() noexcept = default;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
#include "utils/barriers.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Barriers;
 | 
			
		||||
 | 
			
		||||
void Barriers::insertBarrier(
 | 
			
		||||
        const Vulkan::Core::CommandBuffer& buffer,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> r2wImages,
 | 
			
		||||
        std::vector<Vulkan::Core::Image> w2rImages) {
 | 
			
		||||
    std::vector<VkImageMemoryBarrier2> barriers(r2wImages.size() + w2rImages.size());
 | 
			
		||||
 | 
			
		||||
    size_t index = 0;
 | 
			
		||||
    for (auto& image : r2wImages) {
 | 
			
		||||
        barriers[index++] = {
 | 
			
		||||
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
 | 
			
		||||
            .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
 | 
			
		||||
            .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
 | 
			
		||||
            .oldLayout = image.getLayout(),
 | 
			
		||||
            .newLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
			
		||||
            .image = image.handle(),
 | 
			
		||||
            .subresourceRange = {
 | 
			
		||||
                .aspectMask = image.getAspectFlags(),
 | 
			
		||||
                .levelCount = 1,
 | 
			
		||||
                .layerCount = 1
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
    for (auto& image : w2rImages) {
 | 
			
		||||
        barriers[index++] = {
 | 
			
		||||
            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
 | 
			
		||||
            .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
 | 
			
		||||
            .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
 | 
			
		||||
            .dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
 | 
			
		||||
            .oldLayout = image.getLayout(),
 | 
			
		||||
            .newLayout = VK_IMAGE_LAYOUT_GENERAL,
 | 
			
		||||
            .image = image.handle(),
 | 
			
		||||
            .subresourceRange = {
 | 
			
		||||
                .aspectMask = image.getAspectFlags(),
 | 
			
		||||
                .levelCount = 1,
 | 
			
		||||
                .layerCount = 1
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
 | 
			
		||||
    }
 | 
			
		||||
    const VkDependencyInfo dependencyInfo = {
 | 
			
		||||
        .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
 | 
			
		||||
        .imageMemoryBarrierCount = static_cast<uint32_t>(barriers.size()),
 | 
			
		||||
        .pImageMemoryBarriers = barriers.data()
 | 
			
		||||
    };
 | 
			
		||||
    vkCmdPipelineBarrier2(buffer.handle(), &dependencyInfo);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
#include "utils/exceptions.hpp"
 | 
			
		||||
 | 
			
		||||
#include <format>
 | 
			
		||||
 | 
			
		||||
using namespace ls;
 | 
			
		||||
 | 
			
		||||
vulkan_error::vulkan_error(VkResult result, const std::string& message)
 | 
			
		||||
    : std::runtime_error(std::format("{} (error {})", message, static_cast<uint32_t>(result))), result(result) {}
 | 
			
		||||
 | 
			
		||||
vulkan_error::~vulkan_error() noexcept = default;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
#include "utils/global.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Vulkan;
 | 
			
		||||
 | 
			
		||||
Core::Sampler Globals::samplerClampBorder;
 | 
			
		||||
Core::Sampler Globals::samplerClampEdge;
 | 
			
		||||
Globals::FgBuffer Globals::fgBuffer;
 | 
			
		||||
 | 
			
		||||
void Globals::initializeGlobals(const Device& device) {
 | 
			
		||||
    // initialize global samplers
 | 
			
		||||
    samplerClampBorder = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
 | 
			
		||||
    samplerClampEdge =   Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
 | 
			
		||||
    // initialize global constant buffer
 | 
			
		||||
    fgBuffer = {
 | 
			
		||||
        .inputOffset = { 0, 29 },
 | 
			
		||||
        .resolutionInvScale = 1.0F,
 | 
			
		||||
        .timestamp = 0.5F,
 | 
			
		||||
        .uiThreshold = 0.1F,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Globals::uninitializeGlobals() noexcept {
 | 
			
		||||
    // uninitialize global samplers
 | 
			
		||||
    samplerClampBorder = Core::Sampler();
 | 
			
		||||
    samplerClampEdge = Core::Sampler();
 | 
			
		||||
 | 
			
		||||
    // uninitialize global constant buffer
 | 
			
		||||
    fgBuffer = Globals::FgBuffer();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,82 +0,0 @@
 | 
			
		|||
#include "utils/upload.hpp"
 | 
			
		||||
#include "core/buffer.hpp"
 | 
			
		||||
#include "core/commandbuffer.hpp"
 | 
			
		||||
#include "utils/exceptions.hpp"
 | 
			
		||||
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <vulkan/vulkan_core.h>
 | 
			
		||||
 | 
			
		||||
using namespace Upload;
 | 
			
		||||
using namespace Vulkan;
 | 
			
		||||
 | 
			
		||||
void Upload::upload(const Device& device, const Core::CommandPool& commandPool,
 | 
			
		||||
        Core::Image& image, const std::string& path) {
 | 
			
		||||
    // read iamge bytecode
 | 
			
		||||
    std::ifstream file(path, std::ios::ate | std::ios::binary);
 | 
			
		||||
    if (!file)
 | 
			
		||||
        throw std::system_error(errno, std::generic_category(), "Failed to open image: " + path);
 | 
			
		||||
 | 
			
		||||
    std::streamsize size = file.tellg();
 | 
			
		||||
    size -= 124 - 4;
 | 
			
		||||
    std::vector<uint8_t> code(static_cast<size_t>(size));
 | 
			
		||||
 | 
			
		||||
    file.seekg(0, std::ios::beg);
 | 
			
		||||
    if (!file.read(reinterpret_cast<char*>(code.data()), size))
 | 
			
		||||
        throw std::system_error(errno, std::generic_category(), "Failed to read image: " + path);
 | 
			
		||||
 | 
			
		||||
    file.close();
 | 
			
		||||
 | 
			
		||||
    // copy data to buffer
 | 
			
		||||
    const Vulkan::Core::Buffer stagingBuffer(
 | 
			
		||||
        device, code.data(), static_cast<uint32_t>(code.size()),
 | 
			
		||||
        VK_BUFFER_USAGE_TRANSFER_SRC_BIT
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // perform the upload
 | 
			
		||||
    Core::CommandBuffer commandBuffer(device, commandPool);
 | 
			
		||||
    commandBuffer.begin();
 | 
			
		||||
 | 
			
		||||
    const VkImageMemoryBarrier barrier{
 | 
			
		||||
        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
			
		||||
        .srcAccessMask = VK_ACCESS_NONE,
 | 
			
		||||
        .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
 | 
			
		||||
        .oldLayout = image.getLayout(),
 | 
			
		||||
        .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
 | 
			
		||||
        .image = image.handle(),
 | 
			
		||||
        .subresourceRange = {
 | 
			
		||||
            .aspectMask = image.getAspectFlags(),
 | 
			
		||||
            .levelCount = 1,
 | 
			
		||||
            .layerCount = 1
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    image.setLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 | 
			
		||||
    vkCmdPipelineBarrier(
 | 
			
		||||
        commandBuffer.handle(),
 | 
			
		||||
        VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
 | 
			
		||||
        0, 0, nullptr, 0, nullptr, 1, &barrier
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    auto extent = image.getExtent();
 | 
			
		||||
    const VkBufferImageCopy region{
 | 
			
		||||
        .bufferImageHeight = 0,
 | 
			
		||||
        .imageSubresource = {
 | 
			
		||||
            .aspectMask = image.getAspectFlags(),
 | 
			
		||||
            .layerCount = 1
 | 
			
		||||
        },
 | 
			
		||||
        .imageExtent = { extent.width, extent.height, 1 }
 | 
			
		||||
    };
 | 
			
		||||
    vkCmdCopyBufferToImage(
 | 
			
		||||
        commandBuffer.handle(),
 | 
			
		||||
        stagingBuffer.handle(), image.handle(),
 | 
			
		||||
        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    commandBuffer.end();
 | 
			
		||||
 | 
			
		||||
    Core::Fence fence(device);
 | 
			
		||||
    commandBuffer.submit(device.getComputeQueue(), fence);
 | 
			
		||||
 | 
			
		||||
    if (!fence.wait(device))
 | 
			
		||||
        throw ls::vulkan_error(VK_TIMEOUT, "Upload operation timed out");
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue