ShaderProgram.cpp 4.35 KB
Newer Older
1
/**
2
 * @authors Simeon Hermann, Leonie Franken
3
4
5
6
 * @file src/vkcv/ShaderProgram.cpp
 * @brief ShaderProgram class to handle and prepare the shader stages for a graphics pipeline
 */

7
#include "vkcv/ShaderProgram.hpp"
8
9
10
11
12
13
14
15

std::vector<const char*> validationLayers = {
	"VK_LAYER_KHRONOS_validation"
};


namespace vkcv {

16
17
18
19
20
	ShaderProgram::ShaderProgram(){
	    ShaderStages m_shaderStages{};
	    m_shaderStages.shaderCode = std::vector<std::vector<char>> ();
	    m_shaderStages.shaderStageFlag = std::vector<vk::ShaderStageFlagBits> ();
	}
21
22
23
24
25
26
27
28
29
30
31
32
33

	std::vector<char> ShaderProgram::readFile(const std::string& filepath) {
		std::ifstream file(filepath, std::ios::ate | std::ios::binary);
		if (!file.is_open()) {
			throw std::runtime_error("The file could not be opened.");
		}
		size_t fileSize = (size_t)file.tellg();
		std::vector<char> buffer(fileSize);
		file.seekg(0);
		file.read(buffer.data(), fileSize);
		return buffer;
	}

34
    vk::ShaderStageFlagBits ShaderProgram::convertToShaderStageFlagBits(ShaderProgram::ShaderStage shaderStage) const{
35
36
37
38
39
40
41
42
43
44
45
46
        switch (shaderStage) {
            case ShaderStage::VERTEX:
                return vk::ShaderStageFlagBits::eVertex;
            case ShaderStage::FRAGMENT:
                return vk::ShaderStageFlagBits::eFragment;
            case ShaderStage::COMPUTE:
                return vk::ShaderStageFlagBits::eCompute;
        }
        throw std::runtime_error("Shader Type not yet implemented.");
	}

	/*vk::ShaderModule ShaderProgram::createShaderModule(const std::vector<char>& shaderCode) {
47
48
49
		vk::ShaderModuleCreateInfo createInfo({}, shaderCode.size(), reinterpret_cast<const uint32_t*>(shaderCode.data()));
		vk::ShaderModule shaderModule;
		if ((m_context.getDevice().createShaderModule(&createInfo, nullptr, &shaderModule)) != vk::Result::eSuccess) {
50
51
52
			throw std::runtime_error("Failed to create shader module!");
		}
		return shaderModule;
53
	}*/
54

55
	/*vk::PipelineShaderStageCreateInfo ShaderProgram::createShaderStage(vk::ShaderModule& shaderModule, vk::ShaderStageFlagBits shaderStage) {
56
		vk::PipelineShaderStageCreateInfo shaderStageInfo({}, shaderStage, shaderModule, "main", {});
57
58
59
60
		shaderStageInfo.stage = shaderStage;
		shaderStageInfo.module = shaderModule;
		shaderStageInfo.pName = "main";
		return shaderStageInfo;
61
	}*/
62
63
64
65
	
	ShaderProgram::~ShaderProgram() {
	}

66
67
	ShaderProgram ShaderProgram::create() {
		return ShaderProgram();
68
69
	}

70
	void ShaderProgram::addShader(ShaderProgram::ShaderStage shaderStage, const std::string& filepath) {
71
72
73
74
75
		if (containsShaderStage(shaderStage)) {
			throw std::runtime_error("Shader program already contains this particular shader stage.");
		}
		else {
			auto shaderCode = readFile(filepath);
76
            vk::ShaderStageFlagBits convertedShaderStage = convertToShaderStageFlagBits(shaderStage);
77
78
79
80
81
			//vk::ShaderModule shaderModule = createShaderModule(shaderCode);
			//vk::PipelineShaderStageCreateInfo shaderInfo = createShaderStage(shaderModule, shaderStage);
			//m_shaderStagesList.push_back(shaderInfo);
			//m_context.getDevice().destroyShaderModule(shaderModule, nullptr);
			m_shaderStages.shaderCode.push_back(shaderCode);
82
			m_shaderStages.shaderStageFlag.push_back(convertedShaderStage);
83
84
85
		}
	}

86
	bool ShaderProgram::containsShaderStage(ShaderProgram::ShaderStage shaderStage) const{
87
88
89
        vk::ShaderStageFlagBits convertedShaderStage = convertToShaderStageFlagBits(shaderStage);
		for (int i = 0; i < m_shaderStages.shaderStageFlag.size(); i++) {
			if (m_shaderStages.shaderStageFlag[i] == convertedShaderStage) {
90
91
92
93
94
95
				return true;
			}
		}
		return false;
	}

96
97
98
99
100
101
	bool ShaderProgram::deleteShaderStage(ShaderProgram::ShaderStage shaderStage) {
        vk::ShaderStageFlagBits convertedShaderStage = convertToShaderStageFlagBits(shaderStage);
		for (int i = 0; i < m_shaderStages.shaderStageFlag.size() - 1; i++) {
			if (m_shaderStages.shaderStageFlag[i] == convertedShaderStage) {
			    m_shaderStages.shaderStageFlag.erase(m_shaderStages.shaderStageFlag.begin() + i);
                m_shaderStages.shaderCode.erase(m_shaderStages.shaderCode.begin() + i);
102
103
104
105
106
107
				return true;
			}
		}
		return false;
	}

108
	std::vector<vk::ShaderStageFlagBits> ShaderProgram::getShaderStages() const{
109
110
111
		return m_shaderStages.shaderStageFlag;
	}

112
    std::vector<std::vector<char>> ShaderProgram::getShaderCode() const {
113
	    return m_shaderStages.shaderCode;
114
115
	}

116
	int ShaderProgram::getShaderStagesCount() const {
117
		return m_shaderStages.shaderStageFlag.size();
118
119
	}
}