*/
view->target = texture->target;
+ view->is_tex2d_from_buf = false;
view->format = format;
view->u.tex.first_level = 0;
view->u.tex.last_level = texture->last_level;
KernelArgValue::Constant(c) => input.extend_from_slice(c),
KernelArgValue::MemObject(mem) => {
let res = mem.get_res_of_dev(&q.device)?;
+ // If resource is a buffer and mem a 2D image, the 2d image was created from a
+ // buffer. Use strides and dimensions of 2d image
+ let app_img_info =
+ if res.as_ref().is_buffer() && mem.mem_type == CL_MEM_OBJECT_IMAGE2D {
+ Some(AppImgInfo::new(
+ mem.image_desc.row_pitch()? / mem.image_elem_size as u32,
+ mem.image_desc.width()?,
+ mem.image_desc.height()?,
+ ))
+ } else {
+ None
+ };
if mem.is_buffer() {
if q.device.address_bits() == 64 {
input.extend_from_slice(&mem.offset.to_ne_bytes());
} else {
let format = mem.image_format.to_pipe_format().unwrap();
let (formats, orders) = if arg.kind == KernelArgType::Image {
- iviews.push(res.pipe_image_view(format, false));
+ iviews.push(res.pipe_image_view(format, false, app_img_info.as_ref()));
(&mut img_formats, &mut img_orders)
} else if arg.kind == KernelArgType::RWImage {
- iviews.push(res.pipe_image_view(format, true));
+ iviews.push(res.pipe_image_view(format, true, app_img_info.as_ref()));
(&mut img_formats, &mut img_orders)
} else {
- sviews.push((res.clone(), format));
+ sviews.push((res.clone(), format, app_img_info));
(&mut tex_formats, &mut tex_orders)
};
let mut sviews: Vec<_> = sviews
.iter()
- .map(|(s, f)| ctx.create_sampler_view(s, *f))
+ .map(|(s, f, aii)| ctx.create_sampler_view(s, *f, aii.as_ref()))
.collect();
let samplers: Vec<_> = samplers
.iter()
fn bx(&self) -> CLResult<pipe_box>;
fn row_pitch(&self) -> CLResult<u32>;
fn slice_pitch(&self) -> CLResult<u32>;
+ fn width(&self) -> CLResult<u32>;
+ fn height(&self) -> CLResult<u32>;
fn size(&self) -> CLVec<usize>;
fn api_size(&self) -> CLVec<usize>;
.try_into()
.map_err(|_| CL_OUT_OF_HOST_MEMORY)
}
+
+ fn width(&self) -> CLResult<u32> {
+ self.image_width
+ .try_into()
+ .map_err(|_| CL_OUT_OF_HOST_MEMORY)
+ }
+
+ fn height(&self) -> CLResult<u32> {
+ self.image_height
+ .try_into()
+ .map_err(|_| CL_OUT_OF_HOST_MEMORY)
+ }
}
fn sw_copy(
&self,
res: &PipeResource,
format: pipe_format,
+ app_img_info: Option<&AppImgInfo>,
) -> *mut pipe_sampler_view {
- let template = res.pipe_sampler_view_template(format);
+ let template = res.pipe_sampler_view_template(format, app_img_info);
+
unsafe {
- self.pipe.as_ref().create_sampler_view.unwrap()(
+ let s_view = self.pipe.as_ref().create_sampler_view.unwrap()(
self.pipe.as_ptr(),
res.pipe(),
&template,
- )
+ );
+
+ s_view
}
}
pub is_user: bool,
}
+// Image dimensions provide by application to be used in both
+// image and sampler views when image is created from buffer
+#[derive(PartialEq, Eq)]
+pub struct AppImgInfo {
+ row_stride: u32,
+ width: u32,
+ height: u32,
+}
+
+impl AppImgInfo {
+ pub fn new(row_stride: u32, width: u32, height: u32) -> AppImgInfo {
+ AppImgInfo {
+ row_stride: row_stride,
+ width: width,
+ height: height,
+ }
+ }
+}
+
impl PipeResource {
pub fn new(res: *mut pipe_resource, is_user: bool) -> Option<Self> {
if res.is_null() {
unsafe { self.pipe.as_ref().unwrap().array_size }
}
- pub fn pipe_image_view(&self, format: pipe_format, read_write: bool) -> pipe_image_view {
- let u = if self.as_ref().target() == pipe_texture_target::PIPE_BUFFER {
+ pub fn is_buffer(&self) -> bool {
+ self.as_ref().target() == pipe_texture_target::PIPE_BUFFER
+ }
+
+ pub fn pipe_image_view(
+ &self,
+ format: pipe_format,
+ read_write: bool,
+ app_img_info: Option<&AppImgInfo>,
+ ) -> pipe_image_view {
+ let u = if let Some(app_img_info) = app_img_info {
+ pipe_image_view__bindgen_ty_1 {
+ tex2d_from_buf: pipe_image_view__bindgen_ty_1__bindgen_ty_3 {
+ offset: 0,
+ row_stride: app_img_info.row_stride as u16,
+ width: app_img_info.width as u16,
+ height: app_img_info.height as u16,
+ },
+ }
+ } else if self.is_buffer() {
pipe_image_view__bindgen_ty_1 {
buf: pipe_image_view__bindgen_ty_1__bindgen_ty_2 {
offset: 0,
PIPE_IMAGE_ACCESS_WRITE
} as u16;
+ let access = if app_img_info.is_some() {
+ PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER
+ } else {
+ 0
+ } as u16;
+
pipe_image_view {
resource: self.pipe(),
format: format,
- access: 0,
+ access: access,
shader_access: shader_access,
u: u,
}
}
- pub fn pipe_sampler_view_template(&self, format: pipe_format) -> pipe_sampler_view {
+ pub fn pipe_sampler_view_template(
+ &self,
+ format: pipe_format,
+ app_img_info: Option<&AppImgInfo>,
+ ) -> pipe_sampler_view {
let mut res = pipe_sampler_view::default();
unsafe {
u_sampler_view_default_template(&mut res, self.pipe, format);
}
- if res.target() == pipe_texture_target::PIPE_BUFFER {
+ if let Some(app_img_info) = app_img_info {
+ res.u.tex2d_from_buf.offset = 0;
+ res.u.tex2d_from_buf.row_stride = app_img_info.row_stride as u16;
+ res.u.tex2d_from_buf.width = app_img_info.width as u16;
+ res.u.tex2d_from_buf.height = app_img_info.height as u16;
+
+ res.set_is_tex2d_from_buf(true);
+ } else if res.target() == pipe_texture_target::PIPE_BUFFER {
+ res.u.buf.offset = 0;
res.u.buf.size = self.as_ref().width0;
}
/**
* pipe_image_view access flags.
*/
-#define PIPE_IMAGE_ACCESS_READ (1 << 0)
-#define PIPE_IMAGE_ACCESS_WRITE (1 << 1)
-#define PIPE_IMAGE_ACCESS_READ_WRITE (PIPE_IMAGE_ACCESS_READ | \
- PIPE_IMAGE_ACCESS_WRITE)
-#define PIPE_IMAGE_ACCESS_COHERENT (1 << 2)
-#define PIPE_IMAGE_ACCESS_VOLATILE (1 << 3)
+#define PIPE_IMAGE_ACCESS_READ (1 << 0)
+#define PIPE_IMAGE_ACCESS_WRITE (1 << 1)
+#define PIPE_IMAGE_ACCESS_READ_WRITE (PIPE_IMAGE_ACCESS_READ | \
+ PIPE_IMAGE_ACCESS_WRITE)
+#define PIPE_IMAGE_ACCESS_COHERENT (1 << 2)
+#define PIPE_IMAGE_ACCESS_VOLATILE (1 << 3)
+#define PIPE_IMAGE_ACCESS_TEX2D_FROM_BUFFER (1 << 4)
/**
* Implementation capabilities/limits which are queried through
/* Put the refcount on its own cache line to prevent "False sharing". */
EXCLUSIVE_CACHELINE(struct pipe_reference reference);
- enum pipe_format format:15; /**< typed PIPE_FORMAT_x */
+ enum pipe_format format:14; /**< typed PIPE_FORMAT_x */
+ bool is_tex2d_from_buf:1; /**< true if union is tex2d_from_buf */
enum pipe_texture_target target:5; /**< PIPE_TEXTURE_x */
unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */
unsigned swizzle_g:3; /**< PIPE_SWIZZLE_x for green component */
unsigned offset; /**< offset in bytes */
unsigned size; /**< size of the readable sub-range in bytes */
} buf;
+ struct {
+ unsigned offset; /**< offset in pixels */
+ uint16_t row_stride; /**< size of the image row_stride in pixels */
+ uint16_t width; /**< width of image provided by application */
+ uint16_t height; /**< height of image provided by application */
+ } tex2d_from_buf; /**< used in cl extension cl_khr_image2d_from_buffer */
} u;
};
enum pipe_format format; /**< typed PIPE_FORMAT_x */
uint16_t access; /**< PIPE_IMAGE_ACCESS_x */
uint16_t shader_access; /**< PIPE_IMAGE_ACCESS_x */
-
union {
struct {
unsigned first_layer:16; /**< first layer to use for array textures */
unsigned offset; /**< offset in bytes */
unsigned size; /**< size of the accessible sub-range in bytes */
} buf;
+ struct {
+ unsigned offset; /**< offset in pixels */
+ uint16_t row_stride; /**< size of the image row_stride in pixels */
+ uint16_t width; /**< width of image provided by application */
+ uint16_t height; /**< height of image provided by application */
+ } tex2d_from_buf; /**< used in cl extension cl_khr_image2d_from_buffer */
} u;
};