SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
VulkanShader.cpp
Go to the documentation of this file.
2#include "vulkan/vulkan_core.h"
3#include <Core/Logger.hpp>
4#include <cstdint>
5#include <vector>
6#include <fstream>
7
8namespace Sleak {
9 namespace RenderEngine {
10
12 if(device && vertShader)
13 vkDestroyShaderModule(device, vertShader, nullptr);
14 if(device && fragShader)
15 vkDestroyShaderModule(device, fragShader, nullptr);
16}
17
18bool VulkanShader::compile(const std::string& path) {
19 // Strip .hlsl extension if present, then use .vert.spv/.frag.spv
20 std::string basePath = path;
21 auto hlslPos = basePath.rfind(".hlsl");
22 if (hlslPos != std::string::npos) {
23 basePath = basePath.substr(0, hlslPos);
24 }
25 return compile(basePath + ".vert.spv", basePath + ".frag.spv");
26}
27
28bool VulkanShader::compile(const std::string& vert, const std::string& frag) {
29
30 if(!device)
31 SLEAK_RETURN_ERR("Shader codes cannot be compiled without a device!")
32
33 auto vertCode = ReadFile(vert);
34 auto fragCode = ReadFile(frag);
35
36 if(vertCode.empty() || fragCode.empty())
37 SLEAK_RETURN_ERR("Could not read shader files!");
38
39 vertShader = createShaderModule(vertCode);
40 if(!vertShader)
41 SLEAK_RETURN_ERR("Failed to create vertex shader!");
42
43 fragShader = createShaderModule(fragCode);
44 if(!fragShader)
45 SLEAK_RETURN_ERR("Failed to create fragment shader!");
46
47 vertexInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
48 vertexInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
49 vertexInfo.module = vertShader;
50 vertexInfo.pSpecializationInfo = nullptr;
51 vertexInfo.pName = "main";
52
53 fragmentInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
54 fragmentInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
55 fragmentInfo.module = fragShader;
56 fragmentInfo.pSpecializationInfo = nullptr;
57 fragmentInfo.pName = "main";
58
59 return true;
60}
61
62bool VulkanShader::compileVertexOnly(const std::string& vertPath) {
63 if (!device)
64 SLEAK_RETURN_ERR("Shader codes cannot be compiled without a device!")
65
66 auto vertCode = ReadFile(vertPath);
67 if (vertCode.empty())
68 SLEAK_RETURN_ERR("Could not read vertex shader file!");
69
70 vertShader = createShaderModule(vertCode);
71 if (!vertShader)
72 SLEAK_RETURN_ERR("Failed to create vertex shader!");
73
74 vertexInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
75 vertexInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
76 vertexInfo.module = vertShader;
77 vertexInfo.pSpecializationInfo = nullptr;
78 vertexInfo.pName = "main";
79
80 return true;
81}
82
83VkShaderModule VulkanShader::LoadSPIRV(const char* path) {
84 auto code = ReadFile(path);
85 if (code.empty()) return VK_NULL_HANDLE;
86 return createShaderModule(code);
87}
88
90
91}
92
93VkShaderModule VulkanShader::createShaderModule(const std::vector<char>& code) {
94 VkShaderModule module;
95
96 VkShaderModuleCreateInfo ShaderInfo{};
97 ShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
98 ShaderInfo.codeSize = code.size();
99 ShaderInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
100
101 VkResult result = vkCreateShaderModule(device, &ShaderInfo, nullptr, &module);
102
103 if(result != VK_SUCCESS)
104 return nullptr;
105
106 return module;
107}
108
109std::vector<char> VulkanShader::ReadFile(const std::string& path) {
110 std::ifstream file(path, std::ios::ate | std::ios::binary);
111
112 if (!file.is_open())
113 {
114 SLEAK_ERROR("Can't read {}", path);
115 return std::vector<char>(0);
116 }
117
118 size_t size = (size_t) file.tellg();
119 std::vector<char> buffer(size);
120
121 file.seekg(0);
122 file.read(buffer.data(), size);
123
124 file.close();
125
126 return buffer;
127}
128
129
130 }
131}
#define SLEAK_ERROR(...)
Definition Logger.hpp:22
#define SLEAK_RETURN_ERR(...)
Definition Logger.hpp:25
virtual void bind() override
No-op: Vulkan binds shader stages via pipeline creation, not a runtime bind call.
VkShaderModule LoadSPIRV(const char *path)
Reads a .spv file and creates a VkShaderModule from it.
bool compileVertexOnly(const std::string &vertPath)
Loads only the vertex stage (used for depth-only/shadow pipelines with no fragment shader).
virtual bool compile(const std::string &shaderPath) override
Loads the combined-path convention's .vert.spv/.frag.spv pair.
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10