mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-10-28 10:04:37 +08:00
swscale/uops: add SWS_UOP_FLAG_PUNNING
The current CPU-based backends don't suffer any penalty or consequence of intermixing integers and float operations on the same registers. However, this is not a universal assumption - in particular, SPIR-V expects fully typed operations. In theory, older x86 CPUs also have a penalty for switching from float to int, but ENOCARE. Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
1 parent
215351c1c3
commit
1c03b758a3
8 files changed
+25
-13
No files matched your search
@@ -225,7 +225,9 @@ static int aarch64_compile(SwsContext *ctx, const SwsOpList *ops,
|
||||
if (!uops)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
const SwsUOpFlags flags = (ctx->flags & SWS_BITEXACT) ? 0 : SWS_UOP_FLAG_FMA;
|
||||
SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING;
|
||||
if (!(ctx->flags & SWS_BITEXACT))
|
||||
flags |= SWS_UOP_FLAG_FMA;
|
||||
int ret = ff_sws_ops_translate(ctx, ops, flags, uops);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
@@ -41,7 +41,8 @@ static int print_ops(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
|
||||
|
||||
const SwsUOpFlags flags = SWS_UOP_FLAG_EXPAND_BIT
|
||||
| SWS_UOP_FLAG_READ_PALETTE
|
||||
| SWS_UOP_FLAG_ADD;
|
||||
| SWS_UOP_FLAG_ADD
|
||||
| SWS_UOP_FLAG_PUNNING;
|
||||
int ret = ff_sws_ops_translate(ctx, ops, flags, uops);
|
||||
if (ret == AVERROR(ENOTSUP))
|
||||
goto fail;
|
||||
|
||||
@@ -201,7 +201,9 @@ static int collect_ops_compile(SwsContext *ctx, const SwsOpList *ops,
|
||||
if (!uops)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
const SwsUOpFlags flags = (ctx->flags & SWS_BITEXACT) ? 0 : SWS_UOP_FLAG_FMA;
|
||||
SwsUOpFlags flags = SWS_UOP_FLAG_PUNNING;
|
||||
if (!(ctx->flags & SWS_BITEXACT))
|
||||
flags |= SWS_UOP_FLAG_FMA;
|
||||
ret = ff_sws_ops_translate(ctx, ops, flags, uops);
|
||||
if (ret == AVERROR(ENOTSUP)) {
|
||||
ret = 0;
|
||||
|
||||
+11
-7
@@ -206,8 +206,12 @@ int ff_sws_dither_height(const SwsDitherUOp *dither)
|
||||
return (1 << dither->size_log2) + max_offset;
|
||||
}
|
||||
|
||||
static SwsPixelType pixel_type_to_int(const SwsPixelType type)
|
||||
/* Conditionally promotes a pixel type to integer only if allowed by the flags */
|
||||
static SwsPixelType pixel_type_to_int(SwsUOpFlags flags, const SwsPixelType type)
|
||||
{
|
||||
if (!(flags & SWS_UOP_FLAG_PUNNING))
|
||||
return type;
|
||||
|
||||
switch (ff_sws_pixel_type_size(type)) {
|
||||
case 1: return SWS_PIXEL_U8;
|
||||
case 2: return SWS_PIXEL_U16;
|
||||
@@ -274,7 +278,7 @@ static int translate_rw_op(SwsContext *ctx, SwsUOpList *ops, SwsUOpFlags flags,
|
||||
|
||||
/* Non-filtered reads don't care about the exact pixel contents */
|
||||
if (!op->rw.filter.op)
|
||||
uop.type = pixel_type_to_int(op->rw.type);
|
||||
uop.type = pixel_type_to_int(flags, op->rw.type);
|
||||
|
||||
const bool is_read = op->op == SWS_OP_READ;
|
||||
if (op->rw.filter.op) {
|
||||
@@ -327,11 +331,11 @@ static int count_idx(const int *arr, size_t size, int val)
|
||||
return num;
|
||||
}
|
||||
|
||||
static int translate_swizzle(SwsUOpList *ops, const SwsOp *op)
|
||||
static int translate_swizzle(SwsUOpList *ops, SwsUOpFlags flags, const SwsOp *op)
|
||||
{
|
||||
SwsUOp uop = {
|
||||
.uop = SWS_UOP_PERMUTE,
|
||||
.type = pixel_type_to_int(ff_sws_op_input_type(op)),
|
||||
.type = pixel_type_to_int(flags, ff_sws_op_input_type(op)),
|
||||
.mask = ff_sws_comp_mask_needed(op),
|
||||
};
|
||||
SwsMoveUOp *par = &uop.par.move;
|
||||
@@ -524,7 +528,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
|
||||
case SWS_OP_WRITE:
|
||||
return translate_rw_op(ctx, uops, flags, op);
|
||||
case SWS_OP_SWIZZLE:
|
||||
return translate_swizzle(uops, op);
|
||||
return translate_swizzle(uops, flags, op);
|
||||
case SWS_OP_DITHER:
|
||||
return translate_dither_op(uops, flags, op);
|
||||
case SWS_OP_LINEAR:
|
||||
@@ -573,7 +577,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
|
||||
const AVRational64 v = op->clear.value[i];
|
||||
const SwsPixelType type = op->clear.type[i];
|
||||
const SwsPixel px = ff_sws_pixel_from_q64(type, v);
|
||||
uop.type = pixel_type_to_int(type);
|
||||
uop.type = pixel_type_to_int(flags, type);
|
||||
uop.data.vec4[i] = px;
|
||||
if (v.num == 0)
|
||||
uop.par.clear.zero |= SWS_COMP(i);
|
||||
@@ -596,7 +600,7 @@ static int translate_op(SwsContext *ctx, SwsUOpList *uops, SwsUOpFlags flags,
|
||||
break;
|
||||
case SWS_OP_SWAP_BYTES:
|
||||
uop.uop = SWS_UOP_SWAP_BYTES;
|
||||
uop.type = pixel_type_to_int(uop.type);
|
||||
uop.type = pixel_type_to_int(flags, uop.type);
|
||||
break;
|
||||
case SWS_OP_LUT_3D:
|
||||
uop.uop = SWS_UOP_LUT_3D;
|
||||
|
||||
@@ -152,6 +152,7 @@ typedef enum SwsUOpFlagBits {
|
||||
SWS_UOP_FLAG_EXPAND_BIT = (1 << 2), /* backend implements SWS_UOP_EXPAND_BIT */
|
||||
SWS_UOP_FLAG_READ_PALETTE = (1 << 3), /* backend implements SWS_UOP_READ_PALETTE */
|
||||
SWS_UOP_FLAG_ADD = (1 << 4), /* backend implements SWS_UOP_ADD */
|
||||
SWS_UOP_FLAG_PUNNING = (1 << 5), /* allow type punning float data as int */
|
||||
} SwsUOpFlagBits;
|
||||
|
||||
typedef enum SwsUOpType {
|
||||
|
||||
@@ -187,7 +187,8 @@ static int compile_c(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out)
|
||||
|
||||
const SwsUOpFlags flags = SWS_UOP_FLAG_EXPAND_BIT
|
||||
| SWS_UOP_FLAG_READ_PALETTE
|
||||
| SWS_UOP_FLAG_ADD;
|
||||
| SWS_UOP_FLAG_ADD
|
||||
| SWS_UOP_FLAG_PUNNING;
|
||||
int ret = ff_sws_ops_translate(ctx, ops, flags, uops);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -217,7 +217,7 @@ fail:
|
||||
|
||||
enum {
|
||||
COMMON_FLAGS = SWS_UOP_FLAG_EXPAND_BIT | SWS_UOP_FLAG_READ_PALETTE |
|
||||
SWS_UOP_FLAG_ADD,
|
||||
SWS_UOP_FLAG_ADD | SWS_UOP_FLAG_PUNNING,
|
||||
};
|
||||
|
||||
typedef struct Backend {
|
||||
|
||||
@@ -726,7 +726,8 @@ static int compile_x86(SwsContext *ctx, const SwsOpList *ops, SwsCompiledOp *out
|
||||
SwsUOpFlags flags = SWS_UOP_FLAG_PSHUFB
|
||||
| SWS_UOP_FLAG_EXPAND_BIT
|
||||
| SWS_UOP_FLAG_READ_PALETTE
|
||||
| SWS_UOP_FLAG_ADD;
|
||||
| SWS_UOP_FLAG_ADD
|
||||
| SWS_UOP_FLAG_PUNNING;
|
||||
if (EXTERNAL_FMA3(cpu_flags))
|
||||
flags |= SWS_UOP_FLAG_FMA;
|
||||
|
||||
|
||||
Reference in new issue
Block a user