]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/program_backend.cpp
Support compute shaders and compute operations
[libs/gl.git] / source / backends / vulkan / program_backend.cpp
index 61b5efaefd93f4b96fdef3892cf09fc9ff29468b..993a3e38ef965d11b838fb9b41653cb2fe5b3b29 100644 (file)
@@ -19,9 +19,11 @@ VulkanProgram::VulkanProgram():
 VulkanProgram::VulkanProgram(VulkanProgram &&other):
        device(other.device),
        n_stages(other.n_stages),
+       stage_flags(other.stage_flags),
        creation_info(move(other.creation_info)),
        desc_set_layout_handles(move(other.desc_set_layout_handles)),
-       layout_handle(other.layout_handle)
+       layout_handle(other.layout_handle),
+       debug_name(move(other.debug_name))
 {
        other.desc_set_layout_handles.clear();
        other.layout_handle = 0;
@@ -42,7 +44,7 @@ bool VulkanProgram::has_stages() const
        return n_stages;
 }
 
-void VulkanProgram::add_glsl_stages(const GlslModule &, const map<string, int> &, TransientData &)
+void VulkanProgram::add_glsl_stages(const GlslModule &, const map<string, int> &)
 {
        throw invalid_operation("VulkanProgram::add_glsl_stages");
 }
@@ -57,11 +59,11 @@ void VulkanProgram::add_spirv_stages(const SpirVModule &mod, const map<string, i
                entry_names_size += e.name.size()+1;
 
        StructureBuilder sb(creation_info, 5);
-       VkPipelineShaderStageCreateInfo *&stage_infos = sb.add<VkPipelineShaderStageCreateInfo>(n_stages);
-       char *&name_table = sb.add<char>(entry_names_size);
-       VkSpecializationInfo *&spec_info = sb.add<VkSpecializationInfo>();
-       VkSpecializationMapEntry *&spec_map = sb.add<VkSpecializationMapEntry>(spec_values.size());
-       int *&spec_data = sb.add<int>(spec_values.size());
+       VkPipelineShaderStageCreateInfo *const &stage_infos = sb.add<VkPipelineShaderStageCreateInfo>(n_stages);
+       char *const &name_table = sb.add<char>(entry_names_size);
+       VkSpecializationInfo *const &spec_info = sb.add<VkSpecializationInfo>();
+       VkSpecializationMapEntry *const &spec_map = sb.add<VkSpecializationMapEntry>(spec_values.size());
+       int *const &spec_data = sb.add<int>(spec_values.size());
 
        unsigned i = 0;
        for(const SpirVModule::Constant &c: mod.get_spec_constants())
@@ -86,8 +88,11 @@ void VulkanProgram::add_spirv_stages(const SpirVModule &mod, const map<string, i
        i = 0;
        for(const SpirVModule::EntryPoint &e: entry_points)
        {
+               unsigned stage_bit = get_vulkan_stage(e.stage);
+               stage_flags |= stage_bit;
+
                stage_infos[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-               stage_infos[i].stage = static_cast<VkShaderStageFlagBits>(get_vulkan_stage(e.stage));
+               stage_infos[i].stage = static_cast<VkShaderStageFlagBits>(stage_bit);
                stage_infos[i].module = handle_cast<::VkShaderModule>(mod.handle);
                strcpy(name_ptr, e.name.c_str());
                stage_infos[i].pName = name_ptr;
@@ -95,6 +100,12 @@ void VulkanProgram::add_spirv_stages(const SpirVModule &mod, const map<string, i
                stage_infos[i].pSpecializationInfo = spec_info;
                ++i;
        }
+
+#if DEBUG
+       if(!debug_name.empty())
+               if(SpirVModule *spirv = static_cast<Program *>(this)->specialized_spirv)
+                       spirv->set_debug_name(debug_name);
+#endif
 }
 
 void VulkanProgram::finalize_uniforms()
@@ -114,10 +125,10 @@ void VulkanProgram::finalize_uniforms()
                        {
                                bindings.emplace_back();
                                VkDescriptorSetLayoutBinding &binding = bindings.back();
-                               binding.binding = b.bind_point;
+                               binding.binding = b.bind_point&0xFFFFF;
                                binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
                                binding.descriptorCount = 1;
-                               binding.stageFlags = VK_SHADER_STAGE_ALL;
+                               binding.stageFlags = stage_flags;
                                binding.pImmutableSamplers = 0;
                        }
 
@@ -126,10 +137,13 @@ void VulkanProgram::finalize_uniforms()
                        {
                                bindings.emplace_back();
                                VkDescriptorSetLayoutBinding &binding = bindings.back();
-                               binding.binding = u.binding;
-                               binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+                               binding.binding = u.binding&0xFFFFF;
+                               if(is_sampled_image(u.type))
+                                       binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+                               else
+                                       binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
                                binding.descriptorCount = 1;
-                               binding.stageFlags = VK_SHADER_STAGE_ALL;
+                               binding.stageFlags = stage_flags;
                                binding.pImmutableSamplers = 0;
                        }
 
@@ -142,7 +156,7 @@ void VulkanProgram::finalize_uniforms()
        }
 
        VkPushConstantRange push_const_range = { };
-       push_const_range.stageFlags = VK_SHADER_STAGE_ALL;
+       push_const_range.stageFlags = stage_flags;
        push_const_range.offset = 0;
        push_const_range.size = (push_const_block ? push_const_block->data_size : 0);
 
@@ -154,6 +168,53 @@ void VulkanProgram::finalize_uniforms()
        layout_info.pPushConstantRanges = &push_const_range;
 
        vk.CreatePipelineLayout(layout_info, layout_handle);
+
+#if DEBUG
+       if(!debug_name.empty())
+               set_vulkan_object_name();
+#endif
+}
+
+bool VulkanProgram::is_compute() const
+{
+       return stage_flags&VK_SHADER_STAGE_COMPUTE_BIT;
+}
+
+void VulkanProgram::set_debug_name(const string &name)
+{
+#ifdef DEBUG
+       debug_name = name;
+       set_vulkan_object_name();
+       if(SpirVModule *spirv = static_cast<Program *>(this)->specialized_spirv)
+               spirv->set_debug_name(debug_name);
+#else
+       (void)name;
+#endif
+}
+
+void VulkanProgram::set_vulkan_object_name() const
+{
+#ifdef DEBUG
+       const VulkanFunctions &vk = device.get_functions();
+
+       string layout_name = debug_name+" [layout]";
+
+       VkDebugUtilsObjectNameInfoEXT name_info = { };
+       name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+       name_info.objectType = VK_OBJECT_TYPE_PIPELINE_LAYOUT;
+       name_info.objectHandle = reinterpret_cast<uint64_t>(layout_handle);
+       name_info.pObjectName = layout_name.c_str();
+       vk.SetDebugUtilsObjectName(name_info);
+
+       name_info.objectType = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT;
+       for(unsigned i=0; i<desc_set_layout_handles.size(); ++i)
+       {
+               layout_name = format("%s [layout:%d]", debug_name, i);
+       name_info.objectHandle = reinterpret_cast<uint64_t>(desc_set_layout_handles[i]);
+               name_info.pObjectName = layout_name.c_str();
+               vk.SetDebugUtilsObjectName(name_info);
+       }
+#endif
 }
 
 } // namespace GL