Add shader constant support for Vulkan
This commit is contained in:
parent
4e0f92014a
commit
ad29cf3174
2 changed files with 63 additions and 9 deletions
|
@ -144,13 +144,13 @@ struct GFXShaderBinding {
|
||||||
|
|
||||||
struct GFXShaderConstant {
|
struct GFXShaderConstant {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
enum class Type {
|
enum class Type {
|
||||||
Integer
|
Integer
|
||||||
} type;
|
} type = Type::Integer;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int value;
|
int value = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -774,7 +774,29 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
|
||||||
|
|
||||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||||
|
|
||||||
if (has_vertex_stage) {
|
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) {
|
||||||
const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path();
|
const bool vertex_use_shader_source = !info.shaders.vertex_src.is_path();
|
||||||
|
|
||||||
if (vertex_use_shader_source) {
|
if (vertex_use_shader_source) {
|
||||||
|
@ -797,9 +819,24 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
|
||||||
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_fragment_stage) {
|
if (has_fragment_stage) {
|
||||||
const bool fragment_use_shader_source = !info.shaders.fragment_src.is_path();
|
const bool fragment_use_shader_source = !info.shaders.fragment_src.is_path();
|
||||||
|
@ -824,6 +861,21 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
|
||||||
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
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;
|
||||||
|
@ -1381,7 +1434,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_
|
||||||
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
VkIndexType indexType = VK_INDEX_TYPE_UINT32;
|
||||||
if (command.data.set_index_buffer.index_type == IndexType::UINT16)
|
if (command.data.set_index_buffer.index_type == IndexType::UINT16)
|
||||||
indexType = VK_INDEX_TYPE_UINT16;
|
indexType = VK_INDEX_TYPE_UINT16;
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(cmd, ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer)->handle, 0, indexType);
|
vkCmdBindIndexBuffer(cmd, ((GFXVulkanBuffer*)command.data.set_index_buffer.buffer)->handle, 0, indexType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1390,7 +1443,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_
|
||||||
VkShaderStageFlags applicableStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
VkShaderStageFlags applicableStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
if(is_compute)
|
if(is_compute)
|
||||||
applicableStages = VK_SHADER_STAGE_COMPUTE_BIT;
|
applicableStages = VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
|
|
||||||
if(currentPipeline != nullptr)
|
if(currentPipeline != nullptr)
|
||||||
vkCmdPushConstants(cmd, currentPipeline->layout, applicableStages , 0, command.data.set_push_constant.size, command.data.set_push_constant.bytes.data());
|
vkCmdPushConstants(cmd, currentPipeline->layout, applicableStages , 0, command.data.set_push_constant.size, command.data.set_push_constant.bytes.data());
|
||||||
}
|
}
|
||||||
|
@ -1401,7 +1454,7 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const platform::window_
|
||||||
bsb.buffer = command.data.bind_shader_buffer.buffer;
|
bsb.buffer = command.data.bind_shader_buffer.buffer;
|
||||||
bsb.offset = command.data.bind_shader_buffer.offset;
|
bsb.offset = command.data.bind_shader_buffer.offset;
|
||||||
bsb.size = command.data.bind_shader_buffer.size;
|
bsb.size = command.data.bind_shader_buffer.size;
|
||||||
|
|
||||||
boundShaderBuffers[command.data.bind_shader_buffer.index] = bsb;
|
boundShaderBuffers[command.data.bind_shader_buffer.index] = bsb;
|
||||||
}
|
}
|
||||||
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:
|
||||||
|
|
Reference in a new issue