KDGpu::ShaderModule
Module: Public API
Represents compiled shader code (SPIR-V) for a pipeline stage. More...
#include <KDGpu/shader_module.h>
Public Functions
Friends
Detailed Description
| class KDGpu::ShaderModule;
|
Represents compiled shader code (SPIR-V) for a pipeline stage.
Vulkan equivalent:VkShaderModule
ShaderModule wraps compiled SPIR-V shader bytecode. Shaders are written in GLSL or HLSL, compiled to SPIR-V format, and then loaded into shader modules for use in graphics or compute pipelines.
Key features:
- Encapsulates SPIR-V bytecode
- Reusable across multiple pipelines
- Supports all shader stages
- Entry point specification
Lifetime: ShaderModules are created by Device and must remain valid during pipeline creation. ShaderModules can be destroyed after all pipelines that use them have been created. They use RAII and clean up automatically.
Usage
Loading shader from file:
| std::vector<uint32_t> loadSpirv(const std::string &filepath)
{
std::ifstream file(filepath, std::ios::binary | std::ios::ate);
if (!file.is_open())
return {};
size_t fileSize = static_cast<size_t>(file.tellg());
std::vector<uint32_t> buffer(fileSize / sizeof(uint32_t));
file.seekg(0);
file.read(reinterpret_cast<char *>(buffer.data()), fileSize);
return buffer;
}
|
Filename: kdgpu_doc_snippets.cpp
| std::vector<uint32_t> spirvCode = loadSpirv("shader.vert.spv");
KDGpu::ShaderModule shader = device.createShaderModule(spirvCode);
|
Filename: kdgpu_doc_snippets.cpp
KDGpuExample::readShaderFile
Loading shader from SPIR-V data in memory:
| std::vector<uint32_t> vertexSpirv = { /* SPIR-V bytecode */ };
KDGpu::ShaderModule vertexShader = device.createShaderModule(vertexSpirv);
|
Filename: kdgpu_doc_snippets.cpp
Creating graphics pipeline with shaders:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | KDGpu::ShaderModule vertShader = device.createShaderModule(loadSpirv("shader.vert.spv"));
KDGpu::ShaderModule fragShader = device.createShaderModule(loadSpirv("shader.frag.spv"));
KDGpu::PipelineLayout pipelineLayout;
KDGpu::GraphicsPipeline pipelineShaders = device.createGraphicsPipeline(KDGpu::GraphicsPipelineOptions{
.shaderStages = {
{
.shaderModule = vertShader,
.stage = KDGpu::ShaderStageFlagBits::VertexBit,
},
{
.shaderModule = fragShader,
.stage = KDGpu::ShaderStageFlagBits::FragmentBit,
},
},
.layout = pipelineLayout,
// ... other pipeline options ...
});
|
Filename: kdgpu_doc_snippets.cpp
Creating compute pipeline with shader:
| KDGpu::ShaderModule computeShader = device.createShaderModule(loadSpirv("compute.comp.spv"));
KDGpu::ComputePipeline computePipeline = device.createComputePipeline(KDGpu::ComputePipelineOptions{
.layout = pipelineLayout,
.shaderStage = {
.shaderModule = computeShader,
},
});
|
Filename: kdgpu_doc_snippets.cpp
Using specialization constants:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | KDGpu::ShaderModule shaderSpec = device.createShaderModule(loadSpirv("shader.frag.spv"));
KDGpu::GraphicsPipeline pipelineSpec = device.createGraphicsPipeline(KDGpu::GraphicsPipelineOptions{
.shaderStages = {
{
.shaderModule = shaderSpec.handle(),
.stage = KDGpu::ShaderStageFlagBits::FragmentBit,
.specializationConstants = {
{ .constantId = 0, .value = 4u }, // NUM_LIGHTS
{ .constantId = 1, .value = true }, // ENABLE_SHADOWS
{ .constantId = 2, .value = 2.2f }, // GAMMA
},
},
},
.layout = pipelineLayout,
// ... other options ...
});
|
Filename: kdgpu_doc_snippets.cpp
Reusing shaders across pipelines:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 | KDGpu::ShaderModule vertShader = device.createShaderModule(vertSpirv);
KDGpu::ShaderModule fragShader = device.createShaderModule(fragSpirv);
// Use same shaders for multiple pipelines with different state
KDGpu::PipelineLayout pipelineLayout;
KDGpu::Format swapchainFormat = KDGpu::Format::B8G8R8A8_SRGB;
KDGpu::GraphicsPipeline opaquePipeline = device.createGraphicsPipeline(KDGpu::GraphicsPipelineOptions{
.shaderStages = {
{
.shaderModule = vertShader,
.stage = KDGpu::ShaderStageFlagBits::VertexBit,
},
{
.shaderModule = fragShader,
.stage = KDGpu::ShaderStageFlagBits::FragmentBit,
},
},
.layout = pipelineLayout,
.renderTargets = {
{
.format = swapchainFormat,
},
},
});
KDGpu::GraphicsPipeline transparentPipeline = device.createGraphicsPipeline(KDGpu::GraphicsPipelineOptions{
.shaderStages = {
{
.shaderModule = vertShader,
.stage = KDGpu::ShaderStageFlagBits::VertexBit,
},
{
.shaderModule = fragShader,
.stage = KDGpu::ShaderStageFlagBits::FragmentBit,
},
},
.layout = pipelineLayout,
.renderTargets = {
{
.format = swapchainFormat,
},
},
});
|
Filename: kdgpu_doc_snippets.cpp
Geometry shader example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | KDGpu::ShaderModule geomShader = device.createShaderModule(geomSpirv);
KDGpu::GraphicsPipeline pipeline = device.createGraphicsPipeline(KDGpu::GraphicsPipelineOptions{
.shaderStages = {
{
.shaderModule = vertShader,
.stage = KDGpu::ShaderStageFlagBits::VertexBit,
},
{
.shaderModule = geomShader,
.stage = KDGpu::ShaderStageFlagBits::GeometryBit,
},
{
.shaderModule = fragShader,
.stage = KDGpu::ShaderStageFlagBits::FragmentBit,
},
},
.layout = pipelineLayout,
.renderTargets = {
{
.format = swapchainFormat,
},
},
});
|
Filename: kdgpu_doc_snippets.cpp
Compiling GLSL to SPIR-V:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | # Using glslangValidator
glslangValidator -V shader.vert -o shader.vert.spv
glslangValidator -V shader.frag -o shader.frag.spv
glslangValidator -V shader.comp -o shader.comp.spv
# Using glslc (from shaderc)
glslc shader.vert -o shader.vert.spv
glslc shader.frag -o shader.frag.spv
# Using KDGpu cmake helpers in a CMakeLists.txt
kdgpu_compileshader(ComputeShaderTarget particles.comp particles.comp.spv)
kdgpu_compileshaderset(VertexFragmentShaderTarget vertex) # looks for vertex.vert and vertex.frag, compiles to vertex.vert.spv and vertex.frag.spv
kdgpu_compilegeomshaderset(VertexGeomFragmentShaderTarget geom) # looks for geom.vert geom.geom and geom.frag, compiles to geom.vert.spv, geom.geom.spv and geom.frag.spv
kdgpu_compilemeshtaskshader(MeshShaderTarget mesh_shader.mesh mesh_shader.mesh.spv)
kdgpu_compilertshader(RtGenShaderTarget raygen.rgen raygen.spv)
|
Vulkan mapping:
- ShaderModule creation -> vkCreateShaderModule()
- Used in VkPipelineShaderStageCreateInfo
See also:
GraphicsPipeline, ComputePipeline, Device, PipelineLayout
KDGpu API Overview
KDGpu to Vulkan API Mapping
Public Functions Documentation
function ShaderModule
function ~ShaderModule
function ShaderModule
| ShaderModule(
ShaderModule && other
)
|
function operator=
| ShaderModule & operator=(
ShaderModule && other
)
|
function ShaderModule
| ShaderModule(
const ShaderModule &
) =delete
|
function operator=
| ShaderModule & operator=(
const ShaderModule &
) =delete
|
function handle
| inline Handle< ShaderModule_t > handle() const
|
function isValid
| inline bool isValid() const
|
function operator Handle< ShaderModule_t >
| inline operator Handle< ShaderModule_t >() const
|
Friends
friend Device
| friend class Device(
Device
);
|
Updated on 2026-03-31 at 00:02:07 +0000