Mesa (master): radeon/vcn: program drm message buffer
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Nov 4 09:57:52 UTC 2020
Module: Mesa
Branch: master
Commit: f20a20b1e3f513e0075c87d3b406f95bd9ed7df2
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f20a20b1e3f513e0075c87d3b406f95bd9ed7df2
Author: Boyuan Zhang <boyuan.zhang at amd.com>
Date: Wed May 13 20:08:55 2020 -0400
radeon/vcn: program drm message buffer
Add a function to handle drm message buffer using input decryption parameters.
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7006>
---
src/gallium/drivers/radeon/radeon_vcn_dec.c | 117 ++++++++++++++++++++++++++--
1 file changed, 109 insertions(+), 8 deletions(-)
diff --git a/src/gallium/drivers/radeon/radeon_vcn_dec.c b/src/gallium/drivers/radeon/radeon_vcn_dec.c
index 04d879af03e..15781d3036e 100644
--- a/src/gallium/drivers/radeon/radeon_vcn_dec.c
+++ b/src/gallium/drivers/radeon/radeon_vcn_dec.c
@@ -34,6 +34,7 @@
#include "util/u_video.h"
#include "vl/vl_mpeg12_decoder.h"
#include "vl/vl_probs_table.h"
+#include "pspdecryptionparam.h"
#include <assert.h>
#include <stdio.h>
@@ -550,6 +551,47 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
return result;
}
+static void set_drm_keys(rvcn_dec_message_drm_t *drm, DECRYPT_PARAMETERS *decrypted)
+{
+ int cbc = decrypted->u.s.cbc;
+ int ctr = decrypted->u.s.ctr;
+ int id = decrypted->u.s.drm_id;
+ int ekc = 1;
+ int data1 = 1;
+ int data2 = 1;
+
+ drm->drm_cmd = 0;
+ drm->drm_cntl = 0;
+
+ drm->drm_cntl = 1 << DRM_CNTL_BYPASS_SHIFT;
+
+ if (cbc || ctr) {
+ drm->drm_cntl = 0 << DRM_CNTL_BYPASS_SHIFT;
+ drm->drm_cmd |= 0xff << DRM_CMD_BYTE_MASK_SHIFT;
+
+ if (ctr)
+ drm->drm_cmd |= 0x00 << DRM_CMD_ALGORITHM_SHIFT;
+ else if (cbc)
+ drm->drm_cmd |= 0x02 << DRM_CMD_ALGORITHM_SHIFT;
+
+ drm->drm_cmd |= 1 << DRM_CMD_GEN_MASK_SHIFT;
+ drm->drm_cmd |= ekc << DRM_CMD_UNWRAP_KEY_SHIFT;
+ drm->drm_cmd |= 0 << DRM_CMD_OFFSET_SHIFT;
+ drm->drm_cmd |= data2 << DRM_CMD_CNT_DATA_SHIFT;
+ drm->drm_cmd |= data1 << DRM_CMD_CNT_KEY_SHIFT;
+ drm->drm_cmd |= ekc << DRM_CMD_KEY_SHIFT;
+ drm->drm_cmd |= id << DRM_CMD_SESSION_SEL_SHIFT;
+
+ if (ekc)
+ memcpy(drm->drm_wrapped_key, decrypted->encrypted_key, 16);
+ if (data1)
+ memcpy(drm->drm_key, decrypted->session_iv, 16);
+ if (data2)
+ memcpy(drm->drm_counter, decrypted->encrypted_iv, 16);
+ drm->drm_offset = 0;
+ }
+}
+
static unsigned calc_ctx_size_h265_main(struct radeon_decoder *dec)
{
unsigned width = align(dec->base.width, VL_MACROBLOCK_WIDTH);
@@ -796,29 +838,51 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
{
+ DECRYPT_PARAMETERS *decrypt = (DECRYPT_PARAMETERS *)picture->decrypt_key;
+ bool encrypted = (DECRYPT_PARAMETERS *)picture->protected_playback;
struct si_texture *luma = (struct si_texture *)((struct vl_video_buffer *)target)->resources[0];
struct si_texture *chroma =
(struct si_texture *)((struct vl_video_buffer *)target)->resources[1];
+ ASSERTED struct si_screen *sscreen = (struct si_screen *)dec->screen;
rvcn_dec_message_header_t *header;
+ rvcn_dec_message_index_t *index_drm;
rvcn_dec_message_index_t *index;
rvcn_dec_message_decode_t *decode;
unsigned sizes = 0, offset_decode, offset_codec;
+ unsigned int offset_drm;
void *codec;
+ rvcn_dec_message_drm_t *drm = NULL;
header = dec->msg;
sizes += sizeof(rvcn_dec_message_header_t);
- index = (void *)header + sizeof(rvcn_dec_message_header_t);
- sizes += sizeof(rvcn_dec_message_index_t);
+ if (encrypted) {
+ index_drm = (void*)header + sizeof(rvcn_dec_message_header_t);
+ sizes += sizeof(rvcn_dec_message_index_t);
+ index = (void*)index_drm + sizeof(rvcn_dec_message_index_t);
+ sizes += sizeof(rvcn_dec_message_index_t);
+ } else {
+ index = (void*)header + sizeof(rvcn_dec_message_header_t);
+ sizes += sizeof(rvcn_dec_message_index_t);
+ }
offset_decode = sizes;
decode = (void *)index + sizeof(rvcn_dec_message_index_t);
sizes += sizeof(rvcn_dec_message_decode_t);
+ if (encrypted) {
+ offset_drm = sizes;
+ drm = (void*)decode + sizeof(rvcn_dec_message_decode_t);
+ sizes += sizeof(rvcn_dec_message_drm_t);
+ codec = (void*)drm + sizeof(rvcn_dec_message_drm_t);
+ } else
+ codec = (void*)decode + sizeof(rvcn_dec_message_decode_t);
offset_codec = sizes;
- codec = (void *)decode + sizeof(rvcn_dec_message_decode_t);
memset(dec->msg, 0, sizes);
header->header_size = sizeof(rvcn_dec_message_header_t);
header->total_size = sizes;
- header->num_buffers = 2;
+ if (encrypted)
+ header->num_buffers = 3;
+ else
+ header->num_buffers = 2;
header->msg_type = RDECODE_MSG_DECODE;
header->stream_handle = dec->stream_handle;
header->status_report_feedback_number = dec->frame_number;
@@ -827,6 +891,12 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
header->index[0].offset = offset_decode;
header->index[0].size = sizeof(rvcn_dec_message_decode_t);
header->index[0].filled = 0;
+ if (encrypted) {
+ index_drm->message_id = RDECODE_MESSAGE_DRM;
+ index_drm->offset = offset_drm;
+ index_drm->size = sizeof(rvcn_dec_message_drm_t);
+ index_drm->filled = 0;
+ }
index->offset = offset_codec;
index->size = sizeof(rvcn_dec_message_avc_t);
@@ -843,7 +913,12 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
unsigned dpb_size = calc_dpb_size(dec);
bool r;
if (dpb_size) {
- r = si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT);
+ if (encrypted) {
+ r = si_vid_create_tmz_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT);
+ } else {
+ r = si_vid_create_buffer(dec->screen, &dec->dpb, dpb_size, PIPE_USAGE_DEFAULT);
+ }
+ assert(encrypted == (bool)(dec->dpb.res->flags & RADEON_FLAG_ENCRYPTED));
if (!r) {
RVID_ERR("Can't allocated dpb.\n");
return NULL;
@@ -857,7 +932,12 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
if (dec->stream_type == RDECODE_CODEC_H264_PERF) {
unsigned ctx_size = calc_ctx_size_h264_perf(dec);
bool r;
- r = si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ if (encrypted) {
+ r = si_vid_create_tmz_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ } else {
+ r = si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ }
+ assert(encrypted == (bool)(dec->ctx.res->flags & RADEON_FLAG_ENCRYPTED));
if (!r) {
RVID_ERR("Can't allocated context buffer.\n");
@@ -888,7 +968,11 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
if (dec->base.profile == PIPE_VIDEO_PROFILE_VP9_PROFILE2)
ctx_size += 8 * 2 * 4096;
- r = si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ if (encrypted) {
+ r = si_vid_create_tmz_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ } else {
+ r = si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ }
if (!r) {
RVID_ERR("Can't allocated context buffer.\n");
return NULL;
@@ -903,15 +987,27 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
dec->bs_ptr = NULL;
} else if (fmt == PIPE_VIDEO_FORMAT_HEVC) {
unsigned ctx_size;
+ bool r;
if (dec->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)
ctx_size = calc_ctx_size_h265_main10(dec, (struct pipe_h265_picture_desc *)picture);
else
ctx_size = calc_ctx_size_h265_main(dec);
- if (!si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT))
+
+ if (encrypted) {
+ r = si_vid_create_tmz_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ } else {
+ r = si_vid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT);
+ }
+ if (!r) {
RVID_ERR("Can't allocated context buffer.\n");
+ return NULL;
+ }
si_vid_clear_buffer(dec->base.context, &dec->ctx);
}
}
+ if (encrypted != dec->ws->cs_is_secure(dec->cs)) {
+ dec->ws->cs_flush(dec->cs, RADEON_FLUSH_TOGGLE_SECURE_SUBMISSION, NULL);
+ }
decode->dpb_size = dec->dpb.res->buf->size;
decode->dt_size = si_resource(((struct vl_video_buffer *)target)->resources[0])->buf->size +
@@ -953,6 +1049,11 @@ static struct pb_buffer *rvcn_dec_message_decode(struct radeon_decoder *dec,
decode->dt_chroma_bottom_offset = decode->dt_chroma_top_offset;
}
+ if (encrypted) {
+ assert(sscreen->info.has_tmz_support);
+ set_drm_keys(drm, decrypt);
+ }
+
switch (u_reduce_video_profile(picture->profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
rvcn_dec_message_avc_t avc = get_h264_msg(dec, (struct pipe_h264_picture_desc *)picture);
More information about the mesa-commit
mailing list