Skip to content

Commit a44560d

Browse files
asahilinajannau
authored andcommitted
drm/asahi: render: Implement unknown value UAPI extension
1 parent 6dd659c commit a44560d

File tree

2 files changed

+150
-31
lines changed

2 files changed

+150
-31
lines changed

drivers/gpu/drm/asahi/debug.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub(crate) enum DebugFlags {
6565
Debug6 = 54,
6666
Debug7 = 55,
6767

68+
AllowUnknownOverrides = 62,
6869
OopsOnGpuCrash = 63,
6970
}
7071

drivers/gpu/drm/asahi/queue/render.rs

Lines changed: 149 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

@@ -395,7 +435,7 @@ impl super::Queue::ver {
395435
GFP_KERNEL,
396436
)?;
397437

398-
let unk1 = false;
438+
let unk1 = unks.flags & uapi::ASAHI_RENDER_UNK_UNK1 as u64 != 0;
399439

400440
let mut tile_config: u64 = 0;
401441
if !unk1 {
@@ -418,7 +458,7 @@ impl super::Queue::ver {
418458
};
419459

420460
#[ver(G >= G14X)]
421-
let frg_tilecfg = 0x0000000_00036011
461+
let mut frg_tilecfg = 0x0000000_00036011
422462
| (((tile_info.tiles_x - 1) as u64) << 44)
423463
| (((tile_info.tiles_y - 1) as u64) << 53)
424464
| (if unk1 { 0 } else { 0x20_00000000 })
@@ -455,6 +495,85 @@ impl super::Queue::ver {
455495
#[ver(V >= V13_0B4)]
456496
let count_vtx = count_frag + 1;
457497

498+
// Unknowns handling
499+
500+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_TILE_CONFIG as u64 != 0 {
501+
tile_config = unks.tile_config;
502+
}
503+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_UTILE_CONFIG as u64 != 0 {
504+
utile_config = unks.utile_config as u32;
505+
}
506+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_AUX_FB_UNK as u64 == 0 {
507+
unks.aux_fb_unk = 0x100000;
508+
}
509+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_G14_UNK as u64 == 0 {
510+
unks.g14_unk = 0x4040404;
511+
}
512+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_140 as u64 == 0 {
513+
unks.frg_unk_140 = 0x8c60;
514+
}
515+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_158 as u64 == 0 {
516+
unks.frg_unk_158 = 0x1c;
517+
}
518+
#[ver(G >= G14X)]
519+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_TILECFG as u64 != 0 {
520+
frg_tilecfg = unks.frg_tilecfg;
521+
}
522+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_LOAD_BGOBJVALS as u64 == 0 {
523+
unks.load_bgobjvals = cmdbuf.isp_bgobjvals.into();
524+
#[ver(G < G14X)]
525+
unks.load_bgobjvals |= 0x400;
526+
}
527+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_38 as u64 == 0 {
528+
unks.frg_unk_38 = 0;
529+
}
530+
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_3C as u64 == 0 {
531+
unks.frg_unk_3c = 1;
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+
458577
mod_dev_dbg!(self.dev, "[Submission {}] Create Frag\n", id);
459578
let frag = GpuObject::new_init_prealloc(
460579
kalloc.gpu_ro.alloc_object()?,
@@ -614,7 +733,7 @@ impl super::Queue::ver {
614733
width: cmdbuf.fb_width,
615734
height: cmdbuf.fb_height,
616735
#[ver(V >= V13_0B4)]
617-
unk3: U64(0x100000),
736+
unk3: U64(unks.aux_fb_unk),
618737
};
619738

620739
try_init!(fw::fragment::raw::RunFragment::ver {
@@ -656,7 +775,7 @@ impl super::Queue::ver {
656775
visibility_result_buffer: U64(cmdbuf.visibility_result_buffer),
657776
zls_ctrl: U64(cmdbuf.zls_ctrl),
658777
#[ver(G >= G14)]
659-
unk_58_g14_0: U64(0x4040404),
778+
unk_58_g14_0: U64(unks.g14_unk),
660779
#[ver(G >= G14)]
661780
unk_58_g14_8: U64(0),
662781
depth_buffer_ptr1: U64(cmdbuf.depth_buffer_load),
@@ -682,10 +801,10 @@ impl super::Queue::ver {
682801
aux_fb: inner.aux_fb.gpu_pointer(),
683802
unk_108: Default::default(),
684803
pipeline_base: U64(0x11_00000000),
685-
unk_140: U64(0x8c60),
804+
unk_140: U64(unks.frg_unk_140),
686805
unk_148: U64(0x0),
687806
unk_150: U64(0x0),
688-
unk_158: U64(0x1c),
807+
unk_158: U64(unks.frg_unk_158),
689808
unk_160: U64(0),
690809
__pad: Default::default(),
691810
#[ver(V < V13_0B4)]
@@ -707,10 +826,10 @@ impl super::Queue::ver {
707826
tib_blocks: cmdbuf.tib_blocks,
708827
isp_bgobjdepth: cmdbuf.isp_bgobjdepth,
709828
// TODO: does this flag need to be exposed to userspace?
710-
isp_bgobjvals: cmdbuf.isp_bgobjvals | 0x400,
711-
unk_38: 0,
712-
unk_3c: 1,
713-
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,
714833
__pad: Default::default(),
715834
}),
716835
#[ver(G >= G14X)]
@@ -747,14 +866,14 @@ impl super::Queue::ver {
747866
0x15211,
748867
((cmdbuf.fb_height as u64) << 32) | cmdbuf.fb_width as u64,
749868
); // aux_fb_info.{width, heigh
750-
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
751870
r.add(0x10051, cmdbuf.tib_blocks.into()); // s1.unk_2c
752871
r.add(0x15321, cmdbuf.depth_dimensions.into()); // ISP_ZLS_PIXELS
753872
r.add(0x15301, cmdbuf.isp_bgobjdepth.into()); // ISP_BGOBJDEPTH
754-
r.add(0x15309, cmdbuf.isp_bgobjvals.into() | 0x400); // ISP_BGOBJVALS
873+
r.add(0x15309, unks.load_bgobjvals); // ISP_BGOBJVALS
755874
r.add(0x15311, cmdbuf.visibility_result_buffer); // ISP_OCLQRY_BASE
756875
r.add(0x15319, cmdbuf.zls_ctrl); // ISP_ZLSCTL
757-
r.add(0x15349, 0x4040404); // s2.unk_58_g14_0
876+
r.add(0x15349, unks.g14_unk); // s2.unk_58_g14_0
758877
r.add(0x15351, 0); // s2.unk_58_g14_8
759878
r.add(0x15329, cmdbuf.depth_buffer_load); // ISP_ZLOAD_BASE
760879
r.add(0x15331, cmdbuf.depth_buffer_store); // ISP_ZSTORE_BASE
@@ -789,7 +908,7 @@ impl super::Queue::ver {
789908
r.add(0x16020, 0);
790909
r.add(0x16461, inner.aux_fb.gpu_pointer().into());
791910
r.add(0x16090, inner.aux_fb.gpu_pointer().into());
792-
r.add(0x120a1, 0x1c);
911+
r.add(0x120a1, unks.frg_unk_158);
793912
r.add(0x160a8, 0);
794913
r.add(0x16068, frg_tilecfg);
795914
r.add(0x160b8, 0x0);
@@ -826,9 +945,9 @@ impl super::Queue::ver {
826945
pipeline_bind: U64(cmdbuf.partial_reload_pipeline_bind as u64),
827946
address: U64(cmdbuf.partial_reload_pipeline as u64),
828947
},
829-
zls_ctrl: U64(cmdbuf.zls_ctrl),
948+
zls_ctrl: U64(unks.reload_zlsctrl),
830949
#[ver(G >= G14X)]
831-
unk_290: U64(0x4040404),
950+
unk_290: U64(unks.g14_unk),
832951
#[ver(G < G14X)]
833952
unk_290: U64(0x0),
834953
depth_buffer_ptr1: U64(cmdbuf.depth_buffer_load),
@@ -881,7 +1000,7 @@ impl super::Queue::ver {
8811000
unk_10: 0x0, // fixed
8821001
encoder_id: cmdbuf.encoder_id,
8831002
unk_18: 0x0, // fixed
884-
unk_mask: 0xffffffff,
1003+
unk_mask: unks.frg_unk_mask as u32,
8851004
sampler_array: U64(0),
8861005
sampler_count: 0,
8871006
sampler_max: 0,
@@ -1152,9 +1271,8 @@ impl super::Queue::ver {
11521271
tvb_cluster_tilemaps: inner.scene.cluster_tilemaps_pointer(),
11531272
tpc: inner.scene.tpc_pointer(),
11541273
tvb_heapmeta: inner.scene.tvb_heapmeta_pointer().or(0x8000_0000_0000_0000),
1155-
iogpu_unk_54: 0x6b0003, // fixed
1156-
iogpu_unk_55: 0x3a0012, // fixed
1157-
iogpu_unk_56: U64(0x1), // fixed
1274+
iogpu_unk_54: U64(unks.iogpu_unk54), // fixed
1275+
iogpu_unk_56: U64(unks.iogpu_unk56), // fixed
11581276
#[ver(G < G14)]
11591277
tvb_cluster_meta1: inner
11601278
.scene
@@ -1183,7 +1301,7 @@ impl super::Queue::ver {
11831301
#[ver(G < G14)]
11841302
tiling_control,
11851303
#[ver(G < G14)]
1186-
unk_ac: 0, // fixed
1304+
unk_ac: unks.tiling_control_2 as u32, // fixed
11871305
unk_b0: Default::default(), // fixed
11881306
pipeline_base: U64(0x11_00000000),
11891307
#[ver(G < G14)]
@@ -1192,10 +1310,10 @@ impl super::Queue::ver {
11921310
.meta_4_pointer()
11931311
.map(|x| x.or(0x3000_0000_0000_0000)),
11941312
#[ver(G < G14)]
1195-
unk_f0: U64(0x1c + align(tile_info.meta1_blocks, 4) as u64),
1196-
unk_f8: U64(0x8c60), // fixed
1313+
unk_f0: U64(unks.vtx_unk_f0),
1314+
unk_f8: U64(unks.vtx_unk_f8), // fixed
11971315
unk_100: Default::default(), // fixed
1198-
unk_118: 0x1c, // fixed
1316+
unk_118: unks.vtx_unk_118 as u32, // fixed
11991317
__pad: Default::default(),
12001318
}),
12011319
#[ver(G < G14X)]
@@ -1223,8 +1341,8 @@ impl super::Queue::ver {
12231341
.into();
12241342
r.add(0x1c031, tvb_heapmeta_ptr);
12251343
r.add(0x1c9c0, tvb_heapmeta_ptr);
1226-
r.add(0x1c051, 0x3a0012006b0003); // iogpu_unk_54/55
1227-
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
12281346
r.add(0x10149, utile_config.into()); // s2.unk_48 utile_config
12291347
r.add(0x10139, cmdbuf.ppp_multisamplectl); // PPP_MULTISAMPLECTL
12301348
r.add(0x10111, inner.scene.preempt_buf_1_pointer().into());
@@ -1252,7 +1370,7 @@ impl super::Queue::ver {
12521370
inner.scene.meta_3_pointer().map_or(0, |a| a.into()),
12531371
); // tvb_cluster_meta3
12541372
r.add(0x1c890, tiling_control.into()); // tvb_tiling_control
1255-
r.add(0x1c918, 4);
1373+
r.add(0x1c918, unks.tiling_control_2);
12561374
r.add(0x1c079, inner.scene.tvb_heapmeta_pointer().into());
12571375
r.add(0x1c9d8, inner.scene.tvb_heapmeta_pointer().into());
12581376
r.add(0x1c089, 0);
@@ -1261,7 +1379,7 @@ impl super::Queue::ver {
12611379
inner.scene.meta_4_pointer().map_or(0, |a| a.into());
12621380
r.add(0x16c41, cl_meta_4_pointer); // tvb_cluster_meta4
12631381
r.add(0x1ca40, cl_meta_4_pointer); // tvb_cluster_meta4
1264-
r.add(0x1c9a8, 0x1c); // + meta1_blocks? min_free_tvb_pages?
1382+
r.add(0x1c9a8, unks.vtx_unk_f0); // + meta1_blocks? min_free_tvb_pages?
12651383
r.add(
12661384
0x1c920,
12671385
inner.scene.meta_1_pointer().map_or(0, |a| a.into()),
@@ -1292,7 +1410,7 @@ impl super::Queue::ver {
12921410
r.add(0x1c0a9, tile_info.params.tpc_stride.into()); // TE_TPC
12931411
r.add(0x10171, tile_info.params.unk_24.into());
12941412
r.add(0x10169, tile_info.params.unk_28.into()); // TA_RENDER_TARGET_MAX
1295-
r.add(0x12099, 0x1c);
1413+
r.add(0x12099, unks.vtx_unk_118);
12961414
r.add(0x1c9e8, 0);
12971415
/*
12981416
r.add(0x10209, 0x100); // Some kind of counter?? Does this matter?
@@ -1335,7 +1453,7 @@ impl super::Queue::ver {
13351453
unk_10: 0x0, // fixed
13361454
encoder_id: cmdbuf.encoder_id,
13371455
unk_18: 0x0, // fixed
1338-
unk_mask: 0xffffffff,
1456+
unk_mask: unks.vtx_unk_mask as u32,
13391457
sampler_array: U64(0),
13401458
sampler_count: 0,
13411459
sampler_max: 0,

0 commit comments

Comments
 (0)