Module: Mesa
Branch: main
Commit: 4697b71c4e3d67640a03bf6c804efce02b23d553
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=4697b71c4e3d67640a03bf6c804efce02b23d553

Author: Ruijing Dong <[email protected]>
Date:   Tue Apr 18 22:24:06 2023 -0400

radeonsi/vcn: add some av1 encoding function

preparation for enabling av1 encoding in radeonsi,
adding the entropy related functioin.

Reviewed-by: Boyuan Zhang <[email protected]>
Signed-off-by: Ruijing Dong <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22585>

---

 src/gallium/drivers/radeonsi/radeon_vcn_enc.c | 82 +++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/radeon_vcn_enc.h | 14 +++++
 2 files changed, 96 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c 
b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c
index 7c024315ae1..baf5c5d8dde 100644
--- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.c
+++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.c
@@ -894,6 +894,39 @@ void radeon_enc_code_fixed_bits(struct radeon_encoder 
*enc, unsigned int value,
    }
 }
 
+void radeon_enc_code_uvlc(struct radeon_encoder *enc, unsigned int value)
+{
+   uint32_t num_bits = 0;
+   uint64_t value_plus1 = (uint64_t)value + 1;
+   uint32_t num_leading_zeros = 0;
+
+   while ((uint64_t)1 << num_bits <= value_plus1)
+      num_bits++;
+
+   num_leading_zeros = num_bits - 1;
+   radeon_enc_code_fixed_bits(enc, 0, num_leading_zeros);
+   radeon_enc_code_fixed_bits(enc, 1, 1);
+   radeon_enc_code_fixed_bits(enc, (uint32_t)value_plus1, num_leading_zeros);
+}
+
+void radeon_enc_code_leb128(uint8_t *buf, uint32_t value,
+                            uint32_t num_bytes)
+{
+   uint8_t leb128_byte = 0;
+   uint32_t i = 0;
+
+   do {
+      leb128_byte = (value & 0x7f);
+      value >>= 7;
+      if (num_bytes > 1)
+         leb128_byte |= 0x80;
+
+      *(buf + i) = leb128_byte;
+      num_bytes--;
+      i++;
+   } while((leb128_byte & 0x80));
+}
+
 void radeon_enc_reset(struct radeon_encoder *enc)
 {
    enc->emulation_prevention = false;
@@ -955,3 +988,52 @@ void radeon_enc_code_se(struct radeon_encoder *enc, int 
value)
 
    radeon_enc_code_ue(enc, v);
 }
+
+/* dummy function for re-using the same pipeline */
+void radeon_enc_dummy(struct radeon_encoder *enc) {}
+
+/* this function has to be in pair with AV1 header copy instruction type at 
the end */
+static void radeon_enc_av1_bs_copy_end(struct radeon_encoder *enc, uint32_t 
bits)
+{
+   assert(bits > 0);
+   /* it must be dword aligned at the end */
+   *enc->enc_pic.copy_start = ALIGN_TO(bits, 32) * 4 + 12;
+   *(enc->enc_pic.copy_start + 2) = bits;
+}
+
+/* av1 bitstream instruction type */
+void radeon_enc_av1_bs_instruction_type(struct radeon_encoder *enc,
+                                        uint32_t inst,
+                                        uint32_t obu_type)
+{
+   radeon_enc_flush_headers(enc);
+
+   if (enc->bits_output)
+      radeon_enc_av1_bs_copy_end(enc, enc->bits_output);
+
+   enc->enc_pic.copy_start = &enc->cs.current.buf[enc->cs.current.cdw++];
+   RADEON_ENC_CS(inst);
+
+   if (inst != RENCODE_HEADER_INSTRUCTION_COPY) {
+      *enc->enc_pic.copy_start = 8;
+      if (inst == RENCODE_AV1_BITSTREAM_INSTRUCTION_OBU_START) {
+         *enc->enc_pic.copy_start += 4;
+         RADEON_ENC_CS(obu_type);
+      }
+   } else
+      RADEON_ENC_CS(0); /* allocate a dword for number of bits */
+
+   radeon_enc_reset(enc);
+}
+
+uint32_t radeon_enc_value_bits(uint32_t value)
+{
+   uint32_t i = 1;
+
+   while (value > 1) {
+      i++;
+      value >>= 1;
+   }
+
+   return i;
+}
diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h 
b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h
index cb798258ad6..c1e1847afd2 100644
--- a/src/gallium/drivers/radeonsi/radeon_vcn_enc.h
+++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc.h
@@ -854,6 +854,8 @@ struct radeon_encoder {
 void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf,
                            unsigned usage, enum radeon_bo_domain domain, 
signed offset);
 
+void radeon_enc_dummy(struct radeon_encoder *enc);
+
 void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set);
 
 void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char 
byte);
@@ -873,6 +875,11 @@ void radeon_enc_code_ue(struct radeon_encoder *enc, 
unsigned int value);
 
 void radeon_enc_code_se(struct radeon_encoder *enc, int value);
 
+void radeon_enc_code_uvlc(struct radeon_encoder *enc, unsigned int value);
+
+void radeon_enc_code_leb128(unsigned char *buf, unsigned int value,
+                            unsigned int num_bytes);
+
 void radeon_enc_1_2_init(struct radeon_encoder *enc);
 
 void radeon_enc_2_0_init(struct radeon_encoder *enc);
@@ -881,4 +888,11 @@ void radeon_enc_3_0_init(struct radeon_encoder *enc);
 
 void radeon_enc_4_0_init(struct radeon_encoder *enc);
 
+void radeon_enc_av1_bs_instruction_type(struct radeon_encoder *enc,
+                                        unsigned int inst, unsigned int 
obu_type);
+
+unsigned char *radeon_enc_av1_header_size_offset(struct radeon_encoder *enc);
+
+unsigned int radeon_enc_value_bits(unsigned int value);
+
 #endif // _RADEON_VCN_ENC_H

Reply via email to