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