Skip to content

Commit 10eb030

Browse files
authored
Merge pull request #35 from FunMiles/shader_specialization
Shader specialization
2 parents 2099e54 + 33f50b8 commit 10eb030

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

examples/teapot/teapot.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ int main() {
141141
{
142142

143143
vku::PipelineMaker pm{window.width(), window.height()};
144-
pm.shader(vk::ShaderStageFlagBits::eVertex, final_vert);
144+
pm.shader(vk::ShaderStageFlagBits::eVertex, final_vert, {{0,3}});
145145
pm.shader(vk::ShaderStageFlagBits::eFragment, final_frag);
146146
pm.vertexBinding(0, (uint32_t)sizeof(Vertex));
147147
pm.vertexAttribute(0, 0, vk::Format::eR32G32B32Sfloat, (uint32_t)offsetof(Vertex, pos));

examples/teapot/teapot.vert

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#version 450
2-
2+
layout (constant_id = 0) const int xF = 1;
33
layout(location = 0) in vec3 inPosition;
44
layout(location = 1) in vec3 inNormal;
55
layout(location = 2) in vec2 inUv;
@@ -26,6 +26,7 @@ out gl_PerVertex {
2626
void main() {
2727
// Get position in camera, light and world space.
2828
gl_Position = u.modelToPerspective * vec4(inPosition.xyz, 1.0);
29+
gl_Position.x *= xF;
2930
vec4 lightSpacePos = u.modelToLight * vec4(inPosition.xyz, 1.0);
3031
vec3 worldPos = (u.modelToWorld * vec4(inPosition.xyz, 1.0)).xyz;
3132

include/vku/vku.hpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,37 @@ class PipelineMaker {
860860
modules_.emplace_back(info);
861861
}
862862

863+
struct SpecEntry {
864+
uint32_t constantID;
865+
uint32_t value;
866+
};
867+
/// Add a shader module with specialized constants to the pipeline.
868+
void shader(vk::ShaderStageFlagBits stage, vku::ShaderModule &shader,
869+
std::initializer_list<SpecEntry> specEntries,
870+
const char *entryPoint = "main") {
871+
auto data = std::unique_ptr<SpecData>{new SpecData};
872+
uint32_t offset = 0;
873+
data->data_size_ = specEntries.size()*sizeof(uint32_t);
874+
data->data_ = std::unique_ptr<char[]>(new char[data->data_size_]);
875+
for (auto &entry : specEntries) {
876+
data->specializationMapEntries_.emplace_back(
877+
entry.constantID, offset, sizeof(uint32_t));
878+
*reinterpret_cast<int32_t *>(data->data_.get() + offset) = entry.value;
879+
offset += sizeof(uint32_t);
880+
}
881+
data->specializationInfo_.mapEntryCount = specEntries.size();
882+
data->specializationInfo_.pMapEntries = data->specializationMapEntries_.data();
883+
data->specializationInfo_.dataSize = data->data_size_;
884+
data->specializationInfo_.pData = data->data_.get();
885+
vk::PipelineShaderStageCreateInfo info{};
886+
info.module = shader.module();
887+
info.pName = entryPoint;
888+
info.stage = stage;
889+
info.pSpecializationInfo = &data->specializationInfo_;
890+
modules_.emplace_back(info);
891+
moduleSpecializations_.emplace_back(std::move(data));
892+
}
893+
863894
/// Add a blend state to the pipeline for one colour attachment.
864895
/// If you don't do this, a default is used.
865896
void colorBlend(const vk::PipelineColorBlendAttachmentState &state) {
@@ -1012,6 +1043,13 @@ class PipelineMaker {
10121043
vk::PipelineColorBlendStateCreateInfo colorBlendState_;
10131044
std::vector<vk::PipelineColorBlendAttachmentState> colorBlendAttachments_;
10141045
std::vector<vk::PipelineShaderStageCreateInfo> modules_;
1046+
struct SpecData {
1047+
vk::SpecializationInfo specializationInfo_;
1048+
std::vector<vk::SpecializationMapEntry> specializationMapEntries_;
1049+
std::unique_ptr<char []> data_;
1050+
size_t data_size_;
1051+
};
1052+
std::vector<std::unique_ptr<SpecData>> moduleSpecializations_;
10151053
std::vector<vk::VertexInputAttributeDescription> vertexAttributeDescriptions_;
10161054
std::vector<vk::VertexInputBindingDescription> vertexBindingDescriptions_;
10171055
std::vector<vk::DynamicState> dynamicState_;

include/vku/vku_framework.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,8 @@ class Window {
407407
device.waitForFences(cbFence, 1, umax);
408408
device.resetFences(cbFence);
409409

410-
std::array<float, 4> clearColorValue{0.75f, 0.75f, 0.75f, 1};
411410
vk::ClearDepthStencilValue clearDepthValue{ 1.0f, 0 };
412-
std::array<vk::ClearValue, 2> clearColours{vk::ClearValue{clearColorValue}, clearDepthValue};
411+
std::array<vk::ClearValue, 2> clearColours{vk::ClearValue{clearColorValue()}, clearDepthValue};
413412
vk::RenderPassBeginInfo rpbi;
414413
rpbi.renderPass = *renderPass_;
415414
rpbi.framebuffer = *framebuffers_[imageIndex];
@@ -643,6 +642,8 @@ class Window {
643642

644643
vk::Device device() const { return device_; }
645644

645+
std::array<float,4> &clearColorValue() { return clearColorValue_; }
646+
646647
private:
647648
vk::Instance instance_;
648649
vk::PhysicalDevice physicalDevice_;
@@ -670,6 +671,7 @@ class Window {
670671
uint32_t presentQueueFamily_ = 0;
671672
uint32_t width_;
672673
uint32_t height_;
674+
std::array<float, 4> clearColorValue_{0.75f, 0.75f, 0.75f, 1};
673675
vk::Format swapchainImageFormat_ = vk::Format::eB8G8R8A8Unorm;
674676
vk::ColorSpaceKHR swapchainColorSpace_ = vk::ColorSpaceKHR::eSrgbNonlinear;
675677
vk::Device device_;

0 commit comments

Comments
 (0)