[spv-out] Load texture arguments ahead of time

This commit is contained in:
João Capucho
2021-07-04 15:20:46 +01:00
committed by Dzmitry Malyshau
parent c7b98f5ab9
commit 2f002a0594
5 changed files with 78 additions and 56 deletions

View File

@@ -175,3 +175,13 @@ fn vector_size_str(size: crate::VectorSize) -> &'static str {
crate::VectorSize::Quad => "4",
}
}
impl crate::TypeInner {
#[allow(unused)]
fn is_handle(&self) -> bool {
match *self {
crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => true,
_ => false,
}
}
}

View File

@@ -703,7 +703,7 @@ impl<'w> BlockContext<'w> {
array_index,
index,
} => {
let image_id = self.get_image_id(block, image)?;
let image_id = self.get_image_id(image);
let coordinate_id =
self.write_texture_coordinates(coordinate, array_index, block)?;
@@ -773,7 +773,7 @@ impl<'w> BlockContext<'w> {
} => {
use super::instructions::SampleLod;
// image
let image_id = self.get_image_id(block, image)?;
let image_id = self.get_image_id(image);
let image_type = self.fun_info[image].ty.handle().unwrap();
// Vulkan doesn't know about our `Depth` class, and it returns `vec4<f32>`,
// so we need to grab the first component out of it.
@@ -800,7 +800,7 @@ impl<'w> BlockContext<'w> {
let sampled_image_type_id =
self.get_type_id(LookupType::Local(LocalType::SampledImage { image_type_id }))?;
let sampler_id = self.get_image_id(block, sampler)?;
let sampler_id = self.get_image_id(sampler);
let coordinate_id =
self.write_texture_coordinates(coordinate, array_index, block)?;
@@ -960,7 +960,7 @@ impl<'w> BlockContext<'w> {
crate::Expression::ImageQuery { image, query } => {
use crate::{ImageClass as Ic, ImageDimension as Id, ImageQuery as Iq};
let image_id = self.get_image_id(block, image)?;
let image_id = self.get_image_id(image);
let image_type = self.fun_info[image].ty.handle().unwrap();
let (dim, arrayed, class) = match self.ir_module.types[image_type].inner {
crate::TypeInner::Image {
@@ -1200,8 +1200,7 @@ impl<'w> BlockContext<'w> {
break local_var.id;
}
crate::Expression::FunctionArgument(index) => {
let id = self.function.parameters[index as usize].result_id.unwrap();
break id;
break self.function.parameter_id(index);
}
ref other => unimplemented!("Unexpected pointer expression {:?}", other),
}
@@ -1233,32 +1232,25 @@ impl<'w> BlockContext<'w> {
Ok(pointer)
}
fn get_image_id(
&mut self,
block: &mut Block,
expr_handle: Handle<crate::Expression>,
) -> Result<Word, Error> {
Ok(match self.ir_function.expressions[expr_handle] {
fn get_image_id(&mut self, expr_handle: Handle<crate::Expression>) -> Word {
let id = match self.ir_function.expressions[expr_handle] {
crate::Expression::GlobalVariable(handle) => {
let id = self.writer.global_variables[handle.index()].handle_id;
if id == 0 {
unreachable!("Global variable {:?} doesn't have a handle ID", handle);
}
id
self.writer.global_variables[handle.index()].handle_id
}
crate::Expression::FunctionArgument(i) => {
let result_type_id = self.get_type_id(LookupType::Handle(
self.ir_function.arguments[i as usize].ty,
))?;
let pointer_id = self.function.parameter_id(i);
let id = self.gen_id();
block
.body
.push(Instruction::load(result_type_id, id, pointer_id, None));
id
self.function.parameters[i as usize].handle_id
}
ref other => unreachable!("Unexpected global expression {:?}", other),
})
ref other => unreachable!("Unexpected image expression {:?}", other),
};
if id == 0 {
unreachable!(
"Image expression {:?} doesn't have a handle ID",
expr_handle
);
}
id
}
pub(super) fn write_block(
@@ -1531,7 +1523,7 @@ impl<'w> BlockContext<'w> {
array_index,
value,
} => {
let image_id = self.get_image_id(&mut block, image)?;
let image_id = self.get_image_id(image);
let coordinate_id =
self.write_texture_coordinates(coordinate, array_index, &mut block)?;
let value_id = self.cached(value);

View File

@@ -125,7 +125,7 @@ struct EntryPointContext {
#[derive(Default)]
struct Function {
signature: Option<Instruction>,
parameters: Vec<Instruction>,
parameters: Vec<FunctionArgument>,
variables: crate::FastHashMap<Handle<crate::LocalVariable>, LocalVariable>,
blocks: Vec<TerminatedBlock>,
entry_point_context: Option<EntryPointContext>,
@@ -143,7 +143,10 @@ impl Function {
fn parameter_id(&self, index: u32) -> Word {
match self.entry_point_context {
Some(ref context) => context.argument_ids[index as usize],
None => self.parameters[index as usize].result_id.unwrap(),
None => self.parameters[index as usize]
.instruction
.result_id
.unwrap(),
}
}
}
@@ -311,6 +314,12 @@ struct GlobalVariable {
handle_id: Word,
}
struct FunctionArgument {
/// Actual instruction of the argument.
instruction: Instruction,
handle_id: Word,
}
/// General information needed to emit SPIR-V for Naga statements.
struct BlockContext<'w> {
/// The writer handling the module to which this code belongs.

View File

@@ -1,9 +1,9 @@
use super::{
helpers::{contains_builtin, map_storage_class},
make_local, Block, BlockContext, CachedExpressions, EntryPointContext, Error, Function,
GlobalVariable, IdGenerator, Instruction, LocalType, LocalVariable, LogicalLayout,
LookupFunctionType, LookupType, LoopContext, Options, PhysicalLayout, ResultMember, Writer,
WriterFlags, BITS_PER_BYTE,
FunctionArgument, GlobalVariable, IdGenerator, Instruction, LocalType, LocalVariable,
LogicalLayout, LookupFunctionType, LookupType, LoopContext, Options, PhysicalLayout,
ResultMember, Writer, WriterFlags, BITS_PER_BYTE,
};
use crate::{
arena::{Arena, Handle},
@@ -25,8 +25,8 @@ fn map_dim(dim: crate::ImageDimension) -> spirv::Dim {
impl Function {
fn to_words(&self, sink: &mut impl Extend<Word>) {
self.signature.as_ref().unwrap().to_words(sink);
for instruction in self.parameters.iter() {
instruction.to_words(sink);
for argument in self.parameters.iter() {
argument.instruction.to_words(sink);
}
for (index, block) in self.blocks.iter().enumerate() {
Instruction::label(block.label_id).to_words(sink);
@@ -269,10 +269,7 @@ impl Writer {
let mut parameter_type_ids = Vec::with_capacity(ir_function.arguments.len());
for argument in ir_function.arguments.iter() {
let class = spirv::StorageClass::Input;
let handle_ty = match ir_module.types[argument.ty].inner {
crate::TypeInner::Image { .. } | crate::TypeInner::Sampler { .. } => true,
_ => false,
};
let handle_ty = ir_module.types[argument.ty].inner.is_handle();
let argument_type_id = match handle_ty {
true => self.get_pointer_id(
&ir_module.types,
@@ -321,9 +318,23 @@ impl Writer {
};
ep_context.argument_ids.push(id);
} else {
let id = self.id_gen.next();
let instruction = Instruction::function_parameter(argument_type_id, id);
function.parameters.push(instruction);
let argument_id = self.id_gen.next();
let instruction = Instruction::function_parameter(argument_type_id, argument_id);
function.parameters.push(FunctionArgument {
instruction,
handle_id: if handle_ty {
let id = self.id_gen.next();
prelude.body.push(Instruction::load(
self.get_type_id(LookupType::Handle(argument.ty))?,
id,
argument_id,
None,
));
id
} else {
0
},
});
parameter_type_ids.push(argument_type_id);
};
}

View File

@@ -10,7 +10,7 @@ OpExecutionMode %28 OriginUpperLeft
OpSource GLSL 450
OpName %9 "Texture"
OpName %11 "Sampler"
OpName %16 "test"
OpName %18 "test"
OpName %28 "main"
OpDecorate %9 DescriptorSet 0
OpDecorate %9 Binding 0
@@ -28,22 +28,22 @@ OpDecorate %26 Location 0
%9 = OpVariable %10 UniformConstant
%12 = OpTypePointer UniformConstant %6
%11 = OpVariable %12 UniformConstant
%17 = OpTypeFunction %7 %10 %12
%21 = OpTypeSampledImage %5
%19 = OpTypeFunction %7 %10 %12
%22 = OpTypeSampledImage %5
%27 = OpTypePointer Output %7
%26 = OpVariable %27 Output
%29 = OpTypeFunction %2
%16 = OpFunction %7 None %17
%18 = OpFunction %7 None %19
%14 = OpFunctionParameter %10
%15 = OpFunctionParameter %12
%16 = OpFunctionParameter %12
%13 = OpLabel
OpBranch %18
%18 = OpLabel
%19 = OpCompositeConstruct %8 %3 %3
%20 = OpLoad %5 %14
%22 = OpLoad %6 %15
%23 = OpSampledImage %21 %20 %22
%24 = OpImageSampleImplicitLod %7 %23 %19
%15 = OpLoad %5 %14
%17 = OpLoad %6 %16
OpBranch %20
%20 = OpLabel
%21 = OpCompositeConstruct %8 %3 %3
%23 = OpSampledImage %22 %15 %17
%24 = OpImageSampleImplicitLod %7 %23 %21
OpReturnValue %24
OpFunctionEnd
%28 = OpFunction %2 None %29
@@ -52,7 +52,7 @@ OpFunctionEnd
%31 = OpLoad %6 %11
OpBranch %32
%32 = OpLabel
%33 = OpFunctionCall %7 %16 %9 %11
%33 = OpFunctionCall %7 %18 %9 %11
OpStore %26 %33
OpReturn
OpFunctionEnd