35 .queue_flags = VK_QUEUE_COMPUTE_BIT,
83 VK_WHOLE_SIZE, buffer_ref,
84 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
85 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
94 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
95 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
97 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
98 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
141 if (slices_buf && slices_buf->
host_ref) {
185 VkImageMemoryBarrier2 img_bar[8];
187 VkBufferMemoryBarrier2 buf_bar[2];
200 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
201 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
213 vkf->
layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
214 vkf->
access[0] = VK_ACCESS_2_NONE;
217 img_bar, &nb_img_bar,
218 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
219 VK_PIPELINE_STAGE_2_CLEAR_BIT,
220 VK_ACCESS_2_TRANSFER_WRITE_BIT,
221 VK_IMAGE_LAYOUT_GENERAL,
222 VK_QUEUE_FAMILY_IGNORED);
223 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
224 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
225 .pImageMemoryBarriers = img_bar,
226 .imageMemoryBarrierCount = nb_img_bar,
232 vk->CmdClearColorImage(exec->
buf, vkf->
img[
i],
233 VK_IMAGE_LAYOUT_GENERAL,
234 &((VkClearColorValue) { 0 }),
235 1, &((VkImageSubresourceRange) {
236 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
243 VK_PIPELINE_STAGE_2_CLEAR_BIT,
244 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
245 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
246 VK_IMAGE_LAYOUT_GENERAL,
247 VK_QUEUE_FAMILY_IGNORED);
248 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
249 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
250 .pImageMemoryBarriers = img_bar,
251 .imageMemoryBarrierCount = nb_img_bar,
257 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
258 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
260 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
263 vk->CmdFillBuffer(exec->
buf, coeff_buf->
buf, 0, VK_WHOLE_SIZE, 0);
265 buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
266 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
267 .srcStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
268 .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
269 .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
270 .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT |
271 VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
272 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
273 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
274 .buffer = coeff_buf->
buf,
275 .size = VK_WHOLE_SIZE,
277 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
278 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
279 .pBufferMemoryBarriers = buf_bar,
280 .bufferMemoryBarrierCount = nb_buf_bar,
286 .tile_data = slices_buf->
address,
288 .log2_chroma_sub = {
desc->log2_chroma_w,
desc->log2_chroma_h },
289 .components =
desc->nb_components,
297 VK_IMAGE_LAYOUT_GENERAL,
302 0, frame_data_buf->
size,
303 VK_FORMAT_UNDEFINED);
306 coeff_buf, 0, coeff_buf->
size,
307 VK_FORMAT_UNDEFINED);
311 VK_SHADER_STAGE_COMPUTE_BIT,
314 vk->CmdDispatch(exec->
buf,
316 desc->nb_components);
319 buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
320 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
321 .srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
322 .srcAccessMask = VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
323 .dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
324 .dstAccessMask = VK_ACCESS_2_SHADER_STORAGE_READ_BIT,
325 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
326 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
327 .buffer = coeff_buf->
buf,
328 .size = VK_WHOLE_SIZE,
330 vk->CmdPipelineBarrier2(exec->
buf, &(VkDependencyInfo) {
331 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
332 .pBufferMemoryBarriers = buf_bar,
333 .bufferMemoryBarrierCount = nb_buf_bar,
341 VK_IMAGE_LAYOUT_GENERAL,
346 0, frame_data_buf->
size,
347 VK_FORMAT_UNDEFINED);
350 coeff_buf, 0, coeff_buf->
size,
351 VK_FORMAT_UNDEFINED);
355 VK_SHADER_STAGE_COMPUTE_BIT,
360 int idct_cx = 0, idct_by = 0;
362 int sw = (
comp == 0) ? 0 :
desc->log2_chroma_w;
363 int sh = (
comp == 0) ? 0 :
desc->log2_chroma_h;
364 int bx = (avctx->
coded_width + (1 << (3 + sw)) - 1) >> (3 + sw);
365 int by = (avctx->
coded_height + (1 << (3 + sh)) - 1) >> (3 + sh);
366 idct_cx =
FFMAX(idct_cx, (bx + 7) >> 3);
367 idct_by =
FFMAX(idct_by, by);
369 vk->CmdDispatch(exec->
buf, idct_cx, idct_by,
desc->nb_components);
392 (uint32_t []) { 1, 1, 1 }, 0);
394 VK_SHADER_STAGE_COMPUTE_BIT);
399 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
401 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
404 .name =
"frame_data_buf",
405 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
406 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
409 .name =
"coeffs_out_buf",
410 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
411 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
436 const double idct_8_scales[8] = {
437 cos(4.0*
M_PI/16.0) / 2.0, cos(1.0*
M_PI/16.0) / 2.0,
438 cos(2.0*
M_PI/16.0) / 2.0, cos(3.0*
M_PI/16.0) / 2.0,
439 cos(4.0*
M_PI/16.0) / 2.0, cos(5.0*
M_PI/16.0) / 2.0,
440 cos(6.0*
M_PI/16.0) / 2.0, cos(7.0*
M_PI/16.0) / 2.0,
442 for (
int i = 0;
i < 64;
i++)
447 (uint32_t []) { 32, 2, 1 }, 0);
449 VK_SHADER_STAGE_COMPUTE_BIT);
454 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
455 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
459 .name =
"frame_data_buf",
460 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
461 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
464 .name =
"coeffs_in_buf",
465 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
466 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
523 apvvk->
coeff_size += (size_t)(cw >> sx) * (ch >> sy);
551 .p.name =
"apv_vulkan",
static AVFormatContext * ctx
#define i(width, name, range_min, range_max)
int(* init)(AVBSFContext *ctx)
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
FrameData * frame_data(AVFrame *frame)
Get our axiliary frame data attached to the frame, allocating it if needed.
#define AV_NUM_DATA_POINTERS
#define HWACCEL_CAP_ASYNC_SAFE
Header providing the internals of AVHWAccel.
#define HWACCEL_CAP_THREAD_SAFE
const struct FFHWAccel ff_apv_vulkan_hwaccel
static av_always_inline uint32_t av_float2int(float f)
Reinterpret a float as a 32-bit integer.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
int ff_vk_host_map_buffer(FFVulkanContext *s, FFVkBuffer **dst, uint8_t *src_data, VkDeviceSize size, const AVBufferRef *src_buf, VkBufferUsageFlags usage)
Maps a system RAM buffer into a Vulkan buffer.
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
int ff_vk_flush_buffer(FFVulkanContext *s, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize mem_size, int flush)
Flush or invalidate a single buffer, with a given size and offset.
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Memory handling functions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
APVRawFrame * cur_raw_frame
CodedBitstreamContext * cbc
APVDerivedTileInfo tile_info
void * hwaccel_picture_private
uint16_t col_starts[APV_MAX_TILE_COLS+1]
uint16_t row_starts[APV_MAX_TILE_ROWS+1]
APVRawFrameHeader frame_header
APVRawTile tile[APV_MAX_TILE_COUNT]
uint8_t q_matrix[APV_MAX_NUM_COMP][APV_TR_SIZE][APV_TR_SIZE]
APVRawTileHeader tile_header
AVRefStructPool * coeff_pool
AVRefStructPool * frame_data_pool
FFVkBuffer * frame_data_buf
A reference to a data buffer.
uint8_t * data
The data buffer.
main external API structure.
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
int coded_width
Bitstream width / height, may be different from width/height e.g.
struct AVCodecInternal * internal
Private context used for internal data.
void * hwaccel_priv_data
hwaccel-specific private data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
This struct describes a set or pool of "hardware" frames (i.e.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
uint8_t nb_components
The number of components each pixel has, (1-4)
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
void * priv_data
Internal codec-specific data.
VkDeviceAddress tile_data
FFVulkanDecodeShared * shared_ctx
RefStruct is an API for creating reference-counted objects with minimal overhead.
#define SPEC_LIST_ADD(name, idx, val_bits, val)
#define SPEC_LIST_CREATE(name, max_length, max_size)
static int ff_vk_count_images(AVVkFrame *f)
const unsigned char ff_apv_decode_comp_spv_data[]
static int vk_apv_decode_slice(AVCodecContext *avctx, const uint8_t *data, uint32_t size)
static void vk_decode_apv_uninit(FFVulkanDecodeShared *ctx)
const unsigned char ff_apv_idct_comp_spv_data[]
static int vk_decode_apv_init(AVCodecContext *avctx)
static int init_idct_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
const FFVulkanDecodeDescriptor ff_vk_dec_apv_desc
static void vk_apv_free_frame_priv(AVRefStructOpaque _hwctx, void *data)
static int init_decode_shader(AVCodecContext *avctx, FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
static int vk_apv_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, av_unused const uint8_t *buffer, av_unused uint32_t size)
static int vk_apv_end_frame(AVCodecContext *avctx)
const unsigned int ff_apv_idct_comp_spv_len
const unsigned int ff_apv_decode_comp_spv_len
int ff_vk_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
Synchronize the contexts between 2 threads.
int ff_vk_decode_init(AVCodecContext *avctx)
Initialize decoder.
int ff_vk_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Initialize hw_frames_ctx with the parameters needed to decode the stream using the parameters from av...
int ff_vk_decode_add_slice(AVCodecContext *avctx, FFVulkanDecodePicture *vp, const uint8_t *data, size_t size, int add_startcode, uint32_t *nb_slices, const uint32_t **offsets)
Add slice data to frame.
void ff_vk_decode_free_frame(AVHWDeviceContext *dev_ctx, FFVulkanDecodePicture *vp)
Free a frame and its state.
int ff_vk_decode_uninit(AVCodecContext *avctx)
Free decoder.
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY