mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[spv-out] Load texture arguments ahead of time
This commit is contained in:
committed by
Dzmitry Malyshau
parent
c7b98f5ab9
commit
2f002a0594
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user