Archived
1
Fork 0

Add shader constant support for Vulkan

This commit is contained in:
Joshua Goins 2022-02-07 15:15:09 -05:00
parent 4e0f92014a
commit ad29cf3174
2 changed files with 63 additions and 9 deletions

View file

@ -147,10 +147,10 @@ struct GFXShaderConstant {
enum class Type { enum class Type {
Integer Integer
} type; } type = Type::Integer;
union { union {
int value; int value = 0;
}; };
}; };

View file

@ -774,6 +774,28 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
std::vector<VkPipelineShaderStageCreateInfo> shaderStages; std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
VkSpecializationInfo vertex_specialization_info;
std::vector<VkSpecializationMapEntry> vertex_map_entries;
VkSpecializationInfo fragment_specialization_info;
std::vector<VkSpecializationMapEntry> fragment_map_entries;
const auto fill_map_entries = [](const GFXShaderConstants& constants, std::vector<VkSpecializationMapEntry>& entries) {
for(int i = 0; i < constants.size(); i++) {
// TODO: we only support int specializations (which is okay right now)
VkSpecializationMapEntry entry = {};
entry.constantID = constants[i].index;
entry.size = sizeof(int);
entry.offset = sizeof(int) * i;
entries.push_back(entry);
}
};
std::vector<int> vertex_data;
std::vector<int> fragment_data;
if (has_vertex_stage) { if (has_vertex_stage) {
const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path(); const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path();
@ -798,6 +820,21 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
vertShaderStageInfo.module = vertex_module; vertShaderStageInfo.module = vertex_module;
vertShaderStageInfo.pName = "main"; vertShaderStageInfo.pName = "main";
if(!info.shaders.vertex_constants.empty()) {
fill_map_entries(info.shaders.vertex_constants, vertex_map_entries);
vertex_specialization_info.mapEntryCount = vertex_map_entries.size();
vertex_specialization_info.pMapEntries = vertex_map_entries.data();
for(auto constant : info.shaders.vertex_constants) {
vertex_data.push_back(constant.value);
}
vertex_specialization_info.dataSize = vertex_data.size() * sizeof(int);
vertex_specialization_info.pData = vertex_data.data();
vertShaderStageInfo.pSpecializationInfo = &vertex_specialization_info;
}
shaderStages.push_back(vertShaderStageInfo); shaderStages.push_back(vertShaderStageInfo);
} }
@ -825,6 +862,21 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
fragShaderStageInfo.module = fragment_module; fragShaderStageInfo.module = fragment_module;
fragShaderStageInfo.pName = "main"; fragShaderStageInfo.pName = "main";
if(!info.shaders.fragment_constants.empty()) {
fill_map_entries(info.shaders.fragment_constants, fragment_map_entries);
fragment_specialization_info.mapEntryCount = fragment_map_entries.size();
fragment_specialization_info.pMapEntries = fragment_map_entries.data();
for(auto constant : info.shaders.fragment_constants) {
fragment_data.push_back(constant.value);
}
fragment_specialization_info.dataSize = fragment_data.size() * sizeof(int);
fragment_specialization_info.pData = fragment_data.data();
fragShaderStageInfo.pSpecializationInfo = &fragment_specialization_info;
}
shaderStages.push_back(fragShaderStageInfo); shaderStages.push_back(fragShaderStageInfo);
} }
@ -1373,6 +1425,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_
{ {
VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->handle; VkBuffer buffer = ((GFXVulkanBuffer*)command.data.set_vertex_buffer.buffer)->handle;
VkDeviceSize offset = command.data.set_vertex_buffer.offset; VkDeviceSize offset = command.data.set_vertex_buffer.offset;
vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, &buffer, &offset); vkCmdBindVertexBuffers(cmd, command.data.set_vertex_buffer.index, 1, &buffer, &offset);
} }
break; break;
@ -1425,8 +1478,9 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_
break; break;
case GFXCommandType::DrawIndexed: case GFXCommandType::DrawIndexed:
{ {
if(try_bind_descriptor()) if(try_bind_descriptor()) {
vkCmdDrawIndexed(cmd, command.data.draw_indexed.index_count, 1, command.data.draw_indexed.first_index, command.data.draw_indexed.vertex_offset, 0); vkCmdDrawIndexed(cmd, command.data.draw_indexed.index_count, 1, command.data.draw_indexed.first_index, command.data.draw_indexed.vertex_offset, 0);
}
} }
break; break;
case GFXCommandType::SetDepthBias: case GFXCommandType::SetDepthBias: