mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
vulkan_prores_raw: use compile-time SPIR-V generation
This commit is contained in:
@@ -3396,7 +3396,7 @@ mpeg4_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
mpeg4_videotoolbox_hwaccel_select="mpeg4_decoder"
|
||||
prores_videotoolbox_hwaccel_deps="videotoolbox"
|
||||
prores_videotoolbox_hwaccel_select="prores_decoder"
|
||||
prores_raw_vulkan_hwaccel_deps="vulkan spirv_library"
|
||||
prores_raw_vulkan_hwaccel_deps="vulkan"
|
||||
prores_raw_vulkan_hwaccel_select="prores_raw_decoder"
|
||||
prores_vulkan_hwaccel_deps="vulkan spirv_library"
|
||||
prores_vulkan_hwaccel_select="prores_decoder"
|
||||
@@ -4239,7 +4239,7 @@ cws2fws_extralibs="zlib_extralibs"
|
||||
|
||||
# libraries, in any order
|
||||
avcodec_deps="avutil"
|
||||
avcodec_suggest="libm stdatomic spirv_library"
|
||||
avcodec_suggest="libm stdatomic zlib spirv_library"
|
||||
avdevice_deps="avformat avcodec avutil"
|
||||
avdevice_suggest="libm stdatomic"
|
||||
avfilter_deps="avutil"
|
||||
|
||||
@@ -12,9 +12,8 @@ OBJS-$(CONFIG_FFV1_VULKAN_HWACCEL) += vulkan/common.o \
|
||||
vulkan/ffv1_common.o vulkan/ffv1_reset.o \
|
||||
vulkan/ffv1_dec_setup.o vulkan/ffv1_dec.o
|
||||
|
||||
OBJS-$(CONFIG_PRORES_RAW_VULKAN_HWACCEL) += vulkan/common.o vulkan/dct.o \
|
||||
vulkan/prores_raw_decode.o \
|
||||
vulkan/prores_raw_idct.o
|
||||
OBJS-$(CONFIG_PRORES_RAW_VULKAN_HWACCEL) += vulkan/prores_raw_decode.comp.spv.o \
|
||||
vulkan/prores_raw_idct.comp.spv.o
|
||||
|
||||
OBJS-$(CONFIG_PRORES_VULKAN_HWACCEL) += vulkan/common.o vulkan/dct.o \
|
||||
vulkan/prores_vld.o \
|
||||
|
||||
@@ -18,6 +18,35 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef VULKAN_COMMON_H
|
||||
#define VULKAN_COMMON_H
|
||||
|
||||
#pragma use_vulkan_memory_model
|
||||
|
||||
layout (local_size_x_id = 253, local_size_y_id = 254, local_size_z_id = 255) in;
|
||||
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int32 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_float32 : require
|
||||
#extension GL_EXT_shader_explicit_arithmetic_types_float64 : require
|
||||
#extension GL_EXT_shader_8bit_storage : require
|
||||
#extension GL_EXT_shader_16bit_storage : require
|
||||
|
||||
#extension GL_EXT_shader_image_load_formatted : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
#extension GL_EXT_scalar_block_layout : require
|
||||
#extension GL_EXT_buffer_reference : require
|
||||
#extension GL_EXT_buffer_reference2 : require
|
||||
#extension GL_KHR_memory_scope_semantics : require
|
||||
#extension GL_EXT_null_initializer : require
|
||||
|
||||
#extension GL_EXT_expect_assume : enable
|
||||
#extension GL_EXT_control_flow_attributes : enable
|
||||
|
||||
layout(buffer_reference, buffer_reference_align = 1) buffer u8buf {
|
||||
uint8_t v;
|
||||
};
|
||||
@@ -78,6 +107,9 @@ layout(buffer_reference, buffer_reference_align = 8) buffer u64buf {
|
||||
#define ceil_rshift(a, b) \
|
||||
(-((-(a)) >> (b)))
|
||||
|
||||
#define IS_WITHIN(v1, v2) \
|
||||
((v1.x < v2.x) && (v1.y < v2.y))
|
||||
|
||||
/* TODO: optimize */
|
||||
uint align(uint src, uint a)
|
||||
{
|
||||
@@ -336,3 +368,5 @@ int left_bits(in GetBitContext gb)
|
||||
{
|
||||
return int(gb.buf_end - gb.buf) * 8 + gb.bits_valid;
|
||||
}
|
||||
|
||||
#endif /* VULKAN_COMMON_H */
|
||||
|
||||
@@ -31,12 +31,22 @@
|
||||
* IEEE Transactions on Communications, Vol. 25, No. 9, pp 1004-1009, Sept. 1977
|
||||
*/
|
||||
|
||||
#ifndef VULKAN_DCT_H
|
||||
#define VULKAN_DCT_H
|
||||
|
||||
#ifndef NB_BLOCKS
|
||||
#define NB_BLOCKS 1
|
||||
#endif
|
||||
|
||||
#ifndef NB_COMPONENTS
|
||||
#define NB_COMPONENTS 1
|
||||
#endif
|
||||
|
||||
layout (constant_id = 16) const uint32_t nb_blocks = NB_BLOCKS;
|
||||
layout (constant_id = 17) const uint32_t nb_components = NB_COMPONENTS;
|
||||
|
||||
/* Padded by 1 row to avoid bank conflicts */
|
||||
shared float blocks[NB_BLOCKS][NB_COMPONENTS*8*(8 + 1)];
|
||||
shared float blocks[nb_blocks][nb_components*8*(8 + 1)];
|
||||
|
||||
const float idct_scale[64] = {
|
||||
0.1250000000000000, 0.1733799806652684, 0.1633203706095471, 0.1469844503024199,
|
||||
@@ -117,3 +127,5 @@ void idct8(uint block, uint offset, uint stride)
|
||||
blocks[block][6*stride + offset] = u6;
|
||||
blocks[block][7*stride + offset] = u7;
|
||||
}
|
||||
|
||||
#endif /* VULKAN_DCT_H */
|
||||
|
||||
+24
@@ -20,6 +20,30 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "common.comp"
|
||||
|
||||
struct TileData {
|
||||
ivec2 pos;
|
||||
uint offset;
|
||||
uint size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 0) uniform writeonly uimage2D dst;
|
||||
layout (set = 0, binding = 1, scalar) readonly buffer frame_data_buf {
|
||||
TileData tile_data[];
|
||||
};
|
||||
|
||||
layout (push_constant, scalar) uniform pushConstants {
|
||||
u8buf pkt_data;
|
||||
ivec2 frame_size;
|
||||
ivec2 tile_size;
|
||||
uint8_t qmat[64];
|
||||
};
|
||||
|
||||
#define COMP_ID (gl_LocalInvocationID.x)
|
||||
|
||||
GetBitContext gb;
|
||||
@@ -20,6 +20,31 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#version 460
|
||||
#pragma shader_stage(compute)
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "common.comp"
|
||||
#include "dct.comp"
|
||||
|
||||
struct TileData {
|
||||
ivec2 pos;
|
||||
uint offset;
|
||||
uint size;
|
||||
};
|
||||
|
||||
layout (set = 0, binding = 0) uniform uimage2D dst;
|
||||
layout (set = 0, binding = 1, scalar) readonly buffer frame_data_buf {
|
||||
TileData tile_data[];
|
||||
};
|
||||
|
||||
layout (push_constant, scalar) uniform pushConstants {
|
||||
u8buf pkt_data;
|
||||
ivec2 frame_size;
|
||||
ivec2 tile_size;
|
||||
uint8_t qmat[64];
|
||||
};
|
||||
|
||||
#define COMP_ID (gl_LocalInvocationID.z)
|
||||
#define BLOCK_ID (gl_LocalInvocationID.y)
|
||||
#define ROW_ID (gl_LocalInvocationID.x)
|
||||
@@ -22,13 +22,13 @@
|
||||
#include "hwaccel_internal.h"
|
||||
|
||||
#include "prores_raw.h"
|
||||
#include "libavutil/vulkan_spirv.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
extern const char *ff_source_common_comp;
|
||||
extern const char *ff_source_dct_comp;
|
||||
extern const char *ff_source_prores_raw_decode_comp;
|
||||
extern const char *ff_source_prores_raw_idct_comp;
|
||||
extern const unsigned char ff_prores_raw_decode_comp_spv_data[];
|
||||
extern const unsigned int ff_prores_raw_decode_comp_spv_len;
|
||||
|
||||
extern const unsigned char ff_prores_raw_idct_comp_spv_data[];
|
||||
extern const unsigned int ff_prores_raw_idct_comp_spv_len;
|
||||
|
||||
const FFVulkanDecodeDescriptor ff_vk_dec_prores_raw_desc = {
|
||||
.codec_id = AV_CODEC_ID_PRORES_RAW,
|
||||
@@ -287,46 +287,19 @@ fail:
|
||||
static int add_common_data(AVCodecContext *avctx, FFVulkanContext *s,
|
||||
FFVulkanShader *shd, int writeonly)
|
||||
{
|
||||
AVHWFramesContext *dec_frames_ctx;
|
||||
dec_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
|
||||
|
||||
/* Common codec header */
|
||||
GLSLD(ff_source_common_comp);
|
||||
|
||||
GLSLC(0, struct TileData { );
|
||||
GLSLC(1, ivec2 pos; );
|
||||
GLSLC(1, uint offset; );
|
||||
GLSLC(1, uint size; );
|
||||
GLSLC(0, }; );
|
||||
GLSLC(0, );
|
||||
GLSLC(0, layout(push_constant, scalar) uniform pushConstants { );
|
||||
GLSLC(1, u8buf pkt_data; );
|
||||
GLSLC(1, ivec2 frame_size; );
|
||||
GLSLC(1, ivec2 tile_size; );
|
||||
GLSLC(1, uint8_t qmat[64]; );
|
||||
GLSLC(0, }; );
|
||||
GLSLC(0, );
|
||||
ff_vk_shader_add_push_const(shd, 0, sizeof(DecodePushData),
|
||||
VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
|
||||
FFVulkanDescriptorSetBinding *desc_set;
|
||||
desc_set = (FFVulkanDescriptorSetBinding []) {
|
||||
FFVulkanDescriptorSetBinding desc_set[] = {
|
||||
{
|
||||
.name = "dst",
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.mem_layout = ff_vk_shader_rep_fmt(dec_frames_ctx->sw_format,
|
||||
FF_VK_REP_NATIVE),
|
||||
.mem_quali = writeonly ? "writeonly" : NULL,
|
||||
.dimensions = 2,
|
||||
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.name = "dst",
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
},
|
||||
{
|
||||
.name = "frame_data_buf",
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.mem_layout = "scalar",
|
||||
.mem_quali = "readonly",
|
||||
.buf_content = "TileData tile_data[];",
|
||||
.name = "frame_data_buf",
|
||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -334,74 +307,49 @@ static int add_common_data(AVCodecContext *avctx, FFVulkanContext *s,
|
||||
}
|
||||
|
||||
static int init_decode_shader(AVCodecContext *avctx, FFVulkanContext *s,
|
||||
FFVkExecPool *pool, FFVkSPIRVCompiler *spv,
|
||||
FFVulkanShader *shd, int version)
|
||||
FFVkExecPool *pool, FFVulkanShader *shd,
|
||||
int version)
|
||||
{
|
||||
int err;
|
||||
uint8_t *spv_data;
|
||||
size_t spv_len;
|
||||
void *spv_opaque = NULL;
|
||||
|
||||
RET(ff_vk_shader_init(s, shd, "prores_raw",
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
(const char *[]) { "GL_EXT_buffer_reference",
|
||||
"GL_EXT_buffer_reference2",
|
||||
"GL_EXT_null_initializer" }, 3,
|
||||
4, 1, 1, 0));
|
||||
ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, NULL,
|
||||
(uint32_t []) { 4, 1, 1 }, 0);
|
||||
|
||||
RET(add_common_data(avctx, s, shd, 1));
|
||||
add_common_data(avctx, s, shd, 1);
|
||||
|
||||
GLSLD(ff_source_prores_raw_decode_comp);
|
||||
|
||||
RET(spv->compile_shader(s, spv, shd, &spv_data, &spv_len, "main",
|
||||
&spv_opaque));
|
||||
RET(ff_vk_shader_link(s, shd, spv_data, spv_len, "main"));
|
||||
RET(ff_vk_shader_link(s, shd,
|
||||
ff_prores_raw_decode_comp_spv_data,
|
||||
ff_prores_raw_decode_comp_spv_len, "main"));
|
||||
|
||||
RET(ff_vk_shader_register_exec(s, pool, shd));
|
||||
|
||||
fail:
|
||||
if (spv_opaque)
|
||||
spv->free_shader(spv, &spv_opaque);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int init_idct_shader(AVCodecContext *avctx, FFVulkanContext *s,
|
||||
FFVkExecPool *pool, FFVkSPIRVCompiler *spv,
|
||||
FFVulkanShader *shd, int version)
|
||||
FFVkExecPool *pool, FFVulkanShader *shd,
|
||||
int version)
|
||||
{
|
||||
int err;
|
||||
uint8_t *spv_data;
|
||||
size_t spv_len;
|
||||
void *spv_opaque = NULL;
|
||||
SPEC_LIST_CREATE(sl, 2, 2*sizeof(uint32_t))
|
||||
|
||||
RET(ff_vk_shader_init(s, shd, "prores_raw",
|
||||
VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
(const char *[]) { "GL_EXT_buffer_reference",
|
||||
"GL_EXT_buffer_reference2" }, 2,
|
||||
8,
|
||||
version == 0 ? 8 : 16 /* Horizontal blocks */,
|
||||
4 /* Components */,
|
||||
0));
|
||||
int nb_blocks = version == 0 ? 8 : 16;
|
||||
SPEC_LIST_ADD(sl, 16, 32, nb_blocks);
|
||||
SPEC_LIST_ADD(sl, 17, 32, 4); /* nb_components */
|
||||
|
||||
RET(add_common_data(avctx, s, shd, 0));
|
||||
ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
|
||||
(uint32_t []) { 8, nb_blocks, 4 }, 0);
|
||||
|
||||
GLSLC(0, #define NB_BLOCKS 16);
|
||||
GLSLC(0, #define NB_COMPONENTS 4);
|
||||
GLSLD(ff_source_dct_comp);
|
||||
add_common_data(avctx, s, shd, 0);
|
||||
|
||||
GLSLD(ff_source_prores_raw_idct_comp);
|
||||
|
||||
RET(spv->compile_shader(s, spv, shd, &spv_data, &spv_len, "main",
|
||||
&spv_opaque));
|
||||
RET(ff_vk_shader_link(s, shd, spv_data, spv_len, "main"));
|
||||
RET(ff_vk_shader_link(s, shd,
|
||||
ff_prores_raw_idct_comp_spv_data,
|
||||
ff_prores_raw_idct_comp_spv_len, "main"));
|
||||
|
||||
RET(ff_vk_shader_register_exec(s, pool, shd));
|
||||
|
||||
fail:
|
||||
if (spv_opaque)
|
||||
spv->free_shader(spv, &spv_opaque);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -423,12 +371,6 @@ static int vk_decode_prores_raw_init(AVCodecContext *avctx)
|
||||
FFVulkanDecodeContext *dec = avctx->internal->hwaccel_priv_data;
|
||||
ProResRAWContext *prr = avctx->priv_data;
|
||||
|
||||
FFVkSPIRVCompiler *spv = ff_vk_spirv_init();
|
||||
if (!spv) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to initialize SPIR-V compiler!\n");
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
err = ff_vk_decode_init(avctx);
|
||||
if (err < 0)
|
||||
return err;
|
||||
@@ -443,14 +385,12 @@ static int vk_decode_prores_raw_init(AVCodecContext *avctx)
|
||||
ctx->sd_ctx_free = &vk_decode_prores_raw_uninit;
|
||||
|
||||
/* Setup decode shader */
|
||||
RET(init_decode_shader(avctx, &ctx->s, &ctx->exec_pool, spv, &prv->decode,
|
||||
RET(init_decode_shader(avctx, &ctx->s, &ctx->exec_pool, &prv->decode,
|
||||
prr->version));
|
||||
RET(init_idct_shader(avctx, &ctx->s, &ctx->exec_pool, spv, &prv->idct,
|
||||
RET(init_idct_shader(avctx, &ctx->s, &ctx->exec_pool, &prv->idct,
|
||||
prr->version));
|
||||
|
||||
fail:
|
||||
spv->uninit(&spv);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user