mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 18:10:11 +01:00
virgl: add support for hardware video acceleration
Currently H.264 and H.265 decoding is supported, and other profiles and encodings will be added in the future. This function relies on the virglrenderer commit: a92fed821f5ac173ca82c011a5d7e5b25e7bd0eb Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Signed-off-by: Ming Xie <xieming@kylinos.cn> Signed-off-by: Liming Sun <sunliming@kylinos.cn> Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17157>
This commit is contained in:
parent
15c210649d
commit
6b5aecb195
12 changed files with 1212 additions and 2 deletions
|
|
@ -30,6 +30,7 @@ files_libvirgl = files(
|
|||
'virgl_transfer_queue.c',
|
||||
'virgl_texture.c',
|
||||
'virgl_tgsi.c',
|
||||
'virgl_video.c',
|
||||
)
|
||||
|
||||
libvirgl = static_library(
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "virgl_resource.h"
|
||||
#include "virgl_screen.h"
|
||||
#include "virgl_staging_mgr.h"
|
||||
#include "virgl_video.h"
|
||||
|
||||
struct virgl_vertex_elements_state {
|
||||
uint32_t handle;
|
||||
|
|
@ -859,6 +860,17 @@ static void virgl_clear(struct pipe_context *ctx,
|
|||
virgl_encode_clear(vctx, buffers, color, depth, stencil);
|
||||
}
|
||||
|
||||
static void virgl_clear_render_target(struct pipe_context *ctx,
|
||||
struct pipe_surface *dst,
|
||||
const union pipe_color_union *color,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height,
|
||||
bool render_condition_enabled)
|
||||
{
|
||||
if (virgl_debug & VIRGL_DEBUG_VERBOSE)
|
||||
debug_printf("VIRGL: clear render target unsupported.\n");
|
||||
}
|
||||
|
||||
static void virgl_clear_texture(struct pipe_context *ctx,
|
||||
struct pipe_resource *res,
|
||||
unsigned int level,
|
||||
|
|
@ -1624,6 +1636,7 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
|
|||
vctx->base.launch_grid = virgl_launch_grid;
|
||||
|
||||
vctx->base.clear = virgl_clear;
|
||||
vctx->base.clear_render_target = virgl_clear_render_target;
|
||||
vctx->base.clear_texture = virgl_clear_texture;
|
||||
vctx->base.draw_vbo = virgl_draw_vbo;
|
||||
vctx->base.flush = virgl_flush_from_st;
|
||||
|
|
@ -1660,6 +1673,9 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
|
|||
vctx->base.memory_barrier = virgl_memory_barrier;
|
||||
vctx->base.emit_string_marker = virgl_emit_string_marker;
|
||||
|
||||
vctx->base.create_video_codec = virgl_video_create_codec;
|
||||
vctx->base.create_video_buffer = virgl_video_create_buffer;
|
||||
|
||||
if (rs->caps.caps.v2.host_feature_check_version >= 7)
|
||||
vctx->base.link_shader = virgl_link_shader;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "virtio-gpu/virgl_protocol.h"
|
||||
#include "virgl_resource.h"
|
||||
#include "virgl_screen.h"
|
||||
#include "virgl_video.h"
|
||||
|
||||
#define VIRGL_ENCODE_MAX_DWORDS MIN2(VIRGL_MAX_CMDBUF_DWORDS, VIRGL_CMD0_MAX_DWORDS)
|
||||
|
||||
|
|
@ -308,6 +309,18 @@ enum virgl_formats pipe_to_virgl_format(enum pipe_format format)
|
|||
return vformat;
|
||||
}
|
||||
|
||||
enum pipe_format virgl_to_pipe_format(enum virgl_formats format)
|
||||
{
|
||||
enum pipe_format pformat;
|
||||
|
||||
for (pformat = PIPE_FORMAT_NONE; pformat < PIPE_FORMAT_COUNT; pformat++)
|
||||
if (virgl_formats_conv_table[pformat] == format)
|
||||
return pformat;
|
||||
|
||||
debug_printf("VIRGL: virgl format %u not in the format table\n", format);
|
||||
return PIPE_FORMAT_NONE;
|
||||
}
|
||||
|
||||
static int virgl_encoder_write_cmd_dword(struct virgl_context *ctx,
|
||||
uint32_t dword)
|
||||
{
|
||||
|
|
@ -1613,3 +1626,76 @@ void virgl_encode_emit_string_marker(struct virgl_context *ctx,
|
|||
virgl_encoder_write_dword(ctx->cbuf, len);
|
||||
virgl_encoder_write_block(ctx->cbuf, (const uint8_t *)message, len);
|
||||
}
|
||||
|
||||
void virgl_encode_create_video_codec(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_VIDEO_CODEC, 0, 7));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.profile);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.entrypoint);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.chroma_format);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.level);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.width);
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->base.height);
|
||||
}
|
||||
|
||||
void virgl_encode_destroy_video_codec(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DESTROY_VIDEO_CODEC, 0, 1));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
}
|
||||
|
||||
void virgl_encode_create_video_buffer(struct virgl_context *ctx,
|
||||
struct virgl_video_buffer *vbuf)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_VIDEO_BUFFER, 0,
|
||||
4 + vbuf->num_planes));
|
||||
virgl_encoder_write_dword(ctx->cbuf, vbuf->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, pipe_to_virgl_format(vbuf->buf->buffer_format));
|
||||
virgl_encoder_write_dword(ctx->cbuf, vbuf->buf->width);
|
||||
virgl_encoder_write_dword(ctx->cbuf, vbuf->buf->height);
|
||||
for (i = 0; i < vbuf->num_planes; i++)
|
||||
virgl_encoder_write_res(ctx, virgl_resource(vbuf->plane_views[i]->texture));
|
||||
}
|
||||
|
||||
void virgl_encode_destroy_video_buffer(struct virgl_context *ctx,
|
||||
struct virgl_video_buffer *buf)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DESTROY_VIDEO_BUFFER, 0, 1));
|
||||
virgl_encoder_write_dword(ctx->cbuf, buf->handle);
|
||||
}
|
||||
|
||||
void virgl_encode_begin_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_BEGIN_FRAME, 0, 2));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, buf->handle);
|
||||
}
|
||||
|
||||
void virgl_encode_decode_bitstream(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf,
|
||||
void *desc, uint32_t desc_size)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_DECODE_BITSTREAM, 0, 5));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, buf->handle);
|
||||
virgl_encoder_write_res(ctx, virgl_resource(cdc->desc_buffers[cdc->cur_buffer]));
|
||||
virgl_encoder_write_res(ctx, virgl_resource(cdc->bs_buffers[cdc->cur_buffer]));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->bs_size);
|
||||
}
|
||||
|
||||
void virgl_encode_end_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf)
|
||||
{
|
||||
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_END_FRAME, 0, 2));
|
||||
virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
|
||||
virgl_encoder_write_dword(ctx->cbuf, buf->handle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ struct virgl_resource;
|
|||
struct virgl_screen;
|
||||
struct virgl_transfer;
|
||||
struct virgl_sampler_view;
|
||||
struct virgl_video_codec;
|
||||
struct virgl_video_buffer;
|
||||
|
||||
struct virgl_surface {
|
||||
struct pipe_surface base;
|
||||
|
|
@ -317,5 +319,31 @@ void virgl_encode_get_memory_info(struct virgl_context *ctx, struct virgl_resour
|
|||
void virgl_encode_emit_string_marker(struct virgl_context *ctx, const char *message,
|
||||
int len);
|
||||
|
||||
void virgl_encode_create_video_codec(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc);
|
||||
|
||||
void virgl_encode_destroy_video_codec(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc);
|
||||
|
||||
void virgl_encode_create_video_buffer(struct virgl_context *ctx,
|
||||
struct virgl_video_buffer *buf);
|
||||
|
||||
void virgl_encode_destroy_video_buffer(struct virgl_context *ctx,
|
||||
struct virgl_video_buffer *buf);
|
||||
|
||||
void virgl_encode_begin_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf);
|
||||
|
||||
void virgl_encode_decode_bitstream(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf,
|
||||
void *desc, uint32_t desc_size);
|
||||
|
||||
void virgl_encode_end_frame(struct virgl_context *ctx,
|
||||
struct virgl_video_codec *cdc,
|
||||
struct virgl_video_buffer *buf);
|
||||
|
||||
enum virgl_formats pipe_to_virgl_format(enum pipe_format format);
|
||||
enum pipe_format virgl_to_pipe_format(enum virgl_formats format);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "nir/nir_to_tgsi.h"
|
||||
#include "vl/vl_decoder.h"
|
||||
#include "vl/vl_video_buffer.h"
|
||||
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ static const struct debug_named_value virgl_debug_options[] = {
|
|||
{ "xfer", VIRGL_DEBUG_XFER, "Do not optimize for transfers" },
|
||||
{ "r8srgb-readback", VIRGL_DEBUG_L8_SRGB_ENABLE_READBACK, "Enable redaback for L8 sRGB textures" },
|
||||
{ "nocoherent", VIRGL_DEBUG_NO_COHERENT, "Disable coherent memory"},
|
||||
{ "video", VIRGL_DEBUG_VIDEO, "Video codec"},
|
||||
DEBUG_NAMED_VALUE_END
|
||||
};
|
||||
DEBUG_GET_ONCE_FLAGS_OPTION(virgl_debug, "VIRGL_DEBUG", virgl_debug_options, 0)
|
||||
|
|
@ -457,6 +460,72 @@ virgl_get_shader_param(struct pipe_screen *screen,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
virgl_get_video_param(struct pipe_screen *screen,
|
||||
enum pipe_video_profile profile,
|
||||
enum pipe_video_entrypoint entrypoint,
|
||||
enum pipe_video_cap param)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_caps *vcaps = NULL;
|
||||
struct virgl_screen *vscreen;
|
||||
|
||||
if (!screen)
|
||||
return 0;
|
||||
|
||||
vscreen = virgl_screen(screen);
|
||||
if (vscreen->caps.caps.v2.num_video_caps > ARRAY_SIZE(vscreen->caps.caps.v2.video_caps))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < vscreen->caps.caps.v2.num_video_caps; i++) {
|
||||
if (vscreen->caps.caps.v2.video_caps[i].profile == profile &&
|
||||
vscreen->caps.caps.v2.video_caps[i].entrypoint == entrypoint) {
|
||||
vcaps = &vscreen->caps.caps.v2.video_caps[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Since there are calls like this:
|
||||
* pot_buffers = !pipe->screen->get_video_param
|
||||
* (
|
||||
* pipe->screen,
|
||||
* PIPE_VIDEO_PROFILE_UNKNOWN,
|
||||
* PIPE_VIDEO_ENTRYPOINT_UNKNOWN,
|
||||
* PIPE_VIDEO_CAP_NPOT_TEXTURES
|
||||
* );
|
||||
* All parameters need to check the vcaps.
|
||||
*/
|
||||
switch (param) {
|
||||
case PIPE_VIDEO_CAP_SUPPORTED:
|
||||
return vcaps != NULL;
|
||||
case PIPE_VIDEO_CAP_NPOT_TEXTURES:
|
||||
return vcaps ? vcaps->npot_texture : true;
|
||||
case PIPE_VIDEO_CAP_MAX_WIDTH:
|
||||
return vcaps ? vcaps->max_width : 0;
|
||||
case PIPE_VIDEO_CAP_MAX_HEIGHT:
|
||||
return vcaps ? vcaps->max_height : 0;
|
||||
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
|
||||
return vcaps ? virgl_to_pipe_format(vcaps->prefered_format) : PIPE_FORMAT_NV12;
|
||||
case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
|
||||
return vcaps ? vcaps->prefers_interlaced : false;
|
||||
case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
|
||||
return vcaps ? vcaps->supports_interlaced : false;
|
||||
case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
|
||||
return vcaps ? vcaps->supports_progressive : true;
|
||||
case PIPE_VIDEO_CAP_MAX_LEVEL:
|
||||
return vcaps ? vcaps->max_level : 0;
|
||||
case PIPE_VIDEO_CAP_STACKED_FRAMES:
|
||||
return vcaps ? vcaps->stacked_frames : 0;
|
||||
case PIPE_VIDEO_CAP_MAX_MACROBLOCKS:
|
||||
return vcaps ? vcaps->max_macroblocks : 0;
|
||||
case PIPE_VIDEO_CAP_MAX_TEMPORAL_LAYERS:
|
||||
return vcaps ? vcaps->max_temporal_layers : 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static float
|
||||
virgl_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
|
||||
{
|
||||
|
|
@ -804,6 +873,15 @@ virgl_is_format_supported( struct pipe_screen *screen,
|
|||
may_emulate_bgra);
|
||||
}
|
||||
|
||||
static bool virgl_is_video_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_video_profile profile,
|
||||
enum pipe_video_entrypoint entrypoint)
|
||||
{
|
||||
return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint);
|
||||
}
|
||||
|
||||
|
||||
static void virgl_flush_frontbuffer(struct pipe_screen *screen,
|
||||
struct pipe_context *ctx,
|
||||
struct pipe_resource *res,
|
||||
|
|
@ -1055,10 +1133,12 @@ virgl_create_screen(struct virgl_winsys *vws, const struct pipe_screen_config *c
|
|||
screen->base.get_vendor = virgl_get_vendor;
|
||||
screen->base.get_param = virgl_get_param;
|
||||
screen->base.get_shader_param = virgl_get_shader_param;
|
||||
screen->base.get_video_param = virgl_get_video_param;
|
||||
screen->base.get_compute_param = virgl_get_compute_param;
|
||||
screen->base.get_paramf = virgl_get_paramf;
|
||||
screen->base.get_compiler_options = virgl_get_compiler_options;
|
||||
screen->base.is_format_supported = virgl_is_format_supported;
|
||||
screen->base.is_video_format_supported = virgl_is_video_format_supported;
|
||||
screen->base.destroy = virgl_destroy_screen;
|
||||
screen->base.context_create = virgl_context_create;
|
||||
screen->base.flush_frontbuffer = virgl_flush_frontbuffer;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ enum virgl_debug_flags {
|
|||
VIRGL_DEBUG_NO_COHERENT = 1 << 6,
|
||||
VIRGL_DEBUG_USE_TGSI = 1 << 7,
|
||||
VIRGL_DEBUG_L8_SRGB_ENABLE_READBACK = 1 << 8,
|
||||
VIRGL_DEBUG_VIDEO = 1 << 9,
|
||||
};
|
||||
|
||||
extern int virgl_debug;
|
||||
|
|
|
|||
567
src/gallium/drivers/virgl/virgl_video.c
Normal file
567
src/gallium/drivers/virgl/virgl_video.c
Normal file
|
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* Copyright 2022 Kylin Software Co., Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "vl/vl_decoder.h"
|
||||
#include "vl/vl_video_buffer.h"
|
||||
#include "util/u_video.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "virgl_screen.h"
|
||||
#include "virgl_resource.h"
|
||||
#include "virgl_encode.h"
|
||||
#include "virgl_video.h"
|
||||
|
||||
/*
|
||||
* The max size of bs buffer is approximately:
|
||||
* num_of_macroblocks * max_size_of_per_macroblock + size_of_some_headers
|
||||
* Now, we only support YUV420 formats, this means that we have a limit of
|
||||
* 3200 bits(400 Bytes) per macroblock. To simplify the calculation, we
|
||||
* directly use 512 instead of 400.
|
||||
*/
|
||||
#define BS_BUF_DEFAULT_SIZE(width, height) \
|
||||
((width) * (height) / (VL_MACROBLOCK_WIDTH * VL_MACROBLOCK_HEIGHT) * 512)
|
||||
|
||||
static void switch_buffer(struct virgl_video_codec *vcdc)
|
||||
{
|
||||
vcdc->cur_buffer++;
|
||||
vcdc->cur_buffer %= VIRGL_VIDEO_CODEC_BUF_NUM;
|
||||
}
|
||||
|
||||
#define ITEM_SET(dest, src, item) (dest)->item = (src)->item
|
||||
#define ITEM_CPY(dest, src, item) memcpy(&(dest)->item, &(src)->item, sizeof((dest)->item))
|
||||
|
||||
static int fill_base_picture_desc(const struct pipe_picture_desc *desc,
|
||||
struct virgl_base_picture_desc *vbase)
|
||||
{
|
||||
ITEM_SET(vbase, desc, profile);
|
||||
ITEM_SET(vbase, desc, entry_point);
|
||||
ITEM_SET(vbase, desc, protected_playback);
|
||||
ITEM_SET(vbase, desc, key_size);
|
||||
memcpy(vbase->decrypt_key, desc->decrypt_key,
|
||||
MIN(desc->key_size, sizeof(vbase->decrypt_key)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_h264_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_buffer *vbuf;
|
||||
|
||||
struct virgl_h264_picture_desc *vh264 = &vdsc->h264;
|
||||
struct virgl_h264_pps *vpps = &vh264->pps;
|
||||
struct virgl_h264_sps *vsps = &vh264->pps.sps;
|
||||
|
||||
struct pipe_h264_picture_desc *h264 = (struct pipe_h264_picture_desc *)desc;
|
||||
struct pipe_h264_pps *pps = h264->pps;
|
||||
struct pipe_h264_sps *sps = h264->pps->sps;
|
||||
|
||||
fill_base_picture_desc(desc, &vh264->base);
|
||||
|
||||
ITEM_SET(vsps, sps, level_idc);
|
||||
ITEM_SET(vsps, sps, chroma_format_idc);
|
||||
ITEM_SET(vsps, sps, separate_colour_plane_flag);
|
||||
ITEM_SET(vsps, sps, bit_depth_luma_minus8);
|
||||
ITEM_SET(vsps, sps, bit_depth_chroma_minus8);
|
||||
ITEM_SET(vsps, sps, seq_scaling_matrix_present_flag);
|
||||
ITEM_CPY(vsps, sps, ScalingList4x4);
|
||||
ITEM_CPY(vsps, sps, ScalingList8x8);
|
||||
ITEM_SET(vsps, sps, log2_max_frame_num_minus4);
|
||||
ITEM_SET(vsps, sps, pic_order_cnt_type);
|
||||
ITEM_SET(vsps, sps, log2_max_pic_order_cnt_lsb_minus4);
|
||||
ITEM_SET(vsps, sps, delta_pic_order_always_zero_flag);
|
||||
ITEM_SET(vsps, sps, offset_for_non_ref_pic);
|
||||
ITEM_SET(vsps, sps, offset_for_top_to_bottom_field);
|
||||
ITEM_CPY(vsps, sps, offset_for_ref_frame);
|
||||
ITEM_SET(vsps, sps, num_ref_frames_in_pic_order_cnt_cycle);
|
||||
ITEM_SET(vsps, sps, max_num_ref_frames);
|
||||
ITEM_SET(vsps, sps, frame_mbs_only_flag);
|
||||
ITEM_SET(vsps, sps, mb_adaptive_frame_field_flag);
|
||||
ITEM_SET(vsps, sps, direct_8x8_inference_flag);
|
||||
ITEM_SET(vsps, sps, MinLumaBiPredSize8x8);
|
||||
|
||||
ITEM_SET(vpps, pps, entropy_coding_mode_flag);
|
||||
ITEM_SET(vpps, pps, bottom_field_pic_order_in_frame_present_flag);
|
||||
ITEM_SET(vpps, pps, num_slice_groups_minus1);
|
||||
ITEM_SET(vpps, pps, slice_group_map_type);
|
||||
ITEM_SET(vpps, pps, slice_group_change_rate_minus1);
|
||||
ITEM_SET(vpps, pps, num_ref_idx_l0_default_active_minus1);
|
||||
ITEM_SET(vpps, pps, num_ref_idx_l1_default_active_minus1);
|
||||
ITEM_SET(vpps, pps, weighted_pred_flag);
|
||||
ITEM_SET(vpps, pps, weighted_bipred_idc);
|
||||
ITEM_SET(vpps, pps, pic_init_qp_minus26);
|
||||
ITEM_SET(vpps, pps, pic_init_qs_minus26);
|
||||
ITEM_SET(vpps, pps, chroma_qp_index_offset);
|
||||
ITEM_SET(vpps, pps, deblocking_filter_control_present_flag);
|
||||
ITEM_SET(vpps, pps, constrained_intra_pred_flag);
|
||||
ITEM_SET(vpps, pps, redundant_pic_cnt_present_flag);
|
||||
ITEM_CPY(vpps, pps, ScalingList4x4);
|
||||
ITEM_CPY(vpps, pps, ScalingList8x8);
|
||||
ITEM_SET(vpps, pps, transform_8x8_mode_flag);
|
||||
ITEM_SET(vpps, pps, second_chroma_qp_index_offset);
|
||||
|
||||
ITEM_SET(vh264, h264, frame_num);
|
||||
ITEM_SET(vh264, h264, field_pic_flag);
|
||||
ITEM_SET(vh264, h264, bottom_field_flag);
|
||||
ITEM_SET(vh264, h264, num_ref_idx_l0_active_minus1);
|
||||
ITEM_SET(vh264, h264, num_ref_idx_l1_active_minus1);
|
||||
ITEM_SET(vh264, h264, slice_count);
|
||||
ITEM_CPY(vh264, h264, field_order_cnt);
|
||||
ITEM_SET(vh264, h264, is_reference);
|
||||
ITEM_SET(vh264, h264, num_ref_frames);
|
||||
ITEM_CPY(vh264, h264, field_order_cnt_list);
|
||||
ITEM_CPY(vh264, h264, frame_num_list);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
ITEM_SET(vh264, h264, is_long_term[i]);
|
||||
ITEM_SET(vh264, h264, top_is_reference[i]);
|
||||
ITEM_SET(vh264, h264, bottom_is_reference[i]);
|
||||
|
||||
vbuf = virgl_video_buffer(h264->ref[i]);
|
||||
vh264->buffer_id[i] = vbuf ? vbuf->handle : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_h265_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_buffer *vbuf;
|
||||
|
||||
struct virgl_h265_picture_desc *vh265 = &vdsc->h265;
|
||||
struct pipe_h265_picture_desc *h265 = (struct pipe_h265_picture_desc *)desc;
|
||||
|
||||
fill_base_picture_desc(desc, &vh265->base);
|
||||
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, chroma_format_idc);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, separate_colour_plane_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pic_width_in_luma_samples);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pic_height_in_luma_samples);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, bit_depth_luma_minus8);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, bit_depth_chroma_minus8);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_max_pic_order_cnt_lsb_minus4);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, sps_max_dec_pic_buffering_minus1);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_min_luma_coding_block_size_minus3);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_diff_max_min_luma_coding_block_size);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_min_transform_block_size_minus2);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_diff_max_min_transform_block_size);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, max_transform_hierarchy_depth_inter);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, max_transform_hierarchy_depth_intra);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, scaling_list_enabled_flag);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingList4x4);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingList8x8);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingList16x16);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingList32x32);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingListDCCoeff16x16);
|
||||
ITEM_CPY(&vh265->pps.sps, h265->pps->sps, ScalingListDCCoeff32x32);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, amp_enabled_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, sample_adaptive_offset_enabled_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pcm_enabled_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pcm_sample_bit_depth_luma_minus1);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pcm_sample_bit_depth_chroma_minus1);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_min_pcm_luma_coding_block_size_minus3);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, log2_diff_max_min_pcm_luma_coding_block_size);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, pcm_loop_filter_disabled_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, num_short_term_ref_pic_sets);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, long_term_ref_pics_present_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, num_long_term_ref_pics_sps);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, sps_temporal_mvp_enabled_flag);
|
||||
ITEM_SET(&vh265->pps.sps, h265->pps->sps, strong_intra_smoothing_enabled_flag);
|
||||
|
||||
ITEM_SET(&vh265->pps, h265->pps, dependent_slice_segments_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, output_flag_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, num_extra_slice_header_bits);
|
||||
ITEM_SET(&vh265->pps, h265->pps, sign_data_hiding_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, cabac_init_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, num_ref_idx_l0_default_active_minus1);
|
||||
ITEM_SET(&vh265->pps, h265->pps, num_ref_idx_l1_default_active_minus1);
|
||||
ITEM_SET(&vh265->pps, h265->pps, init_qp_minus26);
|
||||
ITEM_SET(&vh265->pps, h265->pps, constrained_intra_pred_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, transform_skip_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, cu_qp_delta_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, diff_cu_qp_delta_depth);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_cb_qp_offset);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_cr_qp_offset);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_slice_chroma_qp_offsets_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, weighted_pred_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, weighted_bipred_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, transquant_bypass_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, tiles_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, entropy_coding_sync_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, num_tile_columns_minus1);
|
||||
ITEM_SET(&vh265->pps, h265->pps, num_tile_rows_minus1);
|
||||
ITEM_SET(&vh265->pps, h265->pps, uniform_spacing_flag);
|
||||
ITEM_CPY(&vh265->pps, h265->pps, column_width_minus1);
|
||||
ITEM_CPY(&vh265->pps, h265->pps, row_height_minus1);
|
||||
ITEM_SET(&vh265->pps, h265->pps, loop_filter_across_tiles_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_loop_filter_across_slices_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, deblocking_filter_control_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, deblocking_filter_override_enabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_deblocking_filter_disabled_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_beta_offset_div2);
|
||||
ITEM_SET(&vh265->pps, h265->pps, pps_tc_offset_div2);
|
||||
ITEM_SET(&vh265->pps, h265->pps, lists_modification_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, log2_parallel_merge_level_minus2);
|
||||
ITEM_SET(&vh265->pps, h265->pps, slice_segment_header_extension_present_flag);
|
||||
ITEM_SET(&vh265->pps, h265->pps, st_rps_bits);
|
||||
|
||||
ITEM_SET(vh265, h265, IDRPicFlag);
|
||||
ITEM_SET(vh265, h265, RAPPicFlag);
|
||||
ITEM_SET(vh265, h265, CurrRpsIdx);
|
||||
ITEM_SET(vh265, h265, NumPocTotalCurr);
|
||||
ITEM_SET(vh265, h265, NumDeltaPocsOfRefRpsIdx);
|
||||
ITEM_SET(vh265, h265, NumShortTermPictureSliceHeaderBits);
|
||||
ITEM_SET(vh265, h265, NumLongTermPictureSliceHeaderBits);
|
||||
|
||||
ITEM_SET(vh265, h265, CurrPicOrderCntVal);
|
||||
for (i = 0; i < 16; i++) {
|
||||
vbuf = virgl_video_buffer(h265->ref[i]);
|
||||
vh265->ref[i] = vbuf ? vbuf->handle : 0;
|
||||
}
|
||||
ITEM_CPY(vh265, h265, PicOrderCntVal);
|
||||
ITEM_CPY(vh265, h265, IsLongTerm);
|
||||
ITEM_SET(vh265, h265, NumPocStCurrBefore);
|
||||
ITEM_SET(vh265, h265, NumPocStCurrAfter);
|
||||
ITEM_SET(vh265, h265, NumPocLtCurr);
|
||||
ITEM_CPY(vh265, h265, RefPicSetStCurrBefore);
|
||||
ITEM_CPY(vh265, h265, RefPicSetStCurrAfter);
|
||||
ITEM_CPY(vh265, h265, RefPicSetLtCurr);
|
||||
ITEM_CPY(vh265, h265, RefPicList);
|
||||
ITEM_SET(vh265, h265, UseRefPicList);
|
||||
ITEM_SET(vh265, h265, UseStRpsBits);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_mpeg4_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_buffer *vbuf;
|
||||
struct virgl_mpeg4_picture_desc *vmpeg4 = &vdsc->mpeg4;
|
||||
struct pipe_mpeg4_picture_desc *mpeg4 = (struct pipe_mpeg4_picture_desc *)desc;
|
||||
|
||||
fill_base_picture_desc(desc, &vmpeg4->base);
|
||||
|
||||
ITEM_CPY(vmpeg4, mpeg4, trd);
|
||||
ITEM_CPY(vmpeg4, mpeg4, trb);
|
||||
ITEM_SET(vmpeg4, mpeg4, vop_time_increment_resolution);
|
||||
ITEM_SET(vmpeg4, mpeg4, vop_coding_type);
|
||||
ITEM_SET(vmpeg4, mpeg4, vop_fcode_forward);
|
||||
ITEM_SET(vmpeg4, mpeg4, vop_fcode_backward);
|
||||
ITEM_SET(vmpeg4, mpeg4, resync_marker_disable);
|
||||
ITEM_SET(vmpeg4, mpeg4, interlaced);
|
||||
ITEM_SET(vmpeg4, mpeg4, quant_type);
|
||||
ITEM_SET(vmpeg4, mpeg4, quarter_sample);
|
||||
ITEM_SET(vmpeg4, mpeg4, short_video_header);
|
||||
ITEM_SET(vmpeg4, mpeg4, rounding_control);
|
||||
ITEM_SET(vmpeg4, mpeg4, alternate_vertical_scan_flag);
|
||||
ITEM_SET(vmpeg4, mpeg4, top_field_first);
|
||||
ITEM_CPY(vmpeg4, mpeg4, intra_matrix);
|
||||
ITEM_CPY(vmpeg4, mpeg4, non_intra_matrix);
|
||||
for (i = 0; i < 16; i++) {
|
||||
vbuf = virgl_video_buffer(mpeg4->ref[i]);
|
||||
vmpeg4->ref[i] = vbuf ? vbuf->handle : 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef ITEM_SET
|
||||
#undef ITEM_CPY
|
||||
|
||||
static int fill_picture_desc(const struct pipe_picture_desc *desc,
|
||||
union virgl_picture_desc *vdsc)
|
||||
{
|
||||
switch (u_reduce_video_profile(desc->profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4:
|
||||
return fill_mpeg4_picture_desc(desc, vdsc);
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
return fill_h264_picture_desc(desc, vdsc);
|
||||
case PIPE_VIDEO_FORMAT_HEVC:
|
||||
return fill_h265_picture_desc(desc, vdsc);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void virgl_video_begin_frame(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture)
|
||||
{
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_video_buffer *vbuf = virgl_video_buffer(target);
|
||||
|
||||
virgl_encode_begin_frame(vcdc->vctx, vcdc, vbuf);
|
||||
}
|
||||
|
||||
static void virgl_video_decode_macroblock(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture,
|
||||
const struct pipe_macroblock *macroblocks,
|
||||
unsigned num_macroblocks)
|
||||
{
|
||||
(void)codec;
|
||||
(void)target;
|
||||
(void)picture;
|
||||
(void)macroblocks;
|
||||
(void)num_macroblocks;
|
||||
}
|
||||
|
||||
static void virgl_video_decode_bitstream(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture,
|
||||
unsigned num_buffers,
|
||||
const void * const *buffers,
|
||||
const unsigned *sizes)
|
||||
{
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_video_buffer *vbuf = virgl_video_buffer(target);
|
||||
struct virgl_context *vctx = vcdc->vctx;
|
||||
struct virgl_screen *vs = virgl_screen(vctx->base.screen);
|
||||
struct virgl_resource *vres;
|
||||
union virgl_picture_desc vdsc;
|
||||
struct pipe_transfer *xfer = NULL;
|
||||
void *ptr;
|
||||
unsigned i, total_size;
|
||||
|
||||
/* transfer bitstream data */
|
||||
for (i = 0, total_size = 0; i < num_buffers; i++)
|
||||
total_size += sizes[i];
|
||||
|
||||
if (total_size > pipe_buffer_size(vcdc->bs_buffers[vcdc->cur_buffer])) {
|
||||
pipe_resource_reference(&vcdc->bs_buffers[vcdc->cur_buffer], NULL);
|
||||
vcdc->bs_buffers[vcdc->cur_buffer] = pipe_buffer_create(vctx->base.screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, total_size);
|
||||
}
|
||||
|
||||
vctx->base.flush(&vctx->base, NULL, 0);
|
||||
|
||||
vres = virgl_resource(vcdc->bs_buffers[vcdc->cur_buffer]);
|
||||
vs->vws->resource_wait(vs->vws, vres->hw_res);
|
||||
ptr = pipe_buffer_map(&vctx->base, vcdc->bs_buffers[vcdc->cur_buffer],
|
||||
PIPE_MAP_WRITE, &xfer);
|
||||
if (!ptr)
|
||||
return;
|
||||
for (i = 0, vcdc->bs_size = 0; i < num_buffers; i++) {
|
||||
memcpy(ptr + vcdc->bs_size, buffers[i], sizes[i]);
|
||||
vcdc->bs_size += sizes[i];
|
||||
}
|
||||
pipe_buffer_unmap(&vctx->base, xfer);
|
||||
|
||||
/* transfer picture description */
|
||||
fill_picture_desc(picture, &vdsc);
|
||||
vres = virgl_resource(vcdc->desc_buffers[vcdc->cur_buffer]);
|
||||
vs->vws->resource_wait(vs->vws, vres->hw_res);
|
||||
ptr = pipe_buffer_map(&vctx->base, vcdc->desc_buffers[vcdc->cur_buffer],
|
||||
PIPE_MAP_WRITE, &xfer);
|
||||
if (!ptr)
|
||||
return;
|
||||
memcpy(ptr, &vdsc, sizeof(vdsc));
|
||||
pipe_buffer_unmap(&vctx->base, xfer);
|
||||
|
||||
virgl_encode_decode_bitstream(vctx, vcdc, vbuf, &vdsc, sizeof(vdsc));
|
||||
}
|
||||
|
||||
static void virgl_video_end_frame(struct pipe_video_codec *codec,
|
||||
struct pipe_video_buffer *target,
|
||||
struct pipe_picture_desc *picture)
|
||||
{
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_context *vctx = virgl_context(vcdc->base.context);
|
||||
struct virgl_video_buffer *vbuf = virgl_video_buffer(target);
|
||||
|
||||
virgl_encode_end_frame(vctx, vcdc, vbuf);
|
||||
virgl_flush_eq(vctx, vctx, NULL);
|
||||
|
||||
switch_buffer(vcdc);
|
||||
}
|
||||
|
||||
static void virgl_video_flush(struct pipe_video_codec *codec)
|
||||
{
|
||||
(void)codec;
|
||||
}
|
||||
|
||||
static void virgl_video_get_feedback(struct pipe_video_codec *codec,
|
||||
void *feedback,
|
||||
unsigned *size)
|
||||
{
|
||||
(void)codec;
|
||||
(void)feedback;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
static void virgl_video_destroy_codec(struct pipe_video_codec *codec)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_codec *vcdc = virgl_video_codec(codec);
|
||||
struct virgl_context *vctx = virgl_context(vcdc->base.context);
|
||||
|
||||
for (i = 0; i < VIRGL_VIDEO_CODEC_BUF_NUM; i++) {
|
||||
pipe_resource_reference(&vcdc->bs_buffers[i], NULL);
|
||||
pipe_resource_reference(&vcdc->desc_buffers[i], NULL);
|
||||
}
|
||||
|
||||
virgl_encode_destroy_video_codec(vctx, vcdc);
|
||||
|
||||
free(vcdc);
|
||||
}
|
||||
|
||||
|
||||
struct pipe_video_codec *
|
||||
virgl_video_create_codec(struct pipe_context *ctx,
|
||||
const struct pipe_video_codec *templ)
|
||||
{
|
||||
unsigned i;
|
||||
struct virgl_video_codec *vcdc;
|
||||
struct virgl_context *vctx = virgl_context(ctx);
|
||||
unsigned width = templ->width, height = templ->height;
|
||||
|
||||
if (virgl_debug & VIRGL_DEBUG_VIDEO)
|
||||
debug_printf("VIDEO: create codec. profile=%d, level=%u, entryp=%d, "
|
||||
"chroma_fmt=%d, size=%ux%u, max_ref=%u, expect=%d\n",
|
||||
templ->profile, templ->level, templ->entrypoint,
|
||||
templ->chroma_format, templ->width, templ->height,
|
||||
templ->max_references, templ->expect_chunked_decode);
|
||||
|
||||
/* encode: not supported now */
|
||||
if (templ->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
|
||||
return NULL;
|
||||
|
||||
/* decode: */
|
||||
switch (u_reduce_video_profile(templ->profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG4: /* fall through */
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
|
||||
width = align(width, VL_MACROBLOCK_WIDTH);
|
||||
height = align(height, VL_MACROBLOCK_HEIGHT);
|
||||
break;
|
||||
case PIPE_VIDEO_FORMAT_HEVC: /* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vcdc = CALLOC_STRUCT(virgl_video_codec);
|
||||
if (!vcdc)
|
||||
return NULL;
|
||||
|
||||
vcdc->base = *templ;
|
||||
vcdc->base.width = width;
|
||||
vcdc->base.height = height;
|
||||
vcdc->base.context = ctx;
|
||||
|
||||
vcdc->base.destroy = virgl_video_destroy_codec;
|
||||
vcdc->base.begin_frame = virgl_video_begin_frame;
|
||||
vcdc->base.decode_macroblock = virgl_video_decode_macroblock;
|
||||
vcdc->base.decode_bitstream = virgl_video_decode_bitstream;
|
||||
vcdc->base.end_frame = virgl_video_end_frame;
|
||||
vcdc->base.flush = virgl_video_flush;
|
||||
vcdc->base.get_feedback = virgl_video_get_feedback;
|
||||
|
||||
vcdc->bs_size = 0;
|
||||
vcdc->cur_buffer = 0;
|
||||
for (i = 0; i < VIRGL_VIDEO_CODEC_BUF_NUM; i++) {
|
||||
vcdc->bs_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
BS_BUF_DEFAULT_SIZE(width, height));
|
||||
|
||||
vcdc->desc_buffers[i] = pipe_buffer_create(ctx->screen,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING,
|
||||
sizeof(union virgl_picture_desc));
|
||||
}
|
||||
|
||||
vcdc->handle = virgl_object_assign_handle();
|
||||
vcdc->vctx = vctx;
|
||||
|
||||
virgl_encode_create_video_codec(vctx, vcdc);
|
||||
|
||||
return &vcdc->base;
|
||||
}
|
||||
|
||||
|
||||
static void virgl_video_destroy_buffer(struct pipe_video_buffer *buffer)
|
||||
{
|
||||
struct virgl_video_buffer *vbuf = virgl_video_buffer(buffer);
|
||||
|
||||
virgl_encode_destroy_video_buffer(vbuf->vctx, vbuf);
|
||||
|
||||
vl_video_buffer_destroy(buffer);
|
||||
|
||||
free(vbuf);
|
||||
}
|
||||
|
||||
static void virgl_video_destroy_buffer_associated_data(void *data)
|
||||
{
|
||||
(void)data;
|
||||
}
|
||||
|
||||
struct pipe_video_buffer *
|
||||
virgl_video_create_buffer(struct pipe_context *ctx,
|
||||
const struct pipe_video_buffer *tmpl)
|
||||
{
|
||||
struct virgl_context *vctx = virgl_context(ctx);
|
||||
struct virgl_video_buffer *vbuf;
|
||||
|
||||
vbuf = CALLOC_STRUCT(virgl_video_buffer);
|
||||
if (!vbuf)
|
||||
return NULL;
|
||||
|
||||
vbuf->buf = vl_video_buffer_create(ctx, tmpl);
|
||||
if (!vbuf->buf) {
|
||||
free(vbuf);
|
||||
return NULL;
|
||||
}
|
||||
vbuf->buf->destroy = virgl_video_destroy_buffer;
|
||||
vl_video_buffer_set_associated_data(vbuf->buf,
|
||||
NULL, vbuf, virgl_video_destroy_buffer_associated_data);
|
||||
|
||||
vbuf->num_planes = util_format_get_num_planes(vbuf->buf->buffer_format);
|
||||
vbuf->plane_views = vbuf->buf->get_sampler_view_planes(vbuf->buf);
|
||||
vbuf->handle = virgl_object_assign_handle();
|
||||
vbuf->buffer_format = tmpl->buffer_format;
|
||||
vbuf->width = tmpl->width;
|
||||
vbuf->height = tmpl->height;
|
||||
vbuf->vctx = vctx;
|
||||
|
||||
virgl_encode_create_video_buffer(vctx, vbuf);
|
||||
|
||||
if (virgl_debug & VIRGL_DEBUG_VIDEO) {
|
||||
debug_printf("VIDEO: create buffer. fmt=%s, %ux%u, num_planes=%u\n",
|
||||
util_format_name(tmpl->buffer_format),
|
||||
tmpl->width, tmpl->height, vbuf->num_planes);
|
||||
|
||||
for (unsigned i = 0; i < vbuf->num_planes; i++)
|
||||
if (vbuf->plane_views[i])
|
||||
debug_printf("VIDEO: plane[%d]: fmt=%s, target=%u\n", i,
|
||||
util_format_name(vbuf->plane_views[i]->format),
|
||||
vbuf->plane_views[i]->target);
|
||||
}
|
||||
|
||||
return vbuf->buf;
|
||||
}
|
||||
|
||||
347
src/gallium/drivers/virgl/virgl_video.h
Normal file
347
src/gallium/drivers/virgl/virgl_video.h
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* Copyright 2022 Kylin Software Co., Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef VIRGL_VIDEO_H
|
||||
#define VIRGL_VIDEO_H
|
||||
|
||||
/*
|
||||
* This file contains parts of the HW ABI, such as union virgl_picture_desc
|
||||
* and other related structures.
|
||||
*/
|
||||
|
||||
#include "virgl_context.h"
|
||||
#include "vl/vl_video_buffer.h"
|
||||
#include "pipe/p_video_codec.h"
|
||||
|
||||
#define VIRGL_VIDEO_CODEC_BUF_NUM 10
|
||||
|
||||
struct virgl_video_codec {
|
||||
struct pipe_video_codec base; /* must be first */
|
||||
|
||||
uint32_t handle;
|
||||
struct virgl_context *vctx;
|
||||
|
||||
uint32_t bs_size; /* size of data in bs_buffer */
|
||||
uint32_t cur_buffer; /* index of current bs/desc buffer */
|
||||
struct pipe_resource *bs_buffers[VIRGL_VIDEO_CODEC_BUF_NUM];
|
||||
struct pipe_resource *desc_buffers[VIRGL_VIDEO_CODEC_BUF_NUM];
|
||||
};
|
||||
|
||||
struct virgl_video_buffer {
|
||||
uint32_t handle;
|
||||
enum pipe_format buffer_format;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
struct virgl_context *vctx;
|
||||
struct pipe_video_buffer *buf;
|
||||
unsigned num_planes;
|
||||
struct pipe_sampler_view **plane_views;
|
||||
};
|
||||
|
||||
struct virgl_base_picture_desc {
|
||||
uint16_t profile; /* enum pipe_video_profile */
|
||||
uint8_t entry_point; /* enum pipe_video_entrypoint */
|
||||
uint8_t protected_playback;
|
||||
uint8_t decrypt_key[256];
|
||||
uint32_t key_size;
|
||||
|
||||
};
|
||||
|
||||
/* H.264 sequence parameter set */
|
||||
struct virgl_h264_sps {
|
||||
uint8_t level_idc;
|
||||
uint8_t chroma_format_idc;
|
||||
uint8_t separate_colour_plane_flag;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
uint8_t seq_scaling_matrix_present_flag;
|
||||
uint8_t ScalingList4x4[6][16];
|
||||
uint8_t ScalingList8x8[6][64];
|
||||
|
||||
uint8_t log2_max_frame_num_minus4;
|
||||
uint8_t pic_order_cnt_type;
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
uint8_t delta_pic_order_always_zero_flag;
|
||||
|
||||
int32_t offset_for_non_ref_pic;
|
||||
int32_t offset_for_top_to_bottom_field;
|
||||
int32_t offset_for_ref_frame[256];
|
||||
|
||||
uint8_t num_ref_frames_in_pic_order_cnt_cycle;
|
||||
uint8_t max_num_ref_frames;
|
||||
uint8_t frame_mbs_only_flag;
|
||||
uint8_t mb_adaptive_frame_field_flag;
|
||||
|
||||
uint8_t direct_8x8_inference_flag;
|
||||
uint8_t MinLumaBiPredSize8x8;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
/* H.264 picture parameter set */
|
||||
struct virgl_h264_pps {
|
||||
struct virgl_h264_sps sps; /* Seq Param Set */
|
||||
|
||||
uint8_t entropy_coding_mode_flag;
|
||||
uint8_t bottom_field_pic_order_in_frame_present_flag;
|
||||
uint8_t num_slice_groups_minus1;
|
||||
uint8_t slice_group_map_type;
|
||||
|
||||
uint8_t slice_group_change_rate_minus1;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
uint8_t weighted_pred_flag;
|
||||
|
||||
uint8_t weighted_bipred_idc;
|
||||
int8_t pic_init_qp_minus26;
|
||||
int8_t pic_init_qs_minus26;
|
||||
int8_t chroma_qp_index_offset;
|
||||
|
||||
uint8_t deblocking_filter_control_present_flag;
|
||||
uint8_t constrained_intra_pred_flag;
|
||||
uint8_t redundant_pic_cnt_present_flag;
|
||||
uint8_t transform_8x8_mode_flag;
|
||||
|
||||
uint8_t ScalingList4x4[6][16];
|
||||
uint8_t ScalingList8x8[6][64];
|
||||
|
||||
int8_t second_chroma_qp_index_offset;
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
|
||||
struct virgl_h264_picture_desc {
|
||||
struct virgl_base_picture_desc base;
|
||||
|
||||
struct virgl_h264_pps pps; /* Picture Param Set */
|
||||
|
||||
uint32_t frame_num;
|
||||
|
||||
uint8_t field_pic_flag;
|
||||
uint8_t bottom_field_flag;
|
||||
uint8_t num_ref_idx_l0_active_minus1;
|
||||
uint8_t num_ref_idx_l1_active_minus1;
|
||||
|
||||
uint32_t slice_count;
|
||||
int32_t field_order_cnt[2];
|
||||
|
||||
uint8_t is_long_term[16];
|
||||
uint8_t top_is_reference[16];
|
||||
uint8_t bottom_is_reference[16];
|
||||
uint32_t field_order_cnt_list[16][2];
|
||||
uint32_t frame_num_list[16];
|
||||
uint32_t buffer_id[16];
|
||||
|
||||
uint8_t is_reference;
|
||||
uint8_t num_ref_frames;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct virgl_h265_sps
|
||||
{
|
||||
uint32_t pic_width_in_luma_samples;
|
||||
uint32_t pic_height_in_luma_samples;
|
||||
|
||||
uint8_t chroma_format_idc;
|
||||
uint8_t separate_colour_plane_flag;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
uint8_t sps_max_dec_pic_buffering_minus1;
|
||||
uint8_t log2_min_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_luma_coding_block_size;
|
||||
|
||||
uint8_t log2_min_transform_block_size_minus2;
|
||||
uint8_t log2_diff_max_min_transform_block_size;
|
||||
uint8_t max_transform_hierarchy_depth_inter;
|
||||
uint8_t max_transform_hierarchy_depth_intra;
|
||||
|
||||
uint8_t ScalingList4x4[6][16];
|
||||
uint8_t ScalingList8x8[6][64];
|
||||
uint8_t ScalingList16x16[6][64];
|
||||
uint8_t ScalingList32x32[2][64];
|
||||
|
||||
uint8_t ScalingListDCCoeff16x16[6];
|
||||
uint8_t ScalingListDCCoeff32x32[2];
|
||||
|
||||
uint8_t scaling_list_enabled_flag;
|
||||
uint8_t amp_enabled_flag;
|
||||
uint8_t sample_adaptive_offset_enabled_flag;
|
||||
uint8_t pcm_enabled_flag;
|
||||
|
||||
uint8_t pcm_sample_bit_depth_luma_minus1;
|
||||
uint8_t pcm_sample_bit_depth_chroma_minus1;
|
||||
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
|
||||
uint8_t pcm_loop_filter_disabled_flag;
|
||||
uint8_t num_short_term_ref_pic_sets;
|
||||
uint8_t long_term_ref_pics_present_flag;
|
||||
uint8_t num_long_term_ref_pics_sps;
|
||||
|
||||
uint8_t sps_temporal_mvp_enabled_flag;
|
||||
uint8_t strong_intra_smoothing_enabled_flag;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct virgl_h265_pps
|
||||
{
|
||||
struct virgl_h265_sps sps;
|
||||
|
||||
uint8_t dependent_slice_segments_enabled_flag;
|
||||
uint8_t output_flag_present_flag;
|
||||
uint8_t num_extra_slice_header_bits;
|
||||
uint8_t sign_data_hiding_enabled_flag;
|
||||
|
||||
uint8_t cabac_init_present_flag;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
int8_t init_qp_minus26;
|
||||
|
||||
uint8_t constrained_intra_pred_flag;
|
||||
uint8_t transform_skip_enabled_flag;
|
||||
uint8_t cu_qp_delta_enabled_flag;
|
||||
uint8_t diff_cu_qp_delta_depth;
|
||||
|
||||
int8_t pps_cb_qp_offset;
|
||||
int8_t pps_cr_qp_offset;
|
||||
uint8_t pps_slice_chroma_qp_offsets_present_flag;
|
||||
uint8_t weighted_pred_flag;
|
||||
|
||||
uint8_t weighted_bipred_flag;
|
||||
uint8_t transquant_bypass_enabled_flag;
|
||||
uint8_t tiles_enabled_flag;
|
||||
uint8_t entropy_coding_sync_enabled_flag;
|
||||
|
||||
uint16_t column_width_minus1[20];
|
||||
uint16_t row_height_minus1[22];
|
||||
|
||||
uint8_t num_tile_columns_minus1;
|
||||
uint8_t num_tile_rows_minus1;
|
||||
uint8_t uniform_spacing_flag;
|
||||
uint8_t loop_filter_across_tiles_enabled_flag;
|
||||
|
||||
uint8_t pps_loop_filter_across_slices_enabled_flag;
|
||||
uint8_t deblocking_filter_control_present_flag;
|
||||
uint8_t deblocking_filter_override_enabled_flag;
|
||||
uint8_t pps_deblocking_filter_disabled_flag;
|
||||
|
||||
int8_t pps_beta_offset_div2;
|
||||
int8_t pps_tc_offset_div2;
|
||||
uint8_t lists_modification_present_flag;
|
||||
uint8_t log2_parallel_merge_level_minus2;
|
||||
|
||||
uint16_t st_rps_bits;
|
||||
uint8_t slice_segment_header_extension_present_flag;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
struct virgl_h265_picture_desc
|
||||
{
|
||||
struct virgl_base_picture_desc base;
|
||||
|
||||
struct virgl_h265_pps pps;
|
||||
|
||||
int32_t CurrPicOrderCntVal;
|
||||
uint32_t ref[16];
|
||||
int32_t PicOrderCntVal[16];
|
||||
|
||||
uint32_t NumPocTotalCurr;
|
||||
uint32_t NumDeltaPocsOfRefRpsIdx;
|
||||
uint32_t NumShortTermPictureSliceHeaderBits;
|
||||
uint32_t NumLongTermPictureSliceHeaderBits;
|
||||
|
||||
uint8_t IsLongTerm[16];
|
||||
|
||||
uint8_t IDRPicFlag;
|
||||
uint8_t RAPPicFlag;
|
||||
uint8_t CurrRpsIdx;
|
||||
uint8_t NumPocStCurrBefore;
|
||||
|
||||
uint8_t NumPocStCurrAfter;
|
||||
uint8_t NumPocLtCurr;
|
||||
uint8_t UseRefPicList;
|
||||
uint8_t UseStRpsBits;
|
||||
|
||||
uint8_t RefPicSetStCurrBefore[8];
|
||||
uint8_t RefPicSetStCurrAfter[8];
|
||||
uint8_t RefPicSetLtCurr[8];
|
||||
|
||||
uint8_t RefPicList[2][15];
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct virgl_mpeg4_picture_desc
|
||||
{
|
||||
struct virgl_base_picture_desc base;
|
||||
|
||||
int32_t trd[2];
|
||||
int32_t trb[2];
|
||||
uint16_t vop_time_increment_resolution;
|
||||
uint8_t vop_coding_type;
|
||||
uint8_t vop_fcode_forward;
|
||||
uint8_t vop_fcode_backward;
|
||||
uint8_t resync_marker_disable;
|
||||
uint8_t interlaced;
|
||||
uint8_t quant_type;
|
||||
uint8_t quarter_sample;
|
||||
uint8_t short_video_header;
|
||||
uint8_t rounding_control;
|
||||
uint8_t alternate_vertical_scan_flag;
|
||||
uint8_t top_field_first;
|
||||
|
||||
uint8_t intra_matrix[64];
|
||||
uint8_t non_intra_matrix[64];
|
||||
|
||||
uint32_t ref[2];
|
||||
};
|
||||
|
||||
union virgl_picture_desc {
|
||||
struct virgl_base_picture_desc base;
|
||||
struct virgl_h264_picture_desc h264;
|
||||
struct virgl_h265_picture_desc h265;
|
||||
struct virgl_mpeg4_picture_desc mpeg4;
|
||||
};
|
||||
|
||||
static inline struct virgl_video_codec *
|
||||
virgl_video_codec(struct pipe_video_codec *codec)
|
||||
{
|
||||
return (struct virgl_video_codec *)codec;
|
||||
}
|
||||
|
||||
static inline struct virgl_video_buffer *
|
||||
virgl_video_buffer(struct pipe_video_buffer *buffer)
|
||||
{
|
||||
return buffer ? vl_video_buffer_get_associated_data(buffer, NULL) : NULL;
|
||||
}
|
||||
|
||||
struct pipe_video_codec *
|
||||
virgl_video_create_codec(struct pipe_context *ctx,
|
||||
const struct pipe_video_codec *templ);
|
||||
|
||||
struct pipe_video_buffer *
|
||||
virgl_video_create_buffer(struct pipe_context *ctx,
|
||||
const struct pipe_video_buffer *tmpl);
|
||||
|
||||
#endif /* VIRGL_VIDEO_H */
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ libva_gallium = shared_library(
|
|||
link_whole : [libva_st],
|
||||
link_with : link_with_libva_gallium,
|
||||
dependencies : [
|
||||
dep_libdrm, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12,
|
||||
dep_libdrm, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12, driver_virgl,
|
||||
idep_mesautil,
|
||||
],
|
||||
link_depends : va_link_depends,
|
||||
|
|
@ -64,6 +64,7 @@ libva_gallium = shared_library(
|
|||
foreach d : [[with_gallium_r600, 'r600'],
|
||||
[with_gallium_radeonsi, 'radeonsi'],
|
||||
[with_gallium_nouveau, 'nouveau'],
|
||||
[with_gallium_virgl, 'virtio_gpu'],
|
||||
[with_gallium_d3d12_video, 'd3d12']]
|
||||
if d[0]
|
||||
va_drivers += '@0@_drv_video.so'.format(d[1])
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ libvdpau_gallium = shared_library(
|
|||
link_with : link_with_libvdpau_gallium,
|
||||
dependencies : [
|
||||
idep_mesautil,
|
||||
driver_r300, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12,
|
||||
driver_r300, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12, driver_virgl,
|
||||
],
|
||||
link_depends : vdpau_link_depends,
|
||||
soversion : '@0@.@1@.0'.format(VDPAU_MAJOR, VDPAU_MINOR),
|
||||
|
|
@ -69,6 +69,7 @@ foreach d : [[with_gallium_r300, 'r300'],
|
|||
[with_gallium_r600, 'r600'],
|
||||
[with_gallium_radeonsi, 'radeonsi'],
|
||||
[with_gallium_nouveau, 'nouveau'],
|
||||
[with_gallium_virgl, 'virtio_gpu'],
|
||||
[with_gallium_d3d12_video, 'd3d12']]
|
||||
if d[0]
|
||||
vdpau_drivers += 'libvdpau_@0@.so.@1@.@2@.0'.format(d[1], VDPAU_MAJOR, VDPAU_MINOR)
|
||||
|
|
|
|||
|
|
@ -546,6 +546,26 @@ struct virgl_caps_v1 {
|
|||
uint32_t max_texture_gather_components;
|
||||
};
|
||||
|
||||
struct virgl_video_caps {
|
||||
uint32_t profile:8;
|
||||
uint32_t entrypoint:8;
|
||||
uint32_t max_level:8;
|
||||
uint32_t stacked_frames:8;
|
||||
|
||||
uint32_t max_width:16;
|
||||
uint32_t max_height:16;
|
||||
|
||||
uint32_t prefered_format:16;
|
||||
uint32_t max_macroblocks:16;
|
||||
|
||||
uint32_t npot_texture:1;
|
||||
uint32_t supports_progressive:1;
|
||||
uint32_t supports_interlaced:1;
|
||||
uint32_t prefers_interlaced:1;
|
||||
uint32_t max_temporal_layers:8;
|
||||
uint32_t reserved:20;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct should be growable when used in capset 2,
|
||||
* so we shouldn't have to add a v3 ever.
|
||||
|
|
@ -603,6 +623,8 @@ struct virgl_caps_v2 {
|
|||
uint32_t max_shader_sampler_views;
|
||||
struct virgl_supported_format_mask supported_multisample_formats;
|
||||
uint32_t max_const_buffer_size[6]; // PIPE_SHADER_TYPES
|
||||
uint32_t num_video_caps;
|
||||
struct virgl_video_caps video_caps[32];
|
||||
};
|
||||
|
||||
union virgl_caps {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,18 @@ enum virgl_context_cmd {
|
|||
VIRGL_CCMD_GET_MEMORY_INFO,
|
||||
VIRGL_CCMD_EMIT_STRING_MARKER,
|
||||
VIRGL_CCMD_LINK_SHADER,
|
||||
|
||||
/* video codec */
|
||||
VIRGL_CCMD_CREATE_VIDEO_CODEC,
|
||||
VIRGL_CCMD_DESTROY_VIDEO_CODEC,
|
||||
VIRGL_CCMD_CREATE_VIDEO_BUFFER,
|
||||
VIRGL_CCMD_DESTROY_VIDEO_BUFFER,
|
||||
VIRGL_CCMD_BEGIN_FRAME,
|
||||
VIRGL_CCMD_DECODE_MACROBLOCK,
|
||||
VIRGL_CCMD_DECODE_BITSTREAM,
|
||||
VIRGL_CCMD_ENCODE_BITSTREAM,
|
||||
VIRGL_CCMD_END_FRAME,
|
||||
|
||||
VIRGL_MAX_COMMANDS
|
||||
};
|
||||
|
||||
|
|
@ -696,4 +708,52 @@ enum vrend_tweak_type {
|
|||
#define VIRGL_LINK_SHADER_TESS_EVAL_HANDLE 5
|
||||
#define VIRGL_LINK_SHADER_COMPUTE_HANDLE 6
|
||||
|
||||
/* VIRGL_CCMD_CREATE_VIDEO_CODEC */
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_SIZE 7
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_HANDLE 1
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_PROFILE 2
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_ENTRYPOINT 3
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_CHROMA_FMT 4
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_LEVEL 5
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_WIDTH 6
|
||||
#define VIRGL_CREATE_VIDEO_CODEC_HEIGHT 7
|
||||
|
||||
/* VIRGL_CCMD_DESTROY_VIDEO_CODEC */
|
||||
#define VIRGL_DESTROY_VIDEO_CODEC_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_CODEC_HANDLE 1
|
||||
|
||||
/* VIRGL_CCMD_CREATE_VIDEO_BUFFER */
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_MIN_SIZE 5
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_HANDLE 1
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_FORMAT 2
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_WIDTH 3
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_HEIGHT 4
|
||||
#define VIRGL_CREATE_VIDEO_BUFFER_RES_BASE 5
|
||||
|
||||
/* VIRGL_CCMD_DESTROY_VIDEO_BUFFER */
|
||||
#define VIRGL_DESTROY_VIDEO_BUFFER_SIZE 1
|
||||
#define VIRGL_DESTROY_VIDEO_BUFFER_HANDLE 1
|
||||
|
||||
/* VIRGL_CCMD_BEGIN_FRAME */
|
||||
#define VIRGL_BEGIN_FRAME_SIZE 2
|
||||
#define VIRGL_BEGIN_FRAME_CDC_HANDLE 1
|
||||
#define VIRGL_BEGIN_FRAME_TGT_HANDLE 2
|
||||
|
||||
/* VIRGL_CCMD_DECODE_MACROBLOCK */
|
||||
|
||||
/* VIRGL_CCMD_DECODE_BITSTREAM */
|
||||
#define VIRGL_DECODE_BS_SIZE 5
|
||||
#define VIRGL_DECODE_BS_CDC_HANDLE 1
|
||||
#define VIRGL_DECODE_BS_TGT_HANDLE 2
|
||||
#define VIRGL_DECODE_BS_DSC_HANDLE 3
|
||||
#define VIRGL_DECODE_BS_BUF_HANDLE 4
|
||||
#define VIRGL_DECODE_BS_BUF_SIZE 5
|
||||
|
||||
/* VIRGL_CCMD_ENCODE_BITSTREAM */
|
||||
|
||||
/* VIRGL_CCMD_END_FRAME */
|
||||
#define VIRGL_END_FRAME_SIZE 2
|
||||
#define VIRGL_END_FRAME_CDC_HANDLE 1
|
||||
#define VIRGL_END_FRAME_TGT_HANDLE 2
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue