From ca1e9917a9bbf8b9cffe3d9e7cf6c3f7d3c51e09 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Tue, 4 Apr 2023 02:41:45 +0200 Subject: [PATCH] rusticl/program: allow dumping compilation logs through RUSTICL_DEBUG Signed-off-by: Karol Herbst Part-of: --- docs/envvars.rst | 6 +++ src/gallium/frontends/rusticl/api/program.rs | 19 ++++++++-- .../frontends/rusticl/core/platform.rs | 15 ++++++++ src/gallium/frontends/rusticl/core/program.rs | 32 ++++++++++------ .../rusticl/mesa/compiler/clc/spirv.rs | 37 ++++++++++++++----- 5 files changed, 84 insertions(+), 25 deletions(-) diff --git a/docs/envvars.rst b/docs/envvars.rst index 78f2ec4ad31f4..b2c0ba7c2b456 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -893,6 +893,12 @@ Rusticl environment variables - ``RUSTICL_ENABLE=iris:1,radeonsi:0,2`` (enables second iris and first and third radeonsi device) +.. envvar:: RUSTICL_DEBUG + + a comma-separated list of debug channels to enable. + + - ``program`` dumps compilation logs to stderr + Nine frontend environment variables ----------------------------------- diff --git a/src/gallium/frontends/rusticl/api/program.rs b/src/gallium/frontends/rusticl/api/program.rs index daa2180b6c9a0..ce8c11c08b110 100644 --- a/src/gallium/frontends/rusticl/api/program.rs +++ b/src/gallium/frontends/rusticl/api/program.rs @@ -2,6 +2,7 @@ use crate::api::icd::*; use crate::api::types::*; use crate::api::util::*; use crate::core::device::*; +use crate::core::platform::*; use crate::core::program::*; use mesa_rust::compiler::clc::*; @@ -270,8 +271,8 @@ pub fn build_program( // CL_BUILD_PROGRAM_FAILURE if there is a failure to build the program executable. This error // will be returned if clBuildProgram does not return until the build has completed. - for dev in devs { - res &= p.build(&dev, c_string_to_string(options)); + for dev in &devs { + res &= p.build(dev, c_string_to_string(options)); } call_cb(pfn_notify, program, user_data); @@ -284,6 +285,11 @@ pub fn build_program( if res { Ok(()) } else { + if Platform::get().debug.program { + for dev in &devs { + eprintln!("{}", p.log(dev)); + } + } Err(CL_BUILD_PROGRAM_FAILURE) } } @@ -337,8 +343,8 @@ pub fn compile_program( // CL_COMPILE_PROGRAM_FAILURE if there is a failure to compile the program source. This error // will be returned if clCompileProgram does not return until the compile has completed. - for dev in devs { - res &= p.compile(&dev, c_string_to_string(options), &headers); + for dev in &devs { + res &= p.compile(dev, c_string_to_string(options), &headers); } call_cb(pfn_notify, program, user_data); @@ -349,6 +355,11 @@ pub fn compile_program( if res { Ok(()) } else { + if Platform::get().debug.program { + for dev in &devs { + eprintln!("{}", p.log(dev)); + } + } Err(CL_COMPILE_PROGRAM_FAILURE) } } diff --git a/src/gallium/frontends/rusticl/core/platform.rs b/src/gallium/frontends/rusticl/core/platform.rs index 661d39d44f165..41e77a1523906 100644 --- a/src/gallium/frontends/rusticl/core/platform.rs +++ b/src/gallium/frontends/rusticl/core/platform.rs @@ -6,6 +6,7 @@ use crate::core::version::*; use mesa_rust_gen::*; use rusticl_opencl_gen::*; +use std::env; use std::sync::Arc; use std::sync::Once; @@ -14,6 +15,11 @@ pub struct Platform { dispatch: &'static cl_icd_dispatch, pub extensions: [cl_name_version; 2], pub devs: Vec>, + pub debug: PlatformDebug, +} + +pub struct PlatformDebug { + pub program: bool, } static PLATFORM_ONCE: Once = Once::new(); @@ -24,6 +30,7 @@ static mut PLATFORM: Platform = Platform { mk_cl_version_ext(1, 0, 0, "cl_khr_il_program"), ], devs: Vec::new(), + debug: PlatformDebug { program: false }, }; impl Platform { @@ -44,6 +51,14 @@ impl Platform { } self.devs.extend(Device::all()); + if let Ok(debug_flags) = env::var("RUSTICL_DEBUG") { + for flag in debug_flags.split(',') { + match flag { + "program" => self.debug.program = true, + _ => eprintln!("Unknown RUSTICL_DEBUG flag found: {}", flag), + } + } + } } } diff --git a/src/gallium/frontends/rusticl/core/program.rs b/src/gallium/frontends/rusticl/core/program.rs index 60bb813faf572..926be651b1d1f 100644 --- a/src/gallium/frontends/rusticl/core/program.rs +++ b/src/gallium/frontends/rusticl/core/program.rs @@ -1,6 +1,7 @@ use crate::api::icd::*; use crate::core::context::*; use crate::core::device::*; +use crate::core::platform::Platform; use crate::impl_cl_type_trait; use mesa_rust::compiler::clc::*; @@ -595,18 +596,25 @@ impl Program { let info = Self::dev_build_info(&mut lock, d); assert_eq!(info.status, CL_BUILD_SUCCESS as cl_build_status); - info.spirv - .as_ref() - .unwrap() - .to_nir( - kernel, - d.screen - .nir_shader_compiler_options(pipe_shader_type::PIPE_SHADER_COMPUTE), - &d.lib_clc, - &mut spec_constants, - d.address_bits(), - ) - .unwrap() + + let mut log = Platform::get().debug.program.then(Vec::new); + let nir = info.spirv.as_ref().unwrap().to_nir( + kernel, + d.screen + .nir_shader_compiler_options(pipe_shader_type::PIPE_SHADER_COMPUTE), + &d.lib_clc, + &mut spec_constants, + d.address_bits(), + log.as_mut(), + ); + + if let Some(log) = log { + for line in log { + eprintln!("{}", line); + } + }; + + nir.unwrap() } pub fn is_binary(&self) -> bool { diff --git a/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs b/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs index b957b37870293..8626a3ae00b0e 100644 --- a/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs +++ b/src/gallium/frontends/rusticl/mesa/compiler/clc/spirv.rs @@ -37,11 +37,24 @@ pub struct CLCHeader<'a> { pub source: &'a CString, } -unsafe extern "C" fn msg_callback(data: *mut std::ffi::c_void, msg: *const c_char) { +unsafe fn callback_impl(data: *mut c_void, msg: *const c_char) { let msgs = (data as *mut Vec).as_mut().expect(""); msgs.push(c_string_to_string(msg)); } +unsafe extern "C" fn spirv_msg_callback(data: *mut c_void, msg: *const c_char) { + callback_impl(data, msg); +} + +unsafe extern "C" fn spirv_to_nir_msg_callback( + data: *mut c_void, + _dbg_level: mesa_rust_gen::nir_spirv_debug_level, + _offset: usize, + msg: *const c_char, +) { + callback_impl(data, msg); +} + impl SPIRVBin { pub fn from_clc( source: &CString, @@ -102,8 +115,8 @@ impl SPIRVBin { let mut msgs: Vec = Vec::new(); let logger = clc_logger { priv_: &mut msgs as *mut Vec as *mut c_void, - error: Some(msg_callback), - warning: Some(msg_callback), + error: Some(spirv_msg_callback), + warning: Some(spirv_msg_callback), }; let mut out = clc_binary::default(); @@ -143,8 +156,8 @@ impl SPIRVBin { let mut msgs: Vec = Vec::new(); let logger = clc_logger { priv_: &mut msgs as *mut Vec as *mut c_void, - error: Some(msg_callback), - warning: Some(msg_callback), + error: Some(spirv_msg_callback), + warning: Some(spirv_msg_callback), }; let mut out = clc_binary::default(); @@ -256,6 +269,7 @@ impl SPIRVBin { library: bool, clc_shader: *const nir_shader, address_bits: u32, + log: Option<&mut Vec>, ) -> spirv_to_nir_options { let global_addr_format; let offset_addr_format; @@ -268,6 +282,11 @@ impl SPIRVBin { offset_addr_format = nir_address_format::nir_address_format_32bit_offset_as_64bit; } + let debug = log.map(|log| spirv_to_nir_options__bindgen_ty_1 { + func: Some(spirv_to_nir_msg_callback), + private_data: (log as *mut Vec).cast(), + }); + spirv_to_nir_options { create_library: library, environment: nir_spirv_execution_environment::NIR_SPIRV_OPENCL, @@ -295,9 +314,8 @@ impl SPIRVBin { global_addr_format: global_addr_format, shared_addr_format: offset_addr_format, temp_addr_format: offset_addr_format, + debug: debug.unwrap_or_default(), - // default - debug: spirv_to_nir_options__bindgen_ty_1::default(), ..Default::default() } } @@ -309,9 +327,10 @@ impl SPIRVBin { libclc: &NirShader, spec_constants: &mut [nir_spirv_specialization], address_bits: u32, + log: Option<&mut Vec>, ) -> Option { let c_entry = CString::new(entry_point.as_bytes()).unwrap(); - let spirv_options = Self::get_spirv_options(false, libclc.get_nir(), address_bits); + let spirv_options = Self::get_spirv_options(false, libclc.get_nir(), address_bits, log); let nir = unsafe { spirv_to_nir( @@ -332,7 +351,7 @@ impl SPIRVBin { pub fn get_lib_clc(screen: &PipeScreen) -> Option { let nir_options = screen.nir_shader_compiler_options(pipe_shader_type::PIPE_SHADER_COMPUTE); let address_bits = screen.compute_param(pipe_compute_cap::PIPE_COMPUTE_CAP_ADDRESS_BITS); - let spirv_options = Self::get_spirv_options(true, ptr::null(), address_bits); + let spirv_options = Self::get_spirv_options(true, ptr::null(), address_bits, None); let shader_cache = DiskCacheBorrowed::as_ptr(&screen.shader_cache()); NirShader::new(unsafe {