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::*;
// 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);
if res {
Ok(())
} else {
+ if Platform::get().debug.program {
+ for dev in &devs {
+ eprintln!("{}", p.log(dev));
+ }
+ }
Err(CL_BUILD_PROGRAM_FAILURE)
}
}
// 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);
if res {
Ok(())
} else {
+ if Platform::get().debug.program {
+ for dev in &devs {
+ eprintln!("{}", p.log(dev));
+ }
+ }
Err(CL_COMPILE_PROGRAM_FAILURE)
}
}
use mesa_rust_gen::*;
use rusticl_opencl_gen::*;
+use std::env;
use std::sync::Arc;
use std::sync::Once;
dispatch: &'static cl_icd_dispatch,
pub extensions: [cl_name_version; 2],
pub devs: Vec<Arc<Device>>,
+ pub debug: PlatformDebug,
+}
+
+pub struct PlatformDebug {
+ pub program: bool,
}
static PLATFORM_ONCE: Once = Once::new();
mk_cl_version_ext(1, 0, 0, "cl_khr_il_program"),
],
devs: Vec::new(),
+ debug: PlatformDebug { program: false },
};
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),
+ }
+ }
+ }
}
}
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::*;
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 {
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<String>).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,
let mut msgs: Vec<String> = Vec::new();
let logger = clc_logger {
priv_: &mut msgs as *mut Vec<String> 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();
let mut msgs: Vec<String> = Vec::new();
let logger = clc_logger {
priv_: &mut msgs as *mut Vec<String> 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();
library: bool,
clc_shader: *const nir_shader,
address_bits: u32,
+ log: Option<&mut Vec<String>>,
) -> spirv_to_nir_options {
let global_addr_format;
let offset_addr_format;
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<String>).cast(),
+ });
+
spirv_to_nir_options {
create_library: library,
environment: nir_spirv_execution_environment::NIR_SPIRV_OPENCL,
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()
}
}
libclc: &NirShader,
spec_constants: &mut [nir_spirv_specialization],
address_bits: u32,
+ log: Option<&mut Vec<String>>,
) -> Option<NirShader> {
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(
pub fn get_lib_clc(screen: &PipeScreen) -> Option<NirShader> {
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 {