@@ -250,6 +250,46 @@ impl super::Queue::ver {
250250 return Err ( EINVAL ) ;
251251 }
252252
253+ let mut unks: uapi:: drm_asahi_cmd_render_unknowns = Default :: default ( ) ;
254+
255+ let mut ext_ptr = cmdbuf. extensions ;
256+ while ext_ptr != 0 {
257+ let ext_type = u32:: from_ne_bytes (
258+ unsafe { UserSlicePtr :: new ( ext_ptr as usize as * mut _ , 4 ) }
259+ . read_all ( ) ?
260+ . try_into ( )
261+ . or ( Err ( EINVAL ) ) ?,
262+ ) ;
263+
264+ match ext_type {
265+ uapi:: ASAHI_RENDER_EXT_UNKNOWNS => {
266+ if !debug_enabled ( debug:: DebugFlags :: AllowUnknownOverrides ) {
267+ return Err ( EINVAL ) ;
268+ }
269+ let mut ext_reader = unsafe {
270+ UserSlicePtr :: new (
271+ ext_ptr as usize as * mut _ ,
272+ core:: mem:: size_of :: < uapi:: drm_asahi_cmd_render_unknowns > ( ) ,
273+ )
274+ . reader ( )
275+ } ;
276+ unsafe {
277+ ext_reader. read_raw (
278+ & mut unks as * mut _ as * mut u8 ,
279+ core:: mem:: size_of :: < uapi:: drm_asahi_cmd_render_unknowns > ( ) ,
280+ ) ?;
281+ }
282+
283+ ext_ptr = unks. next ;
284+ }
285+ _ => return Err ( EINVAL ) ,
286+ }
287+ }
288+
289+ if unks. pad != 0 {
290+ return Err ( EINVAL ) ;
291+ }
292+
253293 let dev = self . dev . data ( ) ;
254294 let gpu = match dev. gpu . as_any ( ) . downcast_ref :: < gpu:: GpuManager :: ver > ( ) {
255295 Some ( gpu) => gpu,
@@ -272,7 +312,7 @@ impl super::Queue::ver {
272312 }
273313
274314 #[ ver( G != G14 ) ]
275- let tiling_control = {
315+ let mut tiling_control = {
276316 let render_cfg = gpu. get_cfg ( ) . render ;
277317 let mut tiling_control = render_cfg. tiling_control ;
278318
@@ -392,7 +432,7 @@ impl super::Queue::ver {
392432
393433 let timestamps = Arc :: try_new ( kalloc. shared . new_default :: < fw:: job:: RenderTimestamps > ( ) ?) ?;
394434
395- let unk1 = false ;
435+ let unk1 = unks . flags & uapi :: ASAHI_RENDER_UNK_UNK1 as u64 != 0 ;
396436
397437 let mut tile_config: u64 = 0 ;
398438 if !unk1 {
@@ -415,7 +455,7 @@ impl super::Queue::ver {
415455 } ;
416456
417457 #[ ver( G >= G14X ) ]
418- let frg_tilecfg = 0x0000000_00036011
458+ let mut frg_tilecfg = 0x0000000_00036011
419459 | ( ( ( tile_info. tiles_x - 1 ) as u64 ) << 44 )
420460 | ( ( ( tile_info. tiles_y - 1 ) as u64 ) << 53 )
421461 | ( if unk1 { 0 } else { 0x20_00000000 } )
@@ -452,6 +492,88 @@ impl super::Queue::ver {
452492 #[ ver( V >= V13_0B4 ) ]
453493 let count_vtx = count_frag + 1 ;
454494
495+ // Unknowns handling
496+
497+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_TILE_CONFIG as u64 != 0 {
498+ tile_config = unks. tile_config ;
499+ }
500+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_UTILE_CONFIG as u64 != 0 {
501+ utile_config = unks. utile_config as u32 ;
502+ }
503+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_AUX_FB_UNK as u64 == 0 {
504+ unks. aux_fb_unk = 0x100000 ;
505+ }
506+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_G14_UNK as u64 == 0 {
507+ unks. g14_unk = 0x4040404 ;
508+ }
509+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_140 as u64 == 0 {
510+ unks. frg_unk_140 = 0x8c60 ;
511+ }
512+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_158 as u64 == 0 {
513+ unks. frg_unk_158 = 0x1c ;
514+ }
515+ #[ ver( G >= G14X ) ]
516+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_TILECFG as u64 != 0 {
517+ frg_tilecfg = unks. frg_tilecfg ;
518+ }
519+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_LOAD_BGOBJVALS as u64 == 0 {
520+ unks. load_bgobjvals = cmdbuf. isp_bgobjvals . into ( ) ;
521+ #[ ver( G < G14X ) ]
522+ unks. load_bgobjvals |= 0x400 ;
523+ }
524+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_38 as u64 == 0 {
525+ unks. frg_unk_38 = 0 ;
526+ }
527+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_3C as u64 == 0 {
528+ unks. frg_unk_3c = 1 ;
529+ }
530+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_40 as u64 == 0 {
531+ unks. frg_unk_40 = 0 ;
532+ }
533+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_RELOAD_ZLSCTRL as u64 == 0 {
534+ unks. reload_zlsctrl = cmdbuf. zls_ctrl ;
535+ }
536+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_UNK_BUF_10 as u64 == 0 {
537+ #[ ver( G < G14X ) ]
538+ unks. unk_buf_10 = 1 ;
539+ #[ ver( G >= G14X ) ]
540+ unks. unk_buf_10 = 0 ;
541+ }
542+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_FRG_UNK_MASK as u64 == 0 {
543+ unks. frg_unk_mask = 0xffffffff ;
544+ }
545+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_IOGPU_UNK54 == 0 {
546+ unks. iogpu_unk54 = 0x3a0012006b0003 ;
547+ }
548+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_IOGPU_UNK56 == 0 {
549+ unks. iogpu_unk56 = 1 ;
550+ }
551+ #[ ver( G != G14 ) ]
552+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_TILING_CONTROL != 0 {
553+ tiling_control = unks. tiling_control as u32 ;
554+ }
555+ #[ ver( G != G14 ) ]
556+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_TILING_CONTROL_2 == 0 {
557+ #[ ver( G < G14X ) ]
558+ unks. tiling_control_2 = 0 ;
559+ #[ ver( G >= G14X ) ]
560+ unks. tiling_control_2 = 4 ;
561+ }
562+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_VTX_UNK_F0 == 0 {
563+ unks. vtx_unk_f0 = 0x1c ;
564+ #[ ver( G < G14X ) ]
565+ unks. vtx_unk_f0 += align ( tile_info. meta1_blocks , 4 ) as u64 ;
566+ }
567+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_VTX_UNK_F8 == 0 {
568+ unks. vtx_unk_f8 = 0x8c60 ;
569+ }
570+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_VTX_UNK_118 == 0 {
571+ unks. vtx_unk_118 = 0x1c ;
572+ }
573+ if unks. flags & uapi:: ASAHI_RENDER_UNK_SET_VTX_UNK_MASK == 0 {
574+ unks. vtx_unk_mask = 0xffffffff ;
575+ }
576+
455577 mod_dev_dbg ! ( self . dev, "[Submission {}] Create Frag\n " , id) ;
456578 let frag = GpuObject :: new_init_prealloc (
457579 kalloc. gpu_ro . alloc_object ( ) ?,
@@ -611,7 +733,7 @@ impl super::Queue::ver {
611733 width : cmdbuf. fb_width ,
612734 height : cmdbuf. fb_height ,
613735 #[ ver( V >= V13_0B4 ) ]
614- unk3 : U64 ( 0x100000 ) ,
736+ unk3 : U64 ( unks . aux_fb_unk ) ,
615737 } ;
616738
617739 try_init ! ( fw:: fragment:: raw:: RunFragment :: ver {
@@ -653,7 +775,7 @@ impl super::Queue::ver {
653775 visibility_result_buffer: U64 ( cmdbuf. visibility_result_buffer) ,
654776 zls_ctrl: U64 ( cmdbuf. zls_ctrl) ,
655777 #[ ver( G >= G14 ) ]
656- unk_58_g14_0: U64 ( 0x4040404 ) ,
778+ unk_58_g14_0: U64 ( unks . g14_unk ) ,
657779 #[ ver( G >= G14 ) ]
658780 unk_58_g14_8: U64 ( 0 ) ,
659781 depth_buffer_ptr1: U64 ( cmdbuf. depth_buffer_load) ,
@@ -679,10 +801,10 @@ impl super::Queue::ver {
679801 aux_fb: inner. aux_fb. gpu_pointer( ) ,
680802 unk_108: Default :: default ( ) ,
681803 pipeline_base: U64 ( 0x11_00000000 ) ,
682- unk_140: U64 ( 0x8c60 ) ,
804+ unk_140: U64 ( unks . frg_unk_140 ) ,
683805 unk_148: U64 ( 0x0 ) ,
684806 unk_150: U64 ( 0x0 ) ,
685- unk_158: U64 ( 0x1c ) ,
807+ unk_158: U64 ( unks . frg_unk_158 ) ,
686808 unk_160: U64 ( 0 ) ,
687809 __pad: Default :: default ( ) ,
688810 #[ ver( V < V13_0B4 ) ]
@@ -704,10 +826,10 @@ impl super::Queue::ver {
704826 tib_blocks: cmdbuf. tib_blocks,
705827 isp_bgobjdepth: cmdbuf. isp_bgobjdepth,
706828 // TODO: does this flag need to be exposed to userspace?
707- isp_bgobjvals: cmdbuf . isp_bgobjvals | 0x400 ,
708- unk_38: 0 ,
709- unk_3c: 1 ,
710- unk_40: 0 ,
829+ isp_bgobjvals: unks . load_bgobjvals as u32 ,
830+ unk_38: unks . frg_unk_38 as u32 ,
831+ unk_3c: unks . frg_unk_3c as u32 ,
832+ unk_40: unks . frg_unk_40 as u32 ,
711833 __pad: Default :: default ( ) ,
712834 } ) ,
713835 #[ ver( G >= G14X ) ]
@@ -744,14 +866,14 @@ impl super::Queue::ver {
744866 0x15211 ,
745867 ( ( cmdbuf. fb_height as u64 ) << 32 ) | cmdbuf. fb_width as u64 ,
746868 ) ; // aux_fb_info.{width, heigh
747- r. add( 0x15049 , aux_fb_info . unk3 ) ; // s2.aux_fb_info.unk3
869+ r. add( 0x15049 , unks . aux_fb_unk ) ; // s2.aux_fb_info.unk3
748870 r. add( 0x10051 , cmdbuf. tib_blocks. into( ) ) ; // s1.unk_2c
749871 r. add( 0x15321 , cmdbuf. depth_dimensions. into( ) ) ; // ISP_ZLS_PIXELS
750872 r. add( 0x15301 , cmdbuf. isp_bgobjdepth. into( ) ) ; // ISP_BGOBJDEPTH
751- r. add( 0x15309 , cmdbuf . isp_bgobjvals . into ( ) | 0x400 ) ; // ISP_BGOBJVALS
873+ r. add( 0x15309 , unks . load_bgobjvals ) ; // ISP_BGOBJVALS
752874 r. add( 0x15311 , cmdbuf. visibility_result_buffer) ; // ISP_OCLQRY_BASE
753875 r. add( 0x15319 , cmdbuf. zls_ctrl) ; // ISP_ZLSCTL
754- r. add( 0x15349 , 0x4040404 ) ; // s2.unk_58_g14_0
876+ r. add( 0x15349 , unks . g14_unk ) ; // s2.unk_58_g14_0
755877 r. add( 0x15351 , 0 ) ; // s2.unk_58_g14_8
756878 r. add( 0x15329 , cmdbuf. depth_buffer_load) ; // ISP_ZLOAD_BASE
757879 r. add( 0x15331 , cmdbuf. depth_buffer_store) ; // ISP_ZSTORE_BASE
@@ -786,7 +908,7 @@ impl super::Queue::ver {
786908 r. add( 0x16020 , 0 ) ;
787909 r. add( 0x16461 , inner. aux_fb. gpu_pointer( ) . into( ) ) ;
788910 r. add( 0x16090 , inner. aux_fb. gpu_pointer( ) . into( ) ) ;
789- r. add( 0x120a1 , 0x1c ) ;
911+ r. add( 0x120a1 , unks . frg_unk_158 ) ;
790912 r. add( 0x160a8 , 0 ) ;
791913 r. add( 0x16068 , frg_tilecfg) ;
792914 r. add( 0x160b8 , 0x0 ) ;
@@ -823,9 +945,9 @@ impl super::Queue::ver {
823945 pipeline_bind: U64 ( cmdbuf. partial_reload_pipeline_bind as u64 ) ,
824946 address: U64 ( cmdbuf. partial_reload_pipeline as u64 ) ,
825947 } ,
826- zls_ctrl: U64 ( cmdbuf . zls_ctrl ) ,
948+ zls_ctrl: U64 ( unks . reload_zlsctrl ) ,
827949 #[ ver( G >= G14X ) ]
828- unk_290: U64 ( 0x4040404 ) ,
950+ unk_290: U64 ( unks . g14_unk ) ,
829951 #[ ver( G < G14X ) ]
830952 unk_290: U64 ( 0x0 ) ,
831953 depth_buffer_ptr1: U64 ( cmdbuf. depth_buffer_load) ,
@@ -878,7 +1000,7 @@ impl super::Queue::ver {
8781000 unk_10: 0x0 , // fixed
8791001 encoder_id: cmdbuf. encoder_id,
8801002 unk_18: 0x0 , // fixed
881- unk_mask: 0xffffffff ,
1003+ unk_mask: unks . frg_unk_mask as u32 ,
8821004 sampler_array: U64 ( 0 ) ,
8831005 sampler_count: 0 ,
8841006 sampler_max: 0 ,
@@ -1149,9 +1271,8 @@ impl super::Queue::ver {
11491271 tvb_cluster_tilemaps: inner. scene. cluster_tilemaps_pointer( ) ,
11501272 tpc: inner. scene. tpc_pointer( ) ,
11511273 tvb_heapmeta: inner. scene. tvb_heapmeta_pointer( ) . or( 0x8000_0000_0000_0000 ) ,
1152- iogpu_unk_54: 0x6b0003 , // fixed
1153- iogpu_unk_55: 0x3a0012 , // fixed
1154- iogpu_unk_56: U64 ( 0x1 ) , // fixed
1274+ iogpu_unk_54: U64 ( unks. iogpu_unk54) , // fixed
1275+ iogpu_unk_56: U64 ( unks. iogpu_unk56) , // fixed
11551276 #[ ver( G < G14 ) ]
11561277 tvb_cluster_meta1: inner
11571278 . scene
@@ -1180,7 +1301,7 @@ impl super::Queue::ver {
11801301 #[ ver( G < G14 ) ]
11811302 tiling_control,
11821303 #[ ver( G < G14 ) ]
1183- unk_ac: 0 , // fixed
1304+ unk_ac: unks . tiling_control_2 as u32 , // fixed
11841305 unk_b0: Default :: default ( ) , // fixed
11851306 pipeline_base: U64 ( 0x11_00000000 ) ,
11861307 #[ ver( G < G14 ) ]
@@ -1189,10 +1310,10 @@ impl super::Queue::ver {
11891310 . meta_4_pointer( )
11901311 . map( |x| x. or( 0x3000_0000_0000_0000 ) ) ,
11911312 #[ ver( G < G14 ) ]
1192- unk_f0: U64 ( 0x1c + align ( tile_info . meta1_blocks , 4 ) as u64 ) ,
1193- unk_f8: U64 ( 0x8c60 ) , // fixed
1313+ unk_f0: U64 ( unks . vtx_unk_f0 ) ,
1314+ unk_f8: U64 ( unks . vtx_unk_f8 ) , // fixed
11941315 unk_100: Default :: default ( ) , // fixed
1195- unk_118: 0x1c , // fixed
1316+ unk_118: unks . vtx_unk_118 as u32 , // fixed
11961317 __pad: Default :: default ( ) ,
11971318 } ) ,
11981319 #[ ver( G < G14X ) ]
@@ -1220,8 +1341,8 @@ impl super::Queue::ver {
12201341 . into( ) ;
12211342 r. add( 0x1c031 , tvb_heapmeta_ptr) ;
12221343 r. add( 0x1c9c0 , tvb_heapmeta_ptr) ;
1223- r. add( 0x1c051 , 0x3a0012006b0003 ) ; // iogpu_unk_54/55
1224- r. add( 0x1c061 , 1 ) ; // iogpu_unk_56
1344+ r. add( 0x1c051 , unks . iogpu_unk54 ) ; // iogpu_unk_54/55
1345+ r. add( 0x1c061 , unks . iogpu_unk56 ) ; // iogpu_unk_56
12251346 r. add( 0x10149 , utile_config. into( ) ) ; // s2.unk_48 utile_config
12261347 r. add( 0x10139 , cmdbuf. ppp_multisamplectl) ; // PPP_MULTISAMPLECTL
12271348 r. add( 0x10111 , inner. scene. preempt_buf_1_pointer( ) . into( ) ) ;
@@ -1249,7 +1370,7 @@ impl super::Queue::ver {
12491370 inner. scene. meta_3_pointer( ) . map_or( 0 , |a| a. into( ) ) ,
12501371 ) ; // tvb_cluster_meta3
12511372 r. add( 0x1c890 , tiling_control. into( ) ) ; // tvb_tiling_control
1252- r. add( 0x1c918 , 4 ) ;
1373+ r. add( 0x1c918 , unks . tiling_control_2 ) ;
12531374 r. add( 0x1c079 , inner. scene. tvb_heapmeta_pointer( ) . into( ) ) ;
12541375 r. add( 0x1c9d8 , inner. scene. tvb_heapmeta_pointer( ) . into( ) ) ;
12551376 r. add( 0x1c089 , 0 ) ;
@@ -1258,7 +1379,7 @@ impl super::Queue::ver {
12581379 inner. scene. meta_4_pointer( ) . map_or( 0 , |a| a. into( ) ) ;
12591380 r. add( 0x16c41 , cl_meta_4_pointer) ; // tvb_cluster_meta4
12601381 r. add( 0x1ca40 , cl_meta_4_pointer) ; // tvb_cluster_meta4
1261- r. add( 0x1c9a8 , 0x1c ) ; // + meta1_blocks? min_free_tvb_pages?
1382+ r. add( 0x1c9a8 , unks . vtx_unk_f0 ) ; // + meta1_blocks? min_free_tvb_pages?
12621383 r. add(
12631384 0x1c920 ,
12641385 inner. scene. meta_1_pointer( ) . map_or( 0 , |a| a. into( ) ) ,
@@ -1289,7 +1410,7 @@ impl super::Queue::ver {
12891410 r. add( 0x1c0a9 , tile_info. params. tpc_stride. into( ) ) ; // TE_TPC
12901411 r. add( 0x10171 , tile_info. params. unk_24. into( ) ) ;
12911412 r. add( 0x10169 , tile_info. params. unk_28. into( ) ) ; // TA_RENDER_TARGET_MAX
1292- r. add( 0x12099 , 0x1c ) ;
1413+ r. add( 0x12099 , unks . vtx_unk_118 ) ;
12931414 r. add( 0x1c9e8 , 0 ) ;
12941415 /*
12951416 r.add(0x10209, 0x100); // Some kind of counter?? Does this matter?
@@ -1332,7 +1453,7 @@ impl super::Queue::ver {
13321453 unk_10: 0x0 , // fixed
13331454 encoder_id: cmdbuf. encoder_id,
13341455 unk_18: 0x0 , // fixed
1335- unk_mask: 0xffffffff ,
1456+ unk_mask: unks . vtx_unk_mask as u32 ,
13361457 sampler_array: U64 ( 0 ) ,
13371458 sampler_count: 0 ,
13381459 sampler_max: 0 ,
0 commit comments