| 51 | } |
| 52 | |
| 53 | bool ShaderModule::loadFromBytecode(VkDevice device, const QByteArray &bytecode, const QString &entryPoint) |
| 54 | { |
| 55 | Q_ASSERT(device); |
| 56 | |
| 57 | destroy(); |
| 58 | |
| 59 | m_device = device; |
| 60 | m_entryPoint = entryPoint.toLocal8Bit(); |
| 61 | |
| 62 | VkShaderModuleCreateInfo createInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; |
| 63 | createInfo.codeSize = static_cast<unsigned long>(bytecode.size()); |
| 64 | createInfo.pCode = reinterpret_cast<const uint32_t*>(bytecode.data()); |
| 65 | |
| 66 | Result result; |
| 67 | if(VKFAILED(result = vkCreateShaderModule(m_device, &createInfo, nullptr, &m_module))) { |
| 68 | qCCritical(logVulkan) << "Failed to create Vulkan shader module from SPIR-V binary:" << result.toString(); |
| 69 | return false; |
| 70 | } |
| 71 | |
| 72 | spv_reflect::ShaderModule spvModule(static_cast<size_t>(bytecode.size()), bytecode.data()); |
| 73 | m_stage = static_cast<VkShaderStageFlagBits>(spvModule.GetShaderStage()); |
| 74 | |
| 75 | uint32_t descriptorSetCount = 0; |
| 76 | spvModule.EnumerateDescriptorSets(&descriptorSetCount, nullptr); |
| 77 | if(descriptorSetCount > 0) { |
| 78 | QVector<SpvReflectDescriptorSet*> descriptorSets(static_cast<int>(descriptorSetCount)); |
| 79 | spvModule.EnumerateDescriptorSets(&descriptorSetCount, descriptorSets.data()); |
| 80 | m_descriptorSets.reserve(static_cast<int>(descriptorSetCount)); |
| 81 | for(const SpvReflectDescriptorSet *spvReflectDescriptorSet : descriptorSets) { |
| 82 | DescriptorSetLayout descriptorSet = { spvReflectDescriptorSet->set }; |
| 83 | descriptorSet.bindings.reserve(static_cast<int>(spvReflectDescriptorSet->binding_count)); |
| 84 | for(unsigned int i=0; i<spvReflectDescriptorSet->binding_count; ++i) { |
| 85 | const SpvReflectDescriptorBinding *spvReflectBinding = spvReflectDescriptorSet->bindings[i]; |
| 86 | DescriptorSetLayoutBinding binding; |
| 87 | binding.name = QString(spvReflectBinding->name); |
| 88 | binding.binding = spvReflectBinding->binding; |
| 89 | binding.type = static_cast<VkDescriptorType>(spvReflectBinding->descriptor_type); |
| 90 | binding.count = spvReflectBinding->count; |
| 91 | descriptorSet.bindings.append(binding); |
| 92 | } |
| 93 | m_descriptorSets.append(descriptorSet); |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | uint32_t pushConstantBlockCount = 0; |
| 98 | spvModule.EnumeratePushConstantBlocks(&pushConstantBlockCount, nullptr); |
| 99 | if(pushConstantBlockCount > 0) { |
| 100 | QVector<SpvReflectBlockVariable*> pushConstantBlocks(static_cast<int>(pushConstantBlockCount)); |
| 101 | spvModule.EnumeratePushConstantBlocks(&pushConstantBlockCount, pushConstantBlocks.data()); |
| 102 | m_pushConstants.reserve(static_cast<int>(pushConstantBlockCount)); |
| 103 | for(const SpvReflectBlockVariable *spvReflectPushConstantBlock : pushConstantBlocks) { |
| 104 | PushConstantRange range; |
| 105 | range.name = QString(spvReflectPushConstantBlock->name); |
| 106 | range.size = spvReflectPushConstantBlock->size; |
| 107 | range.offset = spvReflectPushConstantBlock->offset; |
| 108 | m_pushConstants.append(range); |
| 109 | } |
| 110 | } |
nothing calls this directly
no test coverage detected