host_ptr: *mut ::std::os::raw::c_void,
elem_size: usize,
devs: &[Arc<Device>],
-) -> CLResult<cl_image_desc> {
+) -> CLResult<(cl_image_desc, Option<Arc<Mem>>)> {
// CL_INVALID_IMAGE_DESCRIPTOR if values specified in image_desc are not valid
const err: cl_int = CL_INVALID_IMAGE_DESCRIPTOR;
//
// TODO: cl_khr_image2d_from_buffer is an optional feature
let p = unsafe { &desc.anon_1.mem_object };
- if !p.is_null() {
- let p = p.get_ref()?;
+ let parent = if !p.is_null() {
+ let p = p.get_arc()?;
if !match desc.image_type {
CL_MEM_OBJECT_IMAGE1D_BUFFER => p.is_buffer(),
CL_MEM_OBJECT_IMAGE2D => !p.is_buffer(),
} {
return Err(CL_INVALID_OPERATION);
}
- }
+ Some(p)
+ } else {
+ None
+ };
// image_row_pitch is the scan-line pitch in bytes. This must be 0 if host_ptr is NULL and can
// be either 0 or ≥ image_width × size of element in bytes if host_ptr is not NULL. If host_ptr
}
}
- Ok(desc)
+ Ok((desc, parent))
}
fn desc_eq_no_buffer(a: &cl_image_desc, b: &cl_image_desc) -> bool {
.ok_or(CL_INVALID_OPERATION)?;
let (format, elem_size) = validate_image_format(image_format)?;
- let desc = validate_image_desc(image_desc, host_ptr, elem_size.into(), &c.devs)?;
+ let (desc, parent) = validate_image_desc(image_desc, host_ptr, elem_size.into(), &c.devs)?;
+
+ // validate host_ptr before merging flags
+ validate_host_ptr(host_ptr, flags)?;
+
flags = validate_buffer(&desc, flags, format, host_ptr, elem_size.into())?;
// For all image types except CL_MEM_OBJECT_IMAGE1D_BUFFER, if the value specified for flags is 0, the
}
validate_mem_flags(flags, false)?;
- validate_host_ptr(host_ptr, flags)?;
let filtered_flags = filter_image_access_flags(flags);
// CL_IMAGE_FORMAT_NOT_SUPPORTED if there are no devices in context that support image_format.
Ok(cl_mem::from_arc(Mem::new_image(
c,
+ parent,
desc.image_type,
flags,
format,
use crate::api::util::cl_prop;
use crate::core::device::*;
use crate::core::event::*;
+use crate::core::format::*;
use crate::core::memory::*;
use crate::core::program::*;
use crate::core::queue::*;
input.extend_from_slice(&mem.offset.to_ne_bytes());
resource_info.push((Some(res.clone()), arg.offset));
} else {
+ let format = mem.image_format.to_pipe_format().unwrap();
let (formats, orders) = if arg.kind == KernelArgType::Image {
- iviews.push(res.pipe_image_view());
+ iviews.push(res.pipe_image_view(format));
(&mut img_formats, &mut img_orders)
} else {
- sviews.push(res.clone());
+ sviews.push((res.clone(), format));
(&mut tex_formats, &mut tex_orders)
};
let mut globals: Vec<*mut u32> = Vec::new();
let printf_format = nir.printf_format();
- let mut sviews: Vec<_> = sviews.iter().map(|s| ctx.create_sampler_view(s)).collect();
+ let mut sviews: Vec<_> = sviews
+ .iter()
+ .map(|(s, f)| ctx.create_sampler_view(s, *f))
+ .collect();
let samplers: Vec<_> = samplers
.iter()
.map(|s| ctx.create_sampler_state(s))
pub fn new_image(
context: Arc<Context>,
+ parent: Option<Arc<Mem>>,
mem_type: cl_mem_object_type,
flags: cl_mem_flags,
image_format: &cl_image_format,
image_desc.image_array_size = 1;
}
- let texture = context.create_texture(
- &image_desc,
- image_format,
- host_ptr,
- bit_check(flags, CL_MEM_COPY_HOST_PTR),
- )?;
+ let texture = if parent.is_none() {
+ Some(context.create_texture(
+ &image_desc,
+ image_format,
+ host_ptr,
+ bit_check(flags, CL_MEM_COPY_HOST_PTR),
+ )?)
+ } else {
+ None
+ };
let host_ptr = if bit_check(flags, CL_MEM_USE_HOST_PTR) {
host_ptr
Ok(Arc::new(Self {
base: CLObjectBase::new(),
context: context,
- parent: None,
+ parent: parent,
mem_type: mem_type,
flags: flags,
size: image_desc.pixels() * image_format.pixel_size().unwrap() as usize,
image_elem_size: image_elem_size,
props: props,
cbs: Mutex::new(Vec::new()),
- res: Some(texture),
+ res: texture,
maps: Mappings::new(),
}))
}
CL_MEM_OBJECT_IMAGE3D => pipe_texture_target::PIPE_TEXTURE_3D,
CL_MEM_OBJECT_IMAGE1D_ARRAY => pipe_texture_target::PIPE_TEXTURE_1D_ARRAY,
CL_MEM_OBJECT_IMAGE2D_ARRAY => pipe_texture_target::PIPE_TEXTURE_2D_ARRAY,
- CL_MEM_OBJECT_IMAGE1D_BUFFER => pipe_texture_target::PIPE_BUFFER,
+ CL_MEM_OBJECT_IMAGE1D_BUFFER => pipe_texture_target::PIPE_TEXTURE_1D,
_ => pipe_texture_target::PIPE_TEXTURE_2D,
}
}
}
}
- pub fn create_sampler_view(&self, res: &PipeResource) -> *mut pipe_sampler_view {
- let template = res.pipe_sampler_view_template();
+ pub fn create_sampler_view(
+ &self,
+ res: &PipeResource,
+ format: pipe_format,
+ ) -> *mut pipe_sampler_view {
+ let template = res.pipe_sampler_view_template(format);
unsafe {
self.pipe.as_ref().create_sampler_view.unwrap()(
self.pipe.as_ptr(),
unsafe { self.pipe.as_ref().unwrap() }
}
- pub fn pipe_image_view(&self) -> pipe_image_view {
+ pub fn pipe_image_view(&self, format: pipe_format) -> pipe_image_view {
let u = if self.as_ref().target() == pipe_texture_target::PIPE_BUFFER {
pipe_image_view__bindgen_ty_1 {
buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 {
pipe_image_view {
resource: self.pipe(),
- format: self.as_ref().format(),
+ format: format,
access: 0,
shader_access: PIPE_IMAGE_ACCESS_WRITE as u16,
u: u,
}
}
- pub fn pipe_sampler_view_template(&self) -> pipe_sampler_view {
+ pub fn pipe_sampler_view_template(&self, format: pipe_format) -> pipe_sampler_view {
let mut res = pipe_sampler_view::default();
unsafe {
- u_sampler_view_default_template(&mut res, self.pipe, self.as_ref().format());
+ u_sampler_view_default_template(&mut res, self.pipe, format);
}
+
+ if res.target() == pipe_texture_target::PIPE_BUFFER {
+ res.u.buf.size = self.as_ref().width0;
+ }
+
res
}
}