[spv-in] support image load/store ops

This commit is contained in:
Dzmitry Malyshau
2021-02-13 21:33:46 -05:00
committed by Dzmitry Malyshau
parent de5bd77279
commit 8e96085caf
4 changed files with 67 additions and 14 deletions

View File

@@ -1801,13 +1801,8 @@ impl Writer {
let reject_id =
self.write_expression(ir_module, ir_function, reject, block, function)?;
let instruction = Instruction::select(
result_type_id,
id,
condition_id,
accept_id,
reject_id,
);
let instruction =
Instruction::select(result_type_id, id, condition_id, accept_id, reject_id);
block.body.push(instruction);
RawExpression::Value(id)
}

View File

@@ -40,7 +40,7 @@ pub enum Error {
InvalidBinding(spirv::Word),
InvalidGlobalVar(crate::Expression),
InvalidImageBaseType(Handle<crate::Type>),
InvalidSampleImage(Handle<crate::Type>),
InvalidImage(Handle<crate::Type>),
InvalidDepthReference(Handle<crate::Type>),
InvalidAsType(Handle<crate::Type>),
InvalidVectorType(Handle<crate::Type>),

View File

@@ -182,7 +182,59 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
Ok(())
}
pub(super) fn parse_image_fetch(
pub(super) fn parse_image_write(
&mut self,
words_left: u16,
type_arena: &Arena<crate::Type>,
global_arena: &Arena<crate::GlobalVariable>,
expressions: &mut Arena<crate::Expression>,
) -> Result<crate::Statement, Error> {
let image_id = self.next()?;
let coordinate_id = self.next()?;
let value_id = self.next()?;
if words_left != 0 {
let image_ops = self.next()?;
let other = spirv::ImageOperands::from_bits_truncate(image_ops);
log::warn!("Skipping {:?}", other);
for _ in 1..words_left {
self.next()?;
}
}
let image_lexp = self.lookup_expression.lookup(image_id)?;
let image_var_handle = expressions[image_lexp.handle].as_global_var()?;
let image_var = &global_arena[image_var_handle];
let coord_lexp = self.lookup_expression.lookup(coordinate_id)?;
let coord_type_handle = self.lookup_type.lookup(coord_lexp.type_id)?.handle;
let (coordinate, array_index) = match type_arena[image_var.ty].inner {
crate::TypeInner::Image {
dim,
arrayed,
class: _,
} => extract_image_coordinates(
dim,
arrayed,
coord_lexp.handle,
coord_type_handle,
type_arena,
expressions,
),
_ => return Err(Error::InvalidImage(image_var.ty)),
};
let value_lexp = self.lookup_expression.lookup(value_id)?;
Ok(crate::Statement::ImageStore {
image: image_lexp.handle,
coordinate,
array_index,
value: value_lexp.handle,
})
}
pub(super) fn parse_image_load(
&mut self,
mut words_left: u16,
type_arena: &Arena<crate::Type>,
@@ -240,7 +292,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
type_arena,
expressions,
),
_ => return Err(Error::InvalidSampleImage(image_var.ty)),
_ => return Err(Error::InvalidImage(image_var.ty)),
};
let expr = crate::Expression::ImageLoad {
@@ -328,7 +380,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
type_arena,
expressions,
),
_ => return Err(Error::InvalidSampleImage(image_var.ty)),
_ => return Err(Error::InvalidImage(image_var.ty)),
};
let expr = crate::Expression::ImageSample {
@@ -429,7 +481,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
type_arena,
expressions,
),
_ => return Err(Error::InvalidSampleImage(image_var.ty)),
_ => return Err(Error::InvalidImage(image_var.ty)),
};
let expr = crate::Expression::ImageSample {

View File

@@ -1100,9 +1100,15 @@ impl<I: Iterator<Item = u32>> Parser<I> {
inst.expect(5)?;
self.parse_image_couple()?;
}
Op::ImageFetch => {
Op::ImageWrite => {
let extra = inst.expect_at_least(4)?;
let stmt =
self.parse_image_write(extra, type_arena, global_arena, expressions)?;
block.push(stmt);
}
Op::ImageFetch | Op::ImageRead => {
let extra = inst.expect_at_least(5)?;
self.parse_image_fetch(extra, type_arena, global_arena, expressions)?;
self.parse_image_load(extra, type_arena, global_arena, expressions)?;
}
Op::ImageSampleImplicitLod
| Op::ImageSampleExplicitLod