@ -256,61 +256,103 @@ NvResult nvhost_ctrl_gpu::ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params) {
}
NvResult nvhost_ctrl_gpu : : ZBCSetTable ( IoctlZbcSetTable & params ) {
LOG_DEBUG ( Service_NVDRV , " called " ) ;
ZbcEntry entry = { } ;
std : : memset ( & entry , 0 , sizeof ( entry ) ) ;
// TODO(ogniK): What does this even actually do?
// TODO(myself): This thing I guess
if ( params . type = = 1 ) {
for ( auto i = 0 ; i < 4 ; + + i ) {
entry . color_ds [ i ] = params . color_ds [ i ] ;
entry . color_l2 [ i ] = params . color_l2 [ i ] ;
if ( params . type > supported_types ) {
LOG_ERROR ( Service_NVDRV , " ZBCSetTable: invalid type {:#X} " , params . type ) ;
return NvResult : : BadParameter ;
}
std : : scoped_lock lk ( zbc_mutex ) ;
switch ( static_cast < ZBCTypes > ( params . type ) ) {
case ZBCTypes : : color : {
ZbcColorEntry color_entry { } ;
std : : copy_n ( std : : begin ( params . color_ds ) , color_entry . color_ds . size ( ) , color_entry . color_ds . begin ( ) ) ;
std : : copy_n ( std : : begin ( params . color_l2 ) , color_entry . color_l2 . size ( ) , color_entry . color_l2 . begin ( ) ) ;
color_entry . format = params . format ;
color_entry . ref_cnt = 1u ;
auto color_it = std : : ranges : : find_if ( zbc_colors ,
[ & ] ( const ZbcColorEntry & color_in_question ) {
return color_entry . format = = color_in_question . format & &
color_entry . color_ds = = color_in_question . color_ds & &
color_entry . color_l2 = = color_in_question . color_l2 ;
} ) ;
if ( color_it ! = zbc_colors . end ( ) ) {
+ + color_it - > ref_cnt ;
LOG_DEBUG ( Service_NVDRV , " ZBCSetTable: reused color entry fmt={:#X}, ref_cnt={:#X} " ,
params . format , color_it - > ref_cnt ) ;
} else {
zbc_colors . push_back ( color_entry ) ;
LOG_DEBUG ( Service_NVDRV , " ZBCSetTable: added color entry fmt={:#X}, index={:#X} " ,
params . format , zbc_colors . size ( ) - 1 ) ;
}
break ;
}
case ZBCTypes : : depth : {
ZbcDepthEntry depth_entry { params . depth , params . format , 1u } ;
auto depth_it = std : : ranges : : find_if ( zbc_depths ,
[ & ] ( const ZbcDepthEntry & depth_entry_in_question ) {
return depth_entry . format = = depth_entry_in_question . format & &
depth_entry . depth = = depth_entry_in_question . depth ;
} ) ;
if ( depth_it ! = zbc_depths . end ( ) ) {
+ + depth_it - > ref_cnt ;
LOG_DEBUG ( Service_NVDRV , " ZBCSetTable: reused depth entry fmt={:#X}, ref_cnt={:#X} " ,
depth_entry . format , depth_it - > ref_cnt ) ;
} else {
zbc_depths . push_back ( depth_entry ) ;
LOG_DEBUG ( Service_NVDRV , " ZBCSetTable: added depth entry fmt={:#X}, index={:#X} " ,
depth_entry . format , zbc_depths . size ( ) - 1 ) ;
}
}
ASSERT ( this - > max_color_entries < 16 ) ;
this - > color_entries [ this - > max_color_entries ] = entry ;
+ + this - > max_color_entries ;
} else if ( params . type = = 2 ) {
entry . depth = params . depth ;
ASSERT ( this - > max_depth_entries < 16 ) ;
this - > depth_entries [ this - > max_depth_entries ] = entry ;
+ + this - > max_depth_entries ;
}
return NvResult : : Success ;
}
NvResult nvhost_ctrl_gpu : : ZBCQueryTable ( IoctlZbcQueryTable & params ) {
LOG_DEBUG ( Service_NVDRV , " called " ) ;
struct ZbcQueryParams {
u32_le color_ds [ 4 ] ;
u32_le color_l2 [ 4 ] ;
u32_le depth ;
u32_le ref_cnt ;
u32_le format ;
u32_le type ;
u32_le index_size ;
} entry = { } ;
std : : memset ( & entry , 0 , sizeof ( entry ) ) ;
auto const index = params . index_size ;
if ( params . type = = 0 ) { //no
entry . index_size = 15 ;
} else if ( params . type = = 1 ) { //color
ASSERT ( index < 16 ) ;
for ( auto i = 0 ; i < 4 ; + + i ) {
params . color_ds [ i ] = this - > color_entries [ index ] . color_ds [ i ] ;
params . color_l2 [ i ] = this - > color_entries [ index ] . color_l2 [ i ] ;
if ( params . type > supported_types ) {
LOG_ERROR ( Service_NVDRV , " ZBCQueryTable: invalid type {:#X} " , params . type ) ;
return NvResult : : BadParameter ;
}
std : : scoped_lock lk ( zbc_mutex ) ;
switch ( static_cast < ZBCTypes > ( params . type ) ) {
case ZBCTypes : : color : {
if ( params . index_size > = zbc_colors . size ( ) ) {
LOG_ERROR ( Service_NVDRV , " ZBCQueryTable: invalid color index {:#X} " , params . index_size ) ;
return NvResult : : BadParameter ;
}
const auto & colors = zbc_colors [ params . index_size ] ;
std : : copy_n ( colors . color_ds . begin ( ) , colors . color_ds . size ( ) , std : : begin ( params . color_ds ) ) ;
std : : copy_n ( colors . color_l2 . begin ( ) , colors . color_l2 . size ( ) , std : : begin ( params . color_l2 ) ) ;
params . depth = 0 ;
params . ref_cnt = colors . ref_cnt ;
params . format = colors . format ;
params . index_size = static_cast < u32 > ( zbc_colors . size ( ) ) ;
break ;
}
case ZBCTypes : : depth : {
if ( params . index_size > = zbc_depths . size ( ) ) {
LOG_ERROR ( Service_NVDRV , " ZBCQueryTable: invalid depth index {:#X} " , params . index_size ) ;
return NvResult : : BadParameter ;
}
const auto & depth_entry = zbc_depths [ params . index_size ] ;
std : : fill ( std : : begin ( params . color_ds ) , std : : end ( params . color_ds ) , 0 ) ;
std : : fill ( std : : begin ( params . color_l2 ) , std : : end ( params . color_l2 ) , 0 ) ;
params . depth = depth_entry . depth ;
params . ref_cnt = depth_entry . ref_cnt ;
params . format = depth_entry . format ;
params . index_size = static_cast < u32 > ( zbc_depths . size ( ) ) ;
}
// TODO: Only if no error thrown (otherwise dont modify)
params . format = this - > color_entries [ index ] . format ;
//params.ref_cnt = this->color_entries[index].ref_cnt;
} else if ( params . type = = 2 ) { //depth
ASSERT ( index < 16 ) ;
params . depth = this - > depth_entries [ index ] . depth ;
// TODO: Only if no error thrown (otherwise dont modify)
params . format = this - > depth_entries [ index ] . format ;
//params.ref_cnt = this->depth_entries[index].ref_cnt;
} else {
UNREACHABLE ( ) ;
}
return NvResult : : Success ;
}