Archived
1
Fork 0

Make fragment shader stage optional

Removes the fragment on (normal) shadow pass
This commit is contained in:
redstrate 2021-02-04 09:36:06 -05:00
parent 0b9a376c24
commit ae599ba744
3 changed files with 62 additions and 46 deletions

View file

@ -607,8 +607,13 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
VkShaderModule vertex_module = VK_NULL_HANDLE, fragment_module = VK_NULL_HANDLE; VkShaderModule vertex_module = VK_NULL_HANDLE, fragment_module = VK_NULL_HANDLE;
const bool has_vertex_stage = !info.shaders.vertex_path.empty() || !info.shaders.vertex_src.empty();
const bool has_fragment_stage = !info.shaders.fragment_path.empty() || !info.shaders.fragment_src.empty();
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
if (has_vertex_stage) {
const bool vertex_use_shader_source = info.shaders.vertex_path.empty(); const bool vertex_use_shader_source = info.shaders.vertex_path.empty();
const bool fragment_use_shader_source = info.shaders.fragment_path.empty();
if (vertex_use_shader_source) { if (vertex_use_shader_source) {
auto& vertex_shader_vector = info.shaders.vertex_src.as_bytecode(); auto& vertex_shader_vector = info.shaders.vertex_src.as_bytecode();
@ -622,6 +627,20 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
vertex_module = createShaderModule(vertex_shader->cast_data<uint32_t>(), vertex_shader->size()); vertex_module = createShaderModule(vertex_shader->cast_data<uint32_t>(), vertex_shader->size());
} }
name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)vertex_module, info.shaders.vertex_path);
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vertex_module;
vertShaderStageInfo.pName = "main";
shaderStages.push_back(vertShaderStageInfo);
}
if (has_fragment_stage) {
const bool fragment_use_shader_source = info.shaders.fragment_path.empty();
if (fragment_use_shader_source) { if (fragment_use_shader_source) {
auto& fragment_shader_vector = info.shaders.fragment_src.as_bytecode(); auto& fragment_shader_vector = info.shaders.fragment_src.as_bytecode();
@ -634,22 +653,16 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
fragment_module = createShaderModule(fragment_shader->cast_data<uint32_t>(), fragment_shader->size()); fragment_module = createShaderModule(fragment_shader->cast_data<uint32_t>(), fragment_shader->size());
} }
name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)vertex_module, info.shaders.vertex_path);
name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)fragment_module, info.shaders.fragment_path); name_object(device, VK_OBJECT_TYPE_SHADER_MODULE, (uint64_t)fragment_module, info.shaders.fragment_path);
VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vertex_module;
vertShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo fragShaderStageInfo = {}; VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
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";
VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo }; shaderStages.push_back(fragShaderStageInfo);
}
// setup vertex inputs/bindings // setup vertex inputs/bindings
std::vector<VkVertexInputBindingDescription> inputs; std::vector<VkVertexInputBindingDescription> inputs;
@ -688,7 +701,6 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
if (info.rasterization.primitive_type == GFXPrimitiveType::TriangleStrip) if (info.rasterization.primitive_type == GFXPrimitiveType::TriangleStrip)
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
VkPipelineViewportStateCreateInfo viewportState = {}; VkPipelineViewportStateCreateInfo viewportState = {};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1; viewportState.viewportCount = 1;
@ -816,8 +828,8 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
// create pipeline // create pipeline
VkGraphicsPipelineCreateInfo pipelineInfo = {}; VkGraphicsPipelineCreateInfo pipelineInfo = {};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2; pipelineInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
pipelineInfo.pStages = shaderStages; pipelineInfo.pStages = shaderStages.data();
pipelineInfo.pVertexInputState = &vertexInputInfo; pipelineInfo.pVertexInputState = &vertexInputInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly; pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState; pipelineInfo.pViewportState = &viewportState;
@ -839,14 +851,14 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline->handle); vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline->handle);
name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, std::string(info.shaders.vertex_path.data()) + std::string(info.shaders.fragment_path.data()));
name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)pipeline->layout, std::string(info.shaders.vertex_path.data()) + std::string(info.shaders.fragment_path.data()));
if (info.label.empty()) if (info.label.empty())
pipeline->label = std::string(info.shaders.vertex_path.data()) + std::string(info.shaders.fragment_path.data()); pipeline->label = std::string(info.shaders.vertex_path) + std::string(info.shaders.fragment_path);
else else
pipeline->label = info.label; pipeline->label = info.label;
name_object(device, VK_OBJECT_TYPE_PIPELINE, (uint64_t)pipeline->handle, pipeline->label);
name_object(device, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)pipeline->layout, pipeline->label);
return pipeline; return pipeline;
} }

View file

@ -322,7 +322,7 @@ void ShadowPass::create_pipelines() {
pipelineInfo.shaders.vertex_path = "shadow.vert"; pipelineInfo.shaders.vertex_path = "shadow.vert";
pipelineInfo.shaders.fragment_constants = { point_light_max_constant }; pipelineInfo.shaders.fragment_constants = { point_light_max_constant };
pipelineInfo.shaders.fragment_path = "shadow.frag"; //pipelineInfo.shaders.fragment_path = "shadow.frag";
pipelineInfo.shader_input.bindings = { pipelineInfo.shader_input.bindings = {
{0, GFXBindingType::PushConstant}, {0, GFXBindingType::PushConstant},

View file

@ -37,12 +37,12 @@ public:
/// Represents the source code of a shader either in plaintext (GLSL, MSL) or bytecode (SPIR-V). /// Represents the source code of a shader either in plaintext (GLSL, MSL) or bytecode (SPIR-V).
class ShaderSource { class ShaderSource {
public: public:
ShaderSource() {} ShaderSource() : source(std::monostate()) {}
ShaderSource(const ShaderSource& rhs) : source (rhs.source) {} ShaderSource(const ShaderSource& rhs) : source (rhs.source) {}
ShaderSource(const std::string source_string) : source(source_string) {} ShaderSource(const std::string source_string) : source(source_string) {}
ShaderSource(const std::vector<uint32_t> source_bytecode) : source(source_bytecode) {} ShaderSource(const std::vector<uint32_t> source_bytecode) : source(source_bytecode) {}
std::variant<std::string, std::vector<uint32_t>> source; std::variant<std::monostate, std::string, std::vector<uint32_t>> source;
/// Returns a view of the shader source as plaintext. /// Returns a view of the shader source as plaintext.
std::string_view as_string() const { std::string_view as_string() const {
@ -53,6 +53,10 @@ public:
std::vector<uint32_t> as_bytecode() const { std::vector<uint32_t> as_bytecode() const {
return std::get<std::vector<uint32_t>>(source); return std::get<std::vector<uint32_t>>(source);
} }
bool empty() const {
return std::holds_alternative<std::monostate>(source);
}
}; };
/// Compiles GLSL shaders to a specified shader language offline or at runtime. /// Compiles GLSL shaders to a specified shader language offline or at runtime.