Skip to content
Snippets Groups Projects
ShaderProgram.hpp 2.96 KiB
#pragma once
/**
 * @authors Artur Wasmut, Leonie Franken, Tobias Frisch, Simeon Hermann, Alexander Gauggel, Mark
 * Mints
 * @file vkcv/ShaderProgram.hpp
 * @brief ShaderProgram class to handle and prepare the shader stages for a graphics pipeline.
 */

#include <algorithm>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <spirv_cross.hpp>
#include <unordered_map>
#include <vulkan/vulkan.hpp>

#include "DescriptorBinding.hpp"
#include "ShaderStage.hpp"
#include "VertexLayout.hpp"

namespace vkcv {

	/**
	 * @brief Class to manage and reflect shaders as a program.
	 */
	class ShaderProgram {
	public:
		ShaderProgram() noexcept;   // ctor
		~ShaderProgram() = default; // dtor

		/**
		 * @brief Adds a shader into the shader program.
		 * The shader is only added if the shader program does not contain
		 * the particular shader stage already.
		 * Contains:
		 * (1) reading the SPIR-V file,
		 * (2) creating a shader module,
		 * (3) creating a shader stage,
		 * (4) adding to the shader stage list,
		 * (5) destroying of the shader module
		 *
		 * @param[in] stage The stage of the shader
		 * @param[in] path Path to the SPIR-V shader file
		 */
		bool addShader(ShaderStage stage, const std::filesystem::path &path);

		/**
		 * @brief Returns the shader binary of a specified stage from the program.
		 * Needed for the transfer to the pipeline.
		 *
		 * @param[in] stage The stage of the shader
		 * @return Shader code binary of the given stage
		 */
		const std::vector<uint32_t> &getShaderBinary(ShaderStage stage) const;

		/**
		 * @brief Returns whether a shader exists in the program for a
		 * specified shader stage.
		 *
		 * @param[in] stage The stage of the shader
		 * @return True, if a shader exists for the stage, else false
		 */
		bool existsShader(ShaderStage stage) const;

		/**
		 * @brief Returns the vertex attachments for the program and its
		 * shader stages.
		 *
		 * @return Vertex attachments
		 */
		const std::vector<VertexAttachment> &getVertexAttachments() const;

		/**
		 * @brief Returns the size of the programs push constants.
		 *
		 * @return Size of push constants
		 */
		size_t getPushConstantsSize() const;

		/**
		 * @brief Returns the reflected descriptor set bindings mapped via
		 * their descriptor set id.
		 *
		 * @return Reflected descriptor set bindings
		 */
		const std::unordered_map<uint32_t, DescriptorBindings> &getReflectedDescriptors() const;

	private:
		/**
		 * @brief Called after successfully adding a shader to the program.
		 * Fills vertex input attachments and descriptor sets (if present).
		 *
		 * @param[in] shaderStage the stage to reflect data from
		 */
		void reflectShader(ShaderStage shaderStage);

		std::unordered_map<ShaderStage, std::vector<uint32_t> > m_Shaders;

		// contains all vertex input attachments used in the vertex buffer
		VertexAttachments m_VertexAttachments;
		std::unordered_map<uint32_t, DescriptorBindings> m_DescriptorSets;
		size_t m_pushConstantsSize = 0;
	};

} // namespace vkcv