Commit c94ffc7432 for ffmpeg
commit c94ffc7432dd232dceef463bf1fc53d70b103d97
Author: Niklas Haas <git@haasn.dev>
Date: Wed Oct 21 18:12:51 2026 +0200
swscale/vulkan/ops: decorate bit-exact linear ops with NoContraction inline
Instead of reserving space for the decorations up front and patching them
in later, based on a separately computed instruction count, decorate each
instruction as it is emitted.
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 e8ae946307..614fa29fda 100644
--- a/libswscale/vulkan/ops.c
+++ b/libswscale/vulkan/ops.c
@@ -325,8 +325,6 @@ typedef struct LinearIDs {
int mat; /* full matrix, only valid without SWS_BITEXACT */
int off[4]; /* offset coefficients */
int off_vec;
- int deco_off; /* space reserved for NoContraction decorations */
- int nb_deco;
} LinearIDs;
/* Constants and buffers used by a single op */
@@ -463,25 +461,8 @@ static int emit_convert(SPICtx *spi, SwsPixelType from, SwsPixelType to,
: spi_OpConvertUToF(spi, res_type, a);
}
-/* Number of arithmetic instructions emitted by insert_bitexact_linear() */
-static int bitexact_linear_nb_ops(const SwsLinearOp *lin)
-{
- int nb_ops = 0;
- for (int j = 0; j < 4; j++) {
- bool acc = lin->m[j][4].num;
- for (int i = 0; i < 4; i++) {
- if (!lin->m[j][i].num)
- continue;
- nb_ops += 1 + acc; /* multiplication, and addition if needed */
- acc = true;
- }
- }
- return nb_ops;
-}
-
/* Section 1: Function to define all shader header data, and decorations */
-static void define_shader_header(SwsContext *sws, const SwsOpList *ops,
- SPICtx *spi, SPIRVIDs *id)
+static void define_shader_header(SPICtx *spi, SPIRVIDs *id)
{
spi_OpCapability(spi, SpvCapabilityShader); /* Shader type */
@@ -522,21 +503,6 @@ static void define_shader_header(SwsContext *sws, const SwsOpList *ops,
spi_OpDecorate(spi, f->id, SpvDecorationDescriptorSet, 1);
spi_OpDecorate(spi, f->id, SpvDecorationBinding, f->binding);
}
-
- if (!(sws->flags & SWS_BITEXACT))
- return;
-
- /* All linear arithmetic ops must be decorated with NoContraction */
- for (int n = 0; n < ops->num_ops; n++) {
- const SwsOp *op = &ops->ops[n];
- if (op->op != SWS_OP_LINEAR)
- continue;
-
- const int nb_ops = bitexact_linear_nb_ops(&op->lin);
- LinearIDs *lin = &id->op[n].lin;
- lin->deco_off = spi_reserve(spi, SPI_SECTION_DECORATIONS, nb_ops*4*3);
- lin->nb_deco = nb_ops;
- }
}
/* Section 2: Define all types and constants */
@@ -841,14 +807,6 @@ static int insert_bitexact_linear(const SwsOp *op, SPICtx *spi, SPIRVIDs *id,
tmp[2] = spi_OpCompositeExtract(spi, type_s, data, 2);
tmp[3] = spi_OpCompositeExtract(spi, type_s, data, 3);
- SPISectionBuf *deco = &spi->sec[SPI_SECTION_DECORATIONS];
- const int off = deco->off;
- deco->off = lin->deco_off;
- for (int i = 0; i < lin->nb_deco; i++)
- spi_OpDecorate(spi, spi->id + i, SpvDecorationNoContraction);
- deco->off = off;
- const int first_id = spi->id;
-
/* Same evaluation order as the C backend: offset first, then each column
* from left to right, skipping zero coefficients */
int res[4];
@@ -860,14 +818,16 @@ static int insert_bitexact_linear(const SwsOp *op, SPICtx *spi, SPIRVIDs *id,
continue;
int v = spi_OpFMul(spi, type_s, tmp[i], lin->m[j][i]);
- res[j] = acc ? spi_OpFAdd(spi, type_s, res[j], v) : v;
+ spi_OpDecorate(spi, v, SpvDecorationNoContraction);
+ if (acc) {
+ v = spi_OpFAdd(spi, type_s, res[j], v);
+ spi_OpDecorate(spi, v, SpvDecorationNoContraction);
+ }
+ res[j] = v;
acc = true;
}
}
- /* The decorations above assume one ID per arithmetic op */
- av_assert0(spi->id - first_id == lin->nb_deco);
-
return spi_OpCompositeConstruct(spi, type_v,
res[0], res[1], res[2], res[3]);
}
@@ -1087,7 +1047,7 @@ static int emit_shader(SwsContext *sws, VulkanPriv *p, FFVulkanOpsCtx *s,
nb_data_bufs, 1);
/* Define shader header sections */
- define_shader_header(sws, ops, spi, id);
+ define_shader_header(spi, id);
define_shader_consts(sws, ops, spi, id);
define_shader_bindings(ops, spi, id, in_img_count, out_img_count);
diff --git a/libswscale/vulkan/spvasm.h b/libswscale/vulkan/spvasm.h
index d455e59850..17e8d851fe 100644
--- a/libswscale/vulkan/spvasm.h
+++ b/libswscale/vulkan/spvasm.h
@@ -200,15 +200,6 @@ static inline int spi_end(const SPICtx *spi, uint8_t **out)
return len;
}
-/* Reserves space in the given section, returns its offset */
-static inline int spi_reserve(SPICtx *spi, SPISection s, int len)
-{
- SPISectionBuf *sec = &spi->sec[s];
- if (!spi_append(sec, len))
- return 0;
- return sec->off - len;
-}
-
static inline void spi_OpCapability(SPICtx *spi, SpvCapability capability)
{
SPISectionBuf *sec = spi_begin(spi, 2, 17);