Shader objects finally allow completely independent shaders. --- libavutil/vulkan.c | 51 +++++++++++++++++++++++++++++++++++++++++++--- libavutil/vulkan.h | 5 ++--- 2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index 71581b91a9..8b1c1eb796 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -1601,6 +1601,41 @@ static int init_compute_pipeline(FFVulkanContext *s, FFVulkanShader *shd, return 0; } +static int create_shader_object(FFVulkanContext *s, FFVulkanShader *shd, + uint8_t *spirv, size_t spirv_len, + const char *entrypoint) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + VkShaderCreateInfoEXT shader_obj_create = { + .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT, + .flags = shd->subgroup_info.requiredSubgroupSize ? + VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT : 0x0, + .stage = shd->stage, + .nextStage = 0, + .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT, + .pCode = spirv, + .codeSize = spirv_len, + .pName = entrypoint, + .pSetLayouts = shd->desc_layout, + .setLayoutCount = shd->nb_descriptor_sets, + .pushConstantRangeCount = shd->push_consts_num, + .pPushConstantRanges = shd->push_consts, + .pSpecializationInfo = NULL, + }; + + ret = vk->CreateShadersEXT(s->hwctx->act_dev, 1, &shader_obj_create, + s->hwctx->alloc, &shd->object); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to create shader object: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; +} + static int init_descriptors(FFVulkanContext *s, FFVulkanShader *shd) { VkResult ret; @@ -1690,7 +1725,11 @@ int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, shd->bound_buffer_indices[i] = i; } - { + if (s->extensions & FF_VK_EXT_SHADER_OBJECT) { + err = create_shader_object(s, shd, spirv, spirv_len, entrypoint); + if (err < 0) + return err; + } else { VkShaderModule mod; err = create_shader_module(s, shd, &mod, spirv, spirv_len); if (err < 0) @@ -2181,8 +2220,12 @@ void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, VkDeviceSize offsets[1024]; FFVulkanShaderData *sd = get_shd_data(e, shd); - /* Bind pipeline */ - vk->CmdBindPipeline(e->buf, shd->bind_point, shd->pipeline); + if (s->extensions & FF_VK_EXT_SHADER_OBJECT) { + VkShaderStageFlagBits stages = shd->stage; + vk->CmdBindShadersEXT(e->buf, 1, &stages, &shd->object); + } else { + vk->CmdBindPipeline(e->buf, shd->bind_point, shd->pipeline); + } if (sd->nb_descriptor_sets) { if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { @@ -2216,6 +2259,8 @@ void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd) s->hwctx->alloc); #endif + if (shd->object) + vk->DestroyShaderEXT(s->hwctx->act_dev, shd->object, s->hwctx->alloc); if (shd->pipeline) vk->DestroyPipeline(s->hwctx->act_dev, shd->pipeline, s->hwctx->alloc); if (shd->pipeline_layout) diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h index 5391afa4e7..47684e600d 100644 --- a/libavutil/vulkan.h +++ b/libavutil/vulkan.h @@ -194,9 +194,8 @@ typedef struct FFVulkanShader { VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info; /* Base shader object */ - union { - VkPipeline pipeline; - }; + VkShaderEXT object; + VkPipeline pipeline; /* Pipeline layout */ VkPipelineLayout pipeline_layout; -- 2.45.2.753.g447d99e1c3b _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".