Commit 46679b0626 for ffmpeg
commit 46679b062607ea8798e67ffeac47f31b35991aee
Author: Niklas Haas <git@haasn.dev>
Date: Wed Oct 21 18:09:49 2026 +0200
swscale/vulkan/ops: define interface variables together with their decorations
Instead of pre-allocating their IDs, define the variables and decorate
them in one place, and emit the entry point last, once all interface
variables are known.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c
index e3886666e9..e8ae946307 100644
--- a/libswscale/vulkan/ops.c
+++ b/libswscale/vulkan/ops.c
@@ -480,8 +480,8 @@ static int bitexact_linear_nb_ops(const SwsLinearOp *lin)
}
/* Section 1: Function to define all shader header data, and decorations */
-static void define_shader_header(SwsContext *sws, FFVulkanShader *shd,
- const SwsOpList *ops, SPICtx *spi, SPIRVIDs *id)
+static void define_shader_header(SwsContext *sws, const SwsOpList *ops,
+ SPICtx *spi, SPIRVIDs *id)
{
spi_OpCapability(spi, SpvCapabilityShader); /* Shader type */
@@ -495,34 +495,6 @@ static void define_shader_header(SwsContext *sws, FFVulkanShader *shd,
/* Next section starts here */
spi_OpMemoryModel(spi, SpvAddressingModelLogical, SpvMemoryModelGLSL450);
- /* Entrypoint */
- id->ep = spi_OpEntryPoint(spi, SpvExecutionModelGLCompute, "main",
- id->iface, id->nb_iface);
- spi_OpExecutionMode(spi, id->ep, SpvExecutionModeLocalSize,
- shd->lg_size, 3);
-
- if (id->interlaced) {
- spi_OpDecorate(spi, id->push_const_struct_id, SpvDecorationBlock);
- spi_OpMemberDecorate(spi, id->push_const_struct_id, 0,
- SpvDecorationOffset, 0);
- }
-
- /* gl_GlobalInvocationID descriptor decorations */
- spi_OpDecorate(spi, id->gid_var, SpvDecorationBuiltIn,
- SpvBuiltInGlobalInvocationId);
-
- /* Input image descriptor decorations */
- if (id->in_img_var) {
- spi_OpDecorate(spi, id->in_img_var, SpvDecorationNonWritable);
- spi_OpDecorate(spi, id->in_img_var, SpvDecorationDescriptorSet, 0);
- spi_OpDecorate(spi, id->in_img_var, SpvDecorationBinding, 0);
- }
-
- /* Output image descriptor decorations */
- spi_OpDecorate(spi, id->out_img_var, SpvDecorationNonReadable);
- spi_OpDecorate(spi, id->out_img_var, SpvDecorationDescriptorSet, 0);
- spi_OpDecorate(spi, id->out_img_var, SpvDecorationBinding, 1);
-
for (int i = 0; i < id->nb_dither_bufs; i++) {
spi_OpDecorate(spi, id->dither[i].arr_1d_id, SpvDecorationArrayStride,
sizeof(float));
@@ -801,26 +773,54 @@ static void define_shader_bindings(const SwsOpList *ops, SPICtx *spi, SPIRVIDs *
}
/* Define inputs */
- spi_OpVariable(spi, id->gid_var, id->u32vec3_tptr,
- SpvStorageClassInput, 0);
+ id->gid_var = spi_OpVariable(spi, spi_get_id(spi), id->u32vec3_tptr,
+ SpvStorageClassInput, 0);
+ id->iface[id->nb_iface++] = id->gid_var;
+ spi_OpDecorate(spi, id->gid_var, SpvDecorationBuiltIn,
+ SpvBuiltInGlobalInvocationId);
+
if (op_r) {
- spi_OpVariable(spi, id->in_img_var, id->in_img_tptr,
- SpvStorageClassUniformConstant, 0);
+ id->in_img_var = spi_OpVariable(spi, spi_get_id(spi), id->in_img_tptr,
+ SpvStorageClassUniformConstant, 0);
+ id->iface[id->nb_iface++] = id->in_img_var;
+ spi_OpDecorate(spi, id->in_img_var, SpvDecorationNonWritable);
+ spi_OpDecorate(spi, id->in_img_var, SpvDecorationDescriptorSet, 0);
+ spi_OpDecorate(spi, id->in_img_var, SpvDecorationBinding, 0);
}
- spi_OpVariable(spi, id->out_img_var, id->out_img_tptr,
- SpvStorageClassUniformConstant, 0);
+
+ id->out_img_var = spi_OpVariable(spi, spi_get_id(spi), id->out_img_tptr,
+ SpvStorageClassUniformConstant, 0);
+ id->iface[id->nb_iface++] = id->out_img_var;
+ spi_OpDecorate(spi, id->out_img_var, SpvDecorationNonReadable);
+ spi_OpDecorate(spi, id->out_img_var, SpvDecorationDescriptorSet, 0);
+ spi_OpDecorate(spi, id->out_img_var, SpvDecorationBinding, 1);
if (id->interlaced) {
+ id->push_const_struct_id = spi_get_id(spi);
spi_OpTypeStruct(spi, id->push_const_struct_id, id->u32_type);
+ spi_OpDecorate(spi, id->push_const_struct_id, SpvDecorationBlock);
+ spi_OpMemberDecorate(spi, id->push_const_struct_id, 0,
+ SpvDecorationOffset, 0);
id->push_const_ptr_id = spi_OpTypePointer(spi, SpvStorageClassPushConstant,
id->push_const_struct_id);
id->push_const_elem_ptr_id = spi_OpTypePointer(spi, SpvStorageClassPushConstant,
id->u32_type);
- spi_OpVariable(spi, id->push_const_var_id, id->push_const_ptr_id,
- SpvStorageClassPushConstant, 0);
+ id->push_const_var_id = spi_OpVariable(spi, spi_get_id(spi),
+ id->push_const_ptr_id,
+ SpvStorageClassPushConstant, 0);
+ id->iface[id->nb_iface++] = id->push_const_var_id;
}
}
+/* Must be called after all interface variables have been defined */
+static void define_entry_point(FFVulkanShader *shd, SPICtx *spi, SPIRVIDs *id)
+{
+ spi_OpEntryPoint(spi, SpvExecutionModelGLCompute, id->ep, "main",
+ id->iface, id->nb_iface);
+ spi_OpExecutionMode(spi, id->ep, SpvExecutionModeLocalSize,
+ shd->lg_size, 3);
+}
+
static int insert_vmat_linear(SPICtx *spi, SPIRVIDs *id, const LinearIDs *lin,
int data)
{
@@ -1033,12 +1033,6 @@ static int emit_shader(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
if (err < 0)
return err;
- /* Entrypoint inputs; gl_GlobalInvocationID, input and output images, dither */
- id->gid_var = id->iface[id->nb_iface++] = spi_get_id(spi);
- if (op_r)
- id->in_img_var = id->iface[id->nb_iface++] = spi_get_id(spi);
- id->out_img_var = id->iface[id->nb_iface++] = spi_get_id(spi);
-
/* Create dither and filter buffer descriptor set. Both are collected in
* op order, so the bindings match the buffer order from create_bufs().*/
id->nb_dither_bufs = 0;
@@ -1092,17 +1086,13 @@ static int emit_shader(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
ff_vk_shader_add_descriptor_set(&s->vkctx, shd, buf_desc,
nb_data_bufs, 1);
- if (id->interlaced) {
- id->push_const_struct_id = spi_get_id(spi);
- id->push_const_var_id = id->iface[id->nb_iface++] = spi_get_id(spi);
- }
-
/* Define shader header sections */
- define_shader_header(sws, shd, ops, spi, id);
+ define_shader_header(sws, ops, spi, id);
define_shader_consts(sws, ops, spi, id);
define_shader_bindings(ops, spi, id, in_img_count, out_img_count);
/* Main function starts here */
+ id->ep = spi_get_id(spi);
spi_OpFunction(spi, id->ep, id->void_type, 0, id->void_fn_type);
spi_OpLabel(spi, spi_get_id(spi));
@@ -1337,6 +1327,8 @@ static int emit_shader(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
/* Return and finalize */
spi_OpReturn(spi);
spi_OpFunctionEnd(spi);
+
+ define_entry_point(shd, spi, id);
return 0;
}
diff --git a/libswscale/vulkan/spvasm.h b/libswscale/vulkan/spvasm.h
index 51909c29a1..d455e59850 100644
--- a/libswscale/vulkan/spvasm.h
+++ b/libswscale/vulkan/spvasm.h
@@ -463,16 +463,16 @@ OP_1SRC(OpReturnValue, 254)
spi_op_res_2src_list(spi, 82, spi_get_id(spi), res_type, src1, src2, \
SPI_ARGS(__VA_ARGS__))
-static inline int spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model,
- const char *name, const int *args, int nb_args)
+static inline void spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model,
+ int entry_point_id, const char *name,
+ const int *args, int nb_args)
{
SPISectionBuf *sec = spi_begin(spi, (3 + nb_args) + spi_strl(name), 15);
spi_write_u32(sec, execution_model);
- spi_write_u32(sec, spi->id);
+ spi_write_u32(sec, entry_point_id);
spi_put_str(sec, name);
for (int i = 0; i < nb_args; i++)
spi_write_u32(sec, args[i]);
- return spi_get_id(spi);
}
static inline void spi_OpName(SPICtx *spi, int target_id, const char *name)