rusticl/program: some more API validation

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15439>
This commit is contained in:
Karol Herbst
2022-08-05 22:29:46 +02:00
committed by Marge Bot
parent 7a5817bf8c
commit 10c379bdd4
3 changed files with 42 additions and 3 deletions

View File

@@ -225,6 +225,11 @@ pub fn build_program(
check_cb(&pfn_notify, user_data)?;
// CL_INVALID_OPERATION if there are kernel objects attached to program.
if p.active_kernels() {
return Err(CL_INVALID_OPERATION);
}
// 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 {
@@ -236,7 +241,6 @@ pub fn build_program(
//• CL_INVALID_BINARY if program is created with clCreateProgramWithBinary and devices listed in device_list do not have a valid program binary loaded.
//• CL_INVALID_BUILD_OPTIONS if the build options specified by options are invalid.
//• CL_INVALID_OPERATION if the build of a program executable for any of the devices listed in device_list by a previous call to clBuildProgram for program has not completed.
//• CL_INVALID_OPERATION if there are kernel objects attached to program.
//• CL_INVALID_OPERATION if program was not created with clCreateProgramWithSource, clCreateProgramWithIL or clCreateProgramWithBinary.
if res {
@@ -282,6 +286,17 @@ pub fn compile_program(
}
}
// CL_INVALID_OPERATION if program has no source or IL available, i.e. it has not been created
// with clCreateProgramWithSource or clCreateProgramWithIL.
if p.is_binary() {
return Err(CL_INVALID_OPERATION);
}
// CL_INVALID_OPERATION if there are kernel objects attached to program.
if p.active_kernels() {
return Err(CL_INVALID_OPERATION);
}
// 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 {
@@ -290,10 +305,8 @@ pub fn compile_program(
call_cb(pfn_notify, program, user_data);
// CL_INVALID_OPERATION if program has no source or IL available, i.e. it has not been created with clCreateProgramWithSource or clCreateProgramWithIL.
// • CL_INVALID_COMPILER_OPTIONS if the compiler options specified by options are invalid.
// • CL_INVALID_OPERATION if the compilation or build of a program executable for any of the devices listed in device_list by a previous call to clCompileProgram or clBuildProgram for program has not completed.
// • CL_INVALID_OPERATION if there are kernel objects attached to program.
if res {
Ok(())

View File

@@ -24,6 +24,7 @@ use std::convert::TryInto;
use std::os::raw::c_void;
use std::ptr;
use std::slice;
use std::sync::atomic::Ordering;
use std::sync::Arc;
// ugh, we are not allowed to take refs, so...
@@ -720,6 +721,9 @@ impl Kernel {
// can't use vec!...
let values = args.iter().map(|_| RefCell::new(None)).collect();
// increase ref
prog.kernel_count.fetch_add(1, Ordering::Relaxed);
Arc::new(Self {
base: CLObjectBase::new(),
prog: prog,
@@ -1036,3 +1040,10 @@ impl Clone for Kernel {
}
}
}
impl Drop for Kernel {
fn drop(&mut self) {
// decrease ref
self.prog.kernel_count.fetch_sub(1, Ordering::Relaxed);
}
}

View File

@@ -15,6 +15,8 @@ use std::ffi::CString;
use std::mem::size_of;
use std::ptr;
use std::slice;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::MutexGuard;
@@ -50,6 +52,7 @@ pub struct Program {
pub devs: Vec<Arc<Device>>,
pub src: CString,
pub il: Vec<u8>,
pub kernel_count: AtomicU32,
spec_constants: Mutex<Vec<spirv::SpecConstant>>,
build: Mutex<ProgramBuild>,
}
@@ -140,6 +143,7 @@ impl Program {
devs: devs.to_vec(),
src: src,
il: Vec::new(),
kernel_count: AtomicU32::new(0),
spec_constants: Mutex::new(Vec::new()),
build: Mutex::new(ProgramBuild {
builds: builds,
@@ -212,6 +216,7 @@ impl Program {
devs: devs,
src: CString::new("").unwrap(),
il: Vec::new(),
kernel_count: AtomicU32::new(0),
spec_constants: Mutex::new(Vec::new()),
build: Mutex::new(ProgramBuild {
builds: builds,
@@ -244,6 +249,7 @@ impl Program {
context: context,
src: CString::new("").unwrap(),
il: spirv.to_vec(),
kernel_count: AtomicU32::new(0),
spec_constants: Mutex::new(Vec::new()),
build: Mutex::new(ProgramBuild {
builds: builds,
@@ -354,6 +360,10 @@ impl Program {
self.build_info().kernels.clone()
}
pub fn active_kernels(&self) -> bool {
self.kernel_count.load(Ordering::Relaxed) != 0
}
pub fn build(&self, dev: &Arc<Device>, options: String) -> bool {
// program binary
let is_il = !self.il.is_empty();
@@ -505,6 +515,7 @@ impl Program {
devs: devs,
src: CString::new("").unwrap(),
il: Vec::new(),
kernel_count: AtomicU32::new(0),
spec_constants: Mutex::new(Vec::new()),
build: Mutex::new(ProgramBuild {
builds: builds,
@@ -573,4 +584,8 @@ impl Program {
)
.unwrap()
}
pub fn is_binary(&self) -> bool {
self.src.to_bytes().is_empty() && self.il.is_empty()
}
}