Skip to content

Commit

Permalink
drm/asahi: render: Implement unknown value UAPI extension
Browse files Browse the repository at this point in the history
  • Loading branch information
asahilina authored and jannau committed Dec 21, 2024
1 parent 6dd659c commit a44560d
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 31 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/asahi/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub(crate) enum DebugFlags {
Debug6 = 54,
Debug7 = 55,

AllowUnknownOverrides = 62,
OopsOnGpuCrash = 63,
}

Expand Down
180 changes: 149 additions & 31 deletions drivers/gpu/drm/asahi/queue/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,46 @@ impl super::Queue::ver {
return Err(EINVAL);
}

let mut unks: uapi::drm_asahi_cmd_render_unknowns = Default::default();

let mut ext_ptr = cmdbuf.extensions;
while ext_ptr != 0 {
let ext_type = u32::from_ne_bytes(
unsafe { UserSlicePtr::new(ext_ptr as usize as *mut _, 4) }
.read_all()?
.try_into()
.or(Err(EINVAL))?,
);

match ext_type {
uapi::ASAHI_RENDER_EXT_UNKNOWNS => {
if !debug_enabled(debug::DebugFlags::AllowUnknownOverrides) {
return Err(EINVAL);
}
let mut ext_reader = unsafe {
UserSlicePtr::new(
ext_ptr as usize as *mut _,
core::mem::size_of::<uapi::drm_asahi_cmd_render_unknowns>(),
)
.reader()
};
unsafe {
ext_reader.read_raw(
&mut unks as *mut _ as *mut u8,
core::mem::size_of::<uapi::drm_asahi_cmd_render_unknowns>(),
)?;
}

ext_ptr = unks.next;
}
_ => return Err(EINVAL),
}
}

if unks.pad != 0 {
return Err(EINVAL);
}

let dev = self.dev.data();
let gpu = match dev.gpu.as_any().downcast_ref::<gpu::GpuManager::ver>() {
Some(gpu) => gpu,
Expand All @@ -272,7 +312,7 @@ impl super::Queue::ver {
}

#[ver(G != G14)]
let tiling_control = {
let mut tiling_control = {
let render_cfg = gpu.get_cfg().render;
let mut tiling_control = render_cfg.tiling_control;

Expand Down Expand Up @@ -395,7 +435,7 @@ impl super::Queue::ver {
GFP_KERNEL,
)?;

let unk1 = false;
let unk1 = unks.flags & uapi::ASAHI_RENDER_UNK_UNK1 as u64 != 0;

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

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

// Unknowns handling

if unks.flags & uapi::ASAHI_RENDER_UNK_SET_TILE_CONFIG as u64 != 0 {
tile_config = unks.tile_config;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_UTILE_CONFIG as u64 != 0 {
utile_config = unks.utile_config as u32;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_AUX_FB_UNK as u64 == 0 {
unks.aux_fb_unk = 0x100000;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_G14_UNK as u64 == 0 {
unks.g14_unk = 0x4040404;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_140 as u64 == 0 {
unks.frg_unk_140 = 0x8c60;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_158 as u64 == 0 {
unks.frg_unk_158 = 0x1c;
}
#[ver(G >= G14X)]
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_TILECFG as u64 != 0 {
frg_tilecfg = unks.frg_tilecfg;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_LOAD_BGOBJVALS as u64 == 0 {
unks.load_bgobjvals = cmdbuf.isp_bgobjvals.into();
#[ver(G < G14X)]
unks.load_bgobjvals |= 0x400;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_38 as u64 == 0 {
unks.frg_unk_38 = 0;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_3C as u64 == 0 {
unks.frg_unk_3c = 1;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_RELOAD_ZLSCTRL as u64 == 0 {
unks.reload_zlsctrl = cmdbuf.zls_ctrl;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_UNK_BUF_10 as u64 == 0 {
#[ver(G < G14X)]
unks.unk_buf_10 = 1;
#[ver(G >= G14X)]
unks.unk_buf_10 = 0;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_FRG_UNK_MASK as u64 == 0 {
unks.frg_unk_mask = 0xffffffff;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_IOGPU_UNK54 == 0 {
unks.iogpu_unk54 = 0x3a0012006b0003;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_IOGPU_UNK56 == 0 {
unks.iogpu_unk56 = 1;
}
#[ver(G != G14)]
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_TILING_CONTROL != 0 {
tiling_control = unks.tiling_control as u32;
}
#[ver(G != G14)]
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_TILING_CONTROL_2 == 0 {
#[ver(G < G14X)]
unks.tiling_control_2 = 0;
#[ver(G >= G14X)]
unks.tiling_control_2 = 4;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_VTX_UNK_F0 == 0 {
unks.vtx_unk_f0 = 0x1c;
#[ver(G < G14X)]
unks.vtx_unk_f0 += align(tile_info.meta1_blocks, 4) as u64;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_VTX_UNK_F8 == 0 {
unks.vtx_unk_f8 = 0x8c60;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_VTX_UNK_118 == 0 {
unks.vtx_unk_118 = 0x1c;
}
if unks.flags & uapi::ASAHI_RENDER_UNK_SET_VTX_UNK_MASK == 0 {
unks.vtx_unk_mask = 0xffffffff;
}

mod_dev_dbg!(self.dev, "[Submission {}] Create Frag\n", id);
let frag = GpuObject::new_init_prealloc(
kalloc.gpu_ro.alloc_object()?,
Expand Down Expand Up @@ -614,7 +733,7 @@ impl super::Queue::ver {
width: cmdbuf.fb_width,
height: cmdbuf.fb_height,
#[ver(V >= V13_0B4)]
unk3: U64(0x100000),
unk3: U64(unks.aux_fb_unk),
};

try_init!(fw::fragment::raw::RunFragment::ver {
Expand Down Expand Up @@ -656,7 +775,7 @@ impl super::Queue::ver {
visibility_result_buffer: U64(cmdbuf.visibility_result_buffer),
zls_ctrl: U64(cmdbuf.zls_ctrl),
#[ver(G >= G14)]
unk_58_g14_0: U64(0x4040404),
unk_58_g14_0: U64(unks.g14_unk),
#[ver(G >= G14)]
unk_58_g14_8: U64(0),
depth_buffer_ptr1: U64(cmdbuf.depth_buffer_load),
Expand All @@ -682,10 +801,10 @@ impl super::Queue::ver {
aux_fb: inner.aux_fb.gpu_pointer(),
unk_108: Default::default(),
pipeline_base: U64(0x11_00000000),
unk_140: U64(0x8c60),
unk_140: U64(unks.frg_unk_140),
unk_148: U64(0x0),
unk_150: U64(0x0),
unk_158: U64(0x1c),
unk_158: U64(unks.frg_unk_158),
unk_160: U64(0),
__pad: Default::default(),
#[ver(V < V13_0B4)]
Expand All @@ -707,10 +826,10 @@ impl super::Queue::ver {
tib_blocks: cmdbuf.tib_blocks,
isp_bgobjdepth: cmdbuf.isp_bgobjdepth,
// TODO: does this flag need to be exposed to userspace?
isp_bgobjvals: cmdbuf.isp_bgobjvals | 0x400,
unk_38: 0,
unk_3c: 1,
unk_40: 0,
isp_bgobjvals: unks.load_bgobjvals as u32,
unk_38: unks.frg_unk_38 as u32,
unk_3c: unks.frg_unk_3c as u32,
unk_40: unks.frg_unk_40 as u32,
__pad: Default::default(),
}),
#[ver(G >= G14X)]
Expand Down Expand Up @@ -747,14 +866,14 @@ impl super::Queue::ver {
0x15211,
((cmdbuf.fb_height as u64) << 32) | cmdbuf.fb_width as u64,
); // aux_fb_info.{width, heigh
r.add(0x15049, aux_fb_info.unk3); // s2.aux_fb_info.unk3
r.add(0x15049, unks.aux_fb_unk); // s2.aux_fb_info.unk3
r.add(0x10051, cmdbuf.tib_blocks.into()); // s1.unk_2c
r.add(0x15321, cmdbuf.depth_dimensions.into()); // ISP_ZLS_PIXELS
r.add(0x15301, cmdbuf.isp_bgobjdepth.into()); // ISP_BGOBJDEPTH
r.add(0x15309, cmdbuf.isp_bgobjvals.into() | 0x400); // ISP_BGOBJVALS
r.add(0x15309, unks.load_bgobjvals); // ISP_BGOBJVALS
r.add(0x15311, cmdbuf.visibility_result_buffer); // ISP_OCLQRY_BASE
r.add(0x15319, cmdbuf.zls_ctrl); // ISP_ZLSCTL
r.add(0x15349, 0x4040404); // s2.unk_58_g14_0
r.add(0x15349, unks.g14_unk); // s2.unk_58_g14_0
r.add(0x15351, 0); // s2.unk_58_g14_8
r.add(0x15329, cmdbuf.depth_buffer_load); // ISP_ZLOAD_BASE
r.add(0x15331, cmdbuf.depth_buffer_store); // ISP_ZSTORE_BASE
Expand Down Expand Up @@ -789,7 +908,7 @@ impl super::Queue::ver {
r.add(0x16020, 0);
r.add(0x16461, inner.aux_fb.gpu_pointer().into());
r.add(0x16090, inner.aux_fb.gpu_pointer().into());
r.add(0x120a1, 0x1c);
r.add(0x120a1, unks.frg_unk_158);
r.add(0x160a8, 0);
r.add(0x16068, frg_tilecfg);
r.add(0x160b8, 0x0);
Expand Down Expand Up @@ -826,9 +945,9 @@ impl super::Queue::ver {
pipeline_bind: U64(cmdbuf.partial_reload_pipeline_bind as u64),
address: U64(cmdbuf.partial_reload_pipeline as u64),
},
zls_ctrl: U64(cmdbuf.zls_ctrl),
zls_ctrl: U64(unks.reload_zlsctrl),
#[ver(G >= G14X)]
unk_290: U64(0x4040404),
unk_290: U64(unks.g14_unk),
#[ver(G < G14X)]
unk_290: U64(0x0),
depth_buffer_ptr1: U64(cmdbuf.depth_buffer_load),
Expand Down Expand Up @@ -881,7 +1000,7 @@ impl super::Queue::ver {
unk_10: 0x0, // fixed
encoder_id: cmdbuf.encoder_id,
unk_18: 0x0, // fixed
unk_mask: 0xffffffff,
unk_mask: unks.frg_unk_mask as u32,
sampler_array: U64(0),
sampler_count: 0,
sampler_max: 0,
Expand Down Expand Up @@ -1152,9 +1271,8 @@ impl super::Queue::ver {
tvb_cluster_tilemaps: inner.scene.cluster_tilemaps_pointer(),
tpc: inner.scene.tpc_pointer(),
tvb_heapmeta: inner.scene.tvb_heapmeta_pointer().or(0x8000_0000_0000_0000),
iogpu_unk_54: 0x6b0003, // fixed
iogpu_unk_55: 0x3a0012, // fixed
iogpu_unk_56: U64(0x1), // fixed
iogpu_unk_54: U64(unks.iogpu_unk54), // fixed
iogpu_unk_56: U64(unks.iogpu_unk56), // fixed
#[ver(G < G14)]
tvb_cluster_meta1: inner
.scene
Expand Down Expand Up @@ -1183,7 +1301,7 @@ impl super::Queue::ver {
#[ver(G < G14)]
tiling_control,
#[ver(G < G14)]
unk_ac: 0, // fixed
unk_ac: unks.tiling_control_2 as u32, // fixed
unk_b0: Default::default(), // fixed
pipeline_base: U64(0x11_00000000),
#[ver(G < G14)]
Expand All @@ -1192,10 +1310,10 @@ impl super::Queue::ver {
.meta_4_pointer()
.map(|x| x.or(0x3000_0000_0000_0000)),
#[ver(G < G14)]
unk_f0: U64(0x1c + align(tile_info.meta1_blocks, 4) as u64),
unk_f8: U64(0x8c60), // fixed
unk_f0: U64(unks.vtx_unk_f0),
unk_f8: U64(unks.vtx_unk_f8), // fixed
unk_100: Default::default(), // fixed
unk_118: 0x1c, // fixed
unk_118: unks.vtx_unk_118 as u32, // fixed
__pad: Default::default(),
}),
#[ver(G < G14X)]
Expand Down Expand Up @@ -1223,8 +1341,8 @@ impl super::Queue::ver {
.into();
r.add(0x1c031, tvb_heapmeta_ptr);
r.add(0x1c9c0, tvb_heapmeta_ptr);
r.add(0x1c051, 0x3a0012006b0003); // iogpu_unk_54/55
r.add(0x1c061, 1); // iogpu_unk_56
r.add(0x1c051, unks.iogpu_unk54); // iogpu_unk_54/55
r.add(0x1c061, unks.iogpu_unk56); // iogpu_unk_56
r.add(0x10149, utile_config.into()); // s2.unk_48 utile_config
r.add(0x10139, cmdbuf.ppp_multisamplectl); // PPP_MULTISAMPLECTL
r.add(0x10111, inner.scene.preempt_buf_1_pointer().into());
Expand Down Expand Up @@ -1252,7 +1370,7 @@ impl super::Queue::ver {
inner.scene.meta_3_pointer().map_or(0, |a| a.into()),
); // tvb_cluster_meta3
r.add(0x1c890, tiling_control.into()); // tvb_tiling_control
r.add(0x1c918, 4);
r.add(0x1c918, unks.tiling_control_2);
r.add(0x1c079, inner.scene.tvb_heapmeta_pointer().into());
r.add(0x1c9d8, inner.scene.tvb_heapmeta_pointer().into());
r.add(0x1c089, 0);
Expand All @@ -1261,7 +1379,7 @@ impl super::Queue::ver {
inner.scene.meta_4_pointer().map_or(0, |a| a.into());
r.add(0x16c41, cl_meta_4_pointer); // tvb_cluster_meta4
r.add(0x1ca40, cl_meta_4_pointer); // tvb_cluster_meta4
r.add(0x1c9a8, 0x1c); // + meta1_blocks? min_free_tvb_pages?
r.add(0x1c9a8, unks.vtx_unk_f0); // + meta1_blocks? min_free_tvb_pages?
r.add(
0x1c920,
inner.scene.meta_1_pointer().map_or(0, |a| a.into()),
Expand Down Expand Up @@ -1292,7 +1410,7 @@ impl super::Queue::ver {
r.add(0x1c0a9, tile_info.params.tpc_stride.into()); // TE_TPC
r.add(0x10171, tile_info.params.unk_24.into());
r.add(0x10169, tile_info.params.unk_28.into()); // TA_RENDER_TARGET_MAX
r.add(0x12099, 0x1c);
r.add(0x12099, unks.vtx_unk_118);
r.add(0x1c9e8, 0);
/*
r.add(0x10209, 0x100); // Some kind of counter?? Does this matter?
Expand Down Expand Up @@ -1335,7 +1453,7 @@ impl super::Queue::ver {
unk_10: 0x0, // fixed
encoder_id: cmdbuf.encoder_id,
unk_18: 0x0, // fixed
unk_mask: 0xffffffff,
unk_mask: unks.vtx_unk_mask as u32,
sampler_array: U64(0),
sampler_count: 0,
sampler_max: 0,
Expand Down

0 comments on commit a44560d

Please sign in to comment.