mirror of https://gitlab.freedesktop.org/mesa/mesa
rusticl/program: make IL programs look closer to CLC ones
We want to validate the actual passed in SPIR-V, but we can only report errors back on build/compile time. So instead of storing the initial IL in the devices `ProgramBuild` objects, just store it on the Program instead. This also simplifies setting spec constants as this is only valid on program directly created from IL and not e.g. linked ones. Signed-off-by: Karol Herbst <kherbst@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22280>
This commit is contained in:
parent
ca1e9917a9
commit
ab032f4bfd
|
@ -5,6 +5,7 @@ use crate::core::device::*;
|
|||
use crate::core::platform::*;
|
||||
use crate::core::program::*;
|
||||
|
||||
use mesa_rust::compiler::clc::spirv::SPIRVBin;
|
||||
use mesa_rust::compiler::clc::*;
|
||||
use mesa_rust_util::string::*;
|
||||
use rusticl_opencl_gen::*;
|
||||
|
@ -41,7 +42,12 @@ impl CLInfo<cl_program_info> for cl_program {
|
|||
.collect(),
|
||||
)
|
||||
}
|
||||
CL_PROGRAM_IL => prog.il.clone(),
|
||||
CL_PROGRAM_IL => prog
|
||||
.il
|
||||
.as_ref()
|
||||
.map(SPIRVBin::to_bin)
|
||||
.unwrap_or_default()
|
||||
.to_vec(),
|
||||
CL_PROGRAM_KERNEL_NAMES => cl_prop::<String>(prog.kernels().join(";")),
|
||||
CL_PROGRAM_NUM_DEVICES => cl_prop::<cl_uint>(prog.devs.len() as cl_uint),
|
||||
CL_PROGRAM_NUM_KERNELS => cl_prop::<usize>(prog.kernels().len()),
|
||||
|
@ -436,7 +442,7 @@ pub fn set_program_specialization_constant(
|
|||
// CL_INVALID_PROGRAM if program is not a valid program object created from an intermediate
|
||||
// language (e.g. SPIR-V)
|
||||
// TODO: or if the intermediate language does not support specialization constants.
|
||||
if program.il.is_empty() {
|
||||
if program.il.is_none() {
|
||||
return Err(CL_INVALID_PROGRAM);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::core::device::*;
|
|||
use crate::core::platform::Platform;
|
||||
use crate::impl_cl_type_trait;
|
||||
|
||||
use mesa_rust::compiler::clc::spirv::SPIRVBin;
|
||||
use mesa_rust::compiler::clc::*;
|
||||
use mesa_rust::compiler::nir::*;
|
||||
use mesa_rust::util::disk_cache::*;
|
||||
|
@ -52,7 +53,7 @@ pub struct Program {
|
|||
pub context: Arc<Context>,
|
||||
pub devs: Vec<Arc<Device>>,
|
||||
pub src: CString,
|
||||
pub il: Vec<u8>,
|
||||
pub il: Option<spirv::SPIRVBin>,
|
||||
pub kernel_count: AtomicU32,
|
||||
spec_constants: Mutex<HashMap<u32, nir_const_value>>,
|
||||
build: Mutex<ProgramBuild>,
|
||||
|
@ -121,9 +122,8 @@ fn prepare_options(options: &str, dev: &Device) -> Vec<CString> {
|
|||
}
|
||||
|
||||
impl Program {
|
||||
pub fn new(context: &Arc<Context>, devs: &[Arc<Device>], src: CString) -> Arc<Program> {
|
||||
let builds = devs
|
||||
.iter()
|
||||
fn create_default_builds(devs: &[Arc<Device>]) -> HashMap<Arc<Device>, ProgramDevBuild> {
|
||||
devs.iter()
|
||||
.map(|d| {
|
||||
(
|
||||
d.clone(),
|
||||
|
@ -136,18 +136,20 @@ impl Program {
|
|||
},
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn new(context: &Arc<Context>, devs: &[Arc<Device>], src: CString) -> Arc<Program> {
|
||||
Arc::new(Self {
|
||||
base: CLObjectBase::new(),
|
||||
context: context.clone(),
|
||||
devs: devs.to_vec(),
|
||||
src: src,
|
||||
il: Vec::new(),
|
||||
il: None,
|
||||
kernel_count: AtomicU32::new(0),
|
||||
spec_constants: Mutex::new(HashMap::new()),
|
||||
build: Mutex::new(ProgramBuild {
|
||||
builds: builds,
|
||||
builds: Self::create_default_builds(devs),
|
||||
kernels: Vec::new(),
|
||||
}),
|
||||
})
|
||||
|
@ -216,7 +218,7 @@ impl Program {
|
|||
context: context,
|
||||
devs: devs,
|
||||
src: CString::new("").unwrap(),
|
||||
il: Vec::new(),
|
||||
il: None,
|
||||
kernel_count: AtomicU32::new(0),
|
||||
spec_constants: Mutex::new(HashMap::new()),
|
||||
build: Mutex::new(ProgramBuild {
|
||||
|
@ -227,29 +229,13 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn from_spirv(context: Arc<Context>, spirv: &[u8]) -> Arc<Program> {
|
||||
let mut builds = HashMap::new();
|
||||
|
||||
for d in &context.devs {
|
||||
let spirv = Some(spirv::SPIRVBin::from_bin(spirv));
|
||||
|
||||
builds.insert(
|
||||
d.clone(),
|
||||
ProgramDevBuild {
|
||||
spirv: spirv,
|
||||
status: CL_BUILD_SUCCESS as cl_build_status,
|
||||
log: String::from(""),
|
||||
options: String::from(""),
|
||||
bin_type: CL_PROGRAM_BINARY_TYPE_INTERMEDIATE,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let builds = Self::create_default_builds(&context.devs);
|
||||
Arc::new(Self {
|
||||
base: CLObjectBase::new(),
|
||||
devs: context.devs.clone(),
|
||||
context: context,
|
||||
src: CString::new("").unwrap(),
|
||||
il: spirv.to_vec(),
|
||||
il: Some(SPIRVBin::from_bin(spirv)),
|
||||
kernel_count: AtomicU32::new(0),
|
||||
spec_constants: Mutex::new(HashMap::new()),
|
||||
build: Mutex::new(ProgramBuild {
|
||||
|
@ -366,9 +352,7 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn build(&self, dev: &Arc<Device>, options: String) -> bool {
|
||||
// program binary
|
||||
let is_il = !self.il.is_empty();
|
||||
if self.src.as_bytes().is_empty() && !is_il {
|
||||
if self.is_binary() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -377,24 +361,25 @@ impl Program {
|
|||
let lib = options.contains("-create-library");
|
||||
let args = prepare_options(&options, dev);
|
||||
|
||||
if !is_il {
|
||||
let (spirv, log) = spirv::SPIRVBin::from_clc(
|
||||
let (spirv, log) = if self.il.is_some() {
|
||||
(self.il.clone(), String::new())
|
||||
} else {
|
||||
spirv::SPIRVBin::from_clc(
|
||||
&self.src,
|
||||
&args,
|
||||
&Vec::new(),
|
||||
get_disk_cache(),
|
||||
dev.cl_features(),
|
||||
dev.address_bits(),
|
||||
);
|
||||
)
|
||||
};
|
||||
|
||||
d.log = log;
|
||||
if spirv.is_none() {
|
||||
d.status = CL_BUILD_ERROR;
|
||||
return false;
|
||||
}
|
||||
d.spirv = spirv;
|
||||
d.log = log;
|
||||
if spirv.is_none() {
|
||||
d.status = CL_BUILD_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
d.spirv = spirv;
|
||||
d.options = options;
|
||||
|
||||
let spirvs = [d.spirv.as_ref().unwrap()];
|
||||
|
@ -424,30 +409,27 @@ impl Program {
|
|||
options: String,
|
||||
headers: &[spirv::CLCHeader],
|
||||
) -> bool {
|
||||
// program binary
|
||||
let is_il = !self.il.is_empty();
|
||||
if self.src.as_bytes().is_empty() && !is_il {
|
||||
if self.is_binary() {
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut info = self.build_info();
|
||||
let d = Self::dev_build_info(&mut info, dev);
|
||||
|
||||
if is_il {
|
||||
d.bin_type = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
|
||||
return true;
|
||||
}
|
||||
let (spirv, log) = if self.il.is_some() {
|
||||
(self.il.clone(), String::new())
|
||||
} else {
|
||||
let args = prepare_options(&options, dev);
|
||||
|
||||
let args = prepare_options(&options, dev);
|
||||
|
||||
let (spirv, log) = spirv::SPIRVBin::from_clc(
|
||||
&self.src,
|
||||
&args,
|
||||
headers,
|
||||
get_disk_cache(),
|
||||
dev.cl_features(),
|
||||
dev.address_bits(),
|
||||
);
|
||||
spirv::SPIRVBin::from_clc(
|
||||
&self.src,
|
||||
&args,
|
||||
headers,
|
||||
get_disk_cache(),
|
||||
dev.cl_features(),
|
||||
dev.address_bits(),
|
||||
)
|
||||
};
|
||||
|
||||
d.spirv = spirv;
|
||||
d.log = log;
|
||||
|
@ -517,7 +499,7 @@ impl Program {
|
|||
context: context,
|
||||
devs: devs,
|
||||
src: CString::new("").unwrap(),
|
||||
il: Vec::new(),
|
||||
il: None,
|
||||
kernel_count: AtomicU32::new(0),
|
||||
spec_constants: Mutex::new(HashMap::new()),
|
||||
build: Mutex::new(ProgramBuild {
|
||||
|
@ -618,7 +600,7 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn is_binary(&self) -> bool {
|
||||
self.src.to_bytes().is_empty() && self.il.is_empty()
|
||||
self.src.to_bytes().is_empty() && self.il.is_none()
|
||||
}
|
||||
|
||||
pub fn is_src(&self) -> bool {
|
||||
|
@ -626,9 +608,9 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn get_spec_constant_size(&self, spec_id: u32) -> u8 {
|
||||
let lock = self.build_info();
|
||||
let spirv = lock.builds.values().next().unwrap().spirv.as_ref().unwrap();
|
||||
spirv
|
||||
self.il
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.spec_constant(spec_id)
|
||||
.map_or(0, spirv::CLCSpecConstantType::size)
|
||||
}
|
||||
|
|
|
@ -405,6 +405,12 @@ impl SPIRVBin {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for SPIRVBin {
|
||||
fn clone(&self) -> Self {
|
||||
Self::from_bin(self.to_bin())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SPIRVBin {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
|
|
Loading…
Reference in New Issue