Skip to content

Commit

Permalink
[AVS-286] Add resource reservation for transcode pool (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
epingel2 authored Jun 24, 2022
1 parent ecac4bf commit 828fb84
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 11 deletions.
6 changes: 5 additions & 1 deletion xilinx/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pub mod sys;
pub use sys::*;

/*---- transcoder ----*/
pub mod xlnx_transcoder_utils;
pub use xlnx_transcoder_utils::*;

/*---- decoder ----*/
pub mod xlnx_decoder;
pub use xlnx_decoder::*;
Expand Down Expand Up @@ -41,7 +45,7 @@ const XCLBIN_FILENAME: &[u8] = b"/opt/xilinx/xcdr/xclbins/transcode.xclbin\0";
///
pub fn xlnx_init_all_devices() -> Result<i32, simple_error::SimpleError> {
let mut xclbin_params = Vec::new();
let device_count = unsafe { xclProbe() } as i32;
let device_count = unsafe { xclProbe() } as i32;
for i in 0..device_count {
xclbin_params.push(XmaXclbinParameter {
xclbin_name: XCLBIN_FILENAME.as_ptr() as *mut i8,
Expand Down
2 changes: 1 addition & 1 deletion xilinx/src/xlnx_dec_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ fn xlnx_fill_dec_pool_props(cu_pool_prop: &mut xrmCuPoolProperty, dec_load: i32)
Ok(())
}

pub(crate) fn xlnx_reserve_dec_resource(xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<(), SimpleError> {
pub fn xlnx_reserve_dec_resource(xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<(), SimpleError> {
// a device has already been chosen, there is no need to assign a reserve id.
if xlnx_dec_ctx.device_id >= 0 {
return Ok(());
Expand Down
9 changes: 3 additions & 6 deletions xilinx/src/xlnx_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ pub struct XlnxDecoder {

impl XlnxDecoder {
pub fn new(xma_dec_props: &mut XmaDecoderProperties, xlnx_dec_ctx: &mut XlnxDecoderXrmCtx) -> Result<Self, SimpleError> {
// reserve the required decoding resources and assign reserve ID
xlnx_reserve_dec_resource(xlnx_dec_ctx)?;

let dec_session = xlnx_create_dec_session(xma_dec_props, xlnx_dec_ctx)?;

let mut frame_props: XmaFrameProperties = Default::default();
Expand All @@ -28,9 +25,9 @@ impl XlnxDecoder {

let out_frame = unsafe { xma_frame_alloc(&mut frame_props, true) };

// Loop through the planes. no buffer shouold be allocated yet.
// Since this will be used in a pipeline, xvbm will allocate the buffers.
// So we need to specify to use device buffers.
// Loop through the planes. no buffer shouold be allocated yet.
// Since this will be used in a pipeline, xvbm will allocate the buffers.
// So we need to specify to use device buffers.
unsafe {
for i in 0..2 {
(*out_frame).data[i].buffer_type = XmaBufferType_XMA_DEVICE_BUFFER_TYPE;
Expand Down
1 change: 1 addition & 0 deletions xilinx/src/xlnx_enc_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ fn xlnx_enc_cu_alloc_reserve_id(xma_enc_props: &mut XmaEncoderProperties, xlnx_e
}

fn xlnx_enc_cu_alloc(xma_enc_props: &mut XmaEncoderProperties, xlnx_enc_ctx: &mut XlnxEncoderXrmCtx) -> Result<(), SimpleError> {
xlnx_enc_ctx.enc_load = xlnx_calc_enc_load(xlnx_enc_ctx.xrm_ctx, xma_enc_props)?;
if xlnx_enc_ctx.device_id >= 0 {
xlnx_enc_cu_alloc_device_id(xma_enc_props, xlnx_enc_ctx)?;
} else {
Expand Down
2 changes: 0 additions & 2 deletions xilinx/src/xlnx_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ pub struct XlnxEncoder {

impl XlnxEncoder {
pub fn new(xma_enc_props: &mut XmaEncoderProperties, xlnx_enc_ctx: &mut XlnxEncoderXrmCtx) -> Result<Self, SimpleError> {
xlnx_reserve_enc_resource(xlnx_enc_ctx)?;

let enc_session = xlnx_create_enc_session(xma_enc_props, xlnx_enc_ctx)?;

let out_buffer = unsafe { xma_data_buffer_alloc(0, true) };
Expand Down
1 change: 0 additions & 1 deletion xilinx/src/xlnx_scaler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub struct XlnxScaler {

impl XlnxScaler {
pub fn new(xma_scal_props: &mut XmaScalerProperties, xlnx_scal_ctx: &mut XlnxScalerXrmCtx) -> Result<Self, SimpleError> {
xlnx_reserve_scal_resource(xlnx_scal_ctx)?;
let scal_session = xlnx_create_scal_session(xma_scal_props, xlnx_scal_ctx)?;

let mut out_frame_list = Vec::new();
Expand Down
139 changes: 139 additions & 0 deletions xilinx/src/xlnx_transcoder_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use crate::{strcpy_to_arr_i8, sys::*, xlnx_dec_utils::*, xlnx_enc_utils::*, xlnx_scal_utils::*, xrm_precision_1000000_bitmask};
use simple_error::{bail, SimpleError};

pub struct XlnxTranscodeLoad {
pub dec_load: i32,
pub scal_load: i32,
pub enc_load: i32,
pub enc_num: i32,
}

pub struct XlnxTranscodeXrmCtx {
pub xrm_ctx: xrmContext,
pub transcode_load: XlnxTranscodeLoad,
pub reserve_idx: u64,
}

impl XlnxTranscodeXrmCtx {
pub fn new() -> Self {
let xrm_ctx = unsafe {xrmCreateContext(XRM_API_VERSION_1)};

Self {
xrm_ctx,
transcode_load: XlnxTranscodeLoad {
dec_load: 0,
scal_load: 0,
enc_load: 0,
enc_num:0,
},
reserve_idx: 0
}
}
}

pub fn xlnx_calc_transcode_load(
xlnx_transcode_xrm_ctx: &mut XlnxTranscodeXrmCtx,
xma_dec_props: &mut XmaDecoderProperties,
xma_scal_props: &mut XmaScalerProperties,
xma_enc_props_list: Vec<&mut XmaEncoderProperties>,
transcode_cu_pool_prop: &mut xrmCuPoolProperty,
) -> Result<(), SimpleError> {
xlnx_transcode_xrm_ctx.transcode_load.dec_load = xlnx_calc_dec_load(xlnx_transcode_xrm_ctx.xrm_ctx, xma_dec_props)?;
xlnx_transcode_xrm_ctx.transcode_load.scal_load = xlnx_calc_scal_load(xlnx_transcode_xrm_ctx.xrm_ctx, xma_scal_props)?;
for xma_enc_props in xma_enc_props_list {
xlnx_transcode_xrm_ctx.transcode_load.enc_load += xlnx_calc_enc_load(xlnx_transcode_xrm_ctx.xrm_ctx, xma_enc_props)?;
xlnx_transcode_xrm_ctx.transcode_load.enc_num += 1;
}

xlnx_fill_transcode_pool_props(transcode_cu_pool_prop, &xlnx_transcode_xrm_ctx.transcode_load)?;
Ok(())
}

fn xlnx_fill_transcode_pool_props(transcode_cu_pool_prop: &mut xrmCuPoolProperty, transcode_load: &XlnxTranscodeLoad) -> Result<(), SimpleError> {
let mut cu_num = 0;
transcode_cu_pool_prop.cuListProp.sameDevice = true;
transcode_cu_pool_prop.cuListNum = 1;

if transcode_load.dec_load > 0 {
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelName, "decoder")?;
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelAlias, "DECODER_MPSOC")?;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].devExcl = false;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].requestLoad = xrm_precision_1000000_bitmask(transcode_load.dec_load);
cu_num += 1;

strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelName, "kernel_vcu_decoder")?;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].devExcl = false;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].requestLoad = xrm_precision_1000000_bitmask(XRM_MAX_CU_LOAD_GRANULARITY_1000000 as i32);
cu_num += 1;
}

if transcode_load.scal_load > 0 {
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelName, "scaler")?;
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelAlias, "SCALER_MPSOC")?;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].devExcl = false;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].requestLoad = xrm_precision_1000000_bitmask(transcode_load.scal_load);
cu_num += 1;
}

if transcode_load.enc_load > 0 {
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelName, "encoder")?;
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelAlias, "ENCODER_MPSOC")?;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].devExcl = false;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].requestLoad = xrm_precision_1000000_bitmask(transcode_load.enc_load);
cu_num += 1;

for _ in 0..transcode_load.enc_num {
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelName, "kernel_vcu_encoder")?;
strcpy_to_arr_i8(&mut transcode_cu_pool_prop.cuListProp.cuProps[cu_num].kernelAlias, "")?;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].devExcl = false;
transcode_cu_pool_prop.cuListProp.cuProps[cu_num].requestLoad = xrm_precision_1000000_bitmask(XRM_MAX_CU_LOAD_GRANULARITY_1000000 as i32);
cu_num += 1;
}
}

transcode_cu_pool_prop.cuListProp.cuNum = cu_num as i32;
Ok(())
}

pub fn xlnx_reserve_transcode_resource(
xlnx_transcode_xrm_ctx: &mut XlnxTranscodeXrmCtx,
xma_dec_props: &mut XmaDecoderProperties,
xma_scal_props: &mut XmaScalerProperties,
xma_enc_props: Vec<&mut XmaEncoderProperties>,
) -> Result<(), SimpleError> {
let mut transcode_cu_pool_prop: xrmCuPoolProperty = Default::default();
xlnx_calc_transcode_load(
xlnx_transcode_xrm_ctx,
xma_dec_props,
xma_scal_props,
xma_enc_props,
&mut transcode_cu_pool_prop,
)?;
unsafe {
let num_cu_pool = xrmCheckCuPoolAvailableNum(xlnx_transcode_xrm_ctx.xrm_ctx, &mut transcode_cu_pool_prop);
if num_cu_pool <= 0 {
bail!("no xilinx hardware resources avaliable for allocation")
}
xlnx_transcode_xrm_ctx.reserve_idx = xrmCuPoolReserve(xlnx_transcode_xrm_ctx.xrm_ctx, &mut transcode_cu_pool_prop);
if xlnx_transcode_xrm_ctx.reserve_idx == 0 {
bail!("failed to reserve encode cu pool")
}
}

Ok(())
}

impl Drop for XlnxTranscodeXrmCtx {
fn drop(&mut self) {
if self.xrm_ctx.is_null() {
return;
}
unsafe {
if self.reserve_idx != 0 {
xrmCuPoolRelinquish(self.xrm_ctx, self.reserve_idx);
}

xrmDestroyContext(self.xrm_ctx);
}
}
}

0 comments on commit 828fb84

Please sign in to comment.