Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions rspirv/dr/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,36 @@ impl Builder {
}
}

/// Appends an OpTypeUntypedPointerKHR instruction and returns the result id, or return the existing id if the instruction was already present.
pub fn type_untyped_pointer(
&mut self,
result_id: Option<spirv::Word>,
storage_class: spirv::StorageClass,
) -> spirv::Word {
let mut inst = dr::Instruction::new(
spirv::Op::TypeUntypedPointerKHR,
None,
result_id,
vec![
dr::Operand::StorageClass(storage_class),
],
);
if let Some(result_id) = result_id {
// An explicit ID was provided, emit it no matter what.
self.module.types_global_values.push(inst);
result_id
} else if let Some(id) = self.dedup_insert_type(&inst) {
// No ID was provided, and the type has already been declared.
id
} else {
// No ID was provided, it didn't already exist, so generate a new ID and emit it.
let new_id = self.id();
inst.result_id = Some(new_id);
self.module.types_global_values.push(inst);
new_id
}
}

/// Appends an OpTypeOpaque instruction and returns the result id.
pub fn type_opaque(&mut self, type_name: impl Into<String>) -> spirv::Word {
let id = self.id();
Expand Down Expand Up @@ -833,6 +863,41 @@ impl Builder {
id
}

/// Appends an OpUntypedVariable instruction to either the current block
/// or the module if no block is under construction.
pub fn untyped_variable(
&mut self,
result_type: spirv::Word,
result_id: Option<spirv::Word>,
storage_class: spirv::StorageClass,
data_type: Option<spirv::Word>,
initializer: Option<spirv::Word>,
) -> spirv::Word {
let id = match result_id {
Some(v) => v,
None => self.id(),
};
let mut operands = vec![dr::Operand::StorageClass(storage_class)];
if let Some(val) = data_type {
operands.push(dr::Operand::IdRef(val));
}
if let Some(val) = initializer {
operands.push(dr::Operand::IdRef(val));
}

let inst = dr::Instruction::new(spirv::Op::UntypedVariableKHR, Some(result_type), Some(id), operands);

match (self.selected_function, self.selected_block) {
(Some(selected_function), Some(selected_block)) => {
self.module.functions[selected_function].blocks[selected_block]
.instructions
.push(inst)
}
_ => self.module.types_global_values.push(inst),
}
id
}

/// Appends an OpUndef instruction to either the current block
/// or the module if no block is under construction.
pub fn undef(
Expand Down
2 changes: 1 addition & 1 deletion rspirv/dr/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl binary::Consumer for Loader {
{
self.module.types_global_values.push(inst)
}
spirv::Op::Variable if self.function.is_none() => {
spirv::Op::Variable | spirv::Op::UntypedVariableKHR if self.function.is_none() => {
self.module.types_global_values.push(inst)
}
spirv::Op::Undef if self.function.is_none() => {
Expand Down
3 changes: 2 additions & 1 deletion rspirv/grammar/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub fn is_type(opcode: spirv::Op) -> bool {
| spirv::Op::TypeStruct
| spirv::Op::TypeOpaque
| spirv::Op::TypePointer
| spirv::Op::TypeUntypedPointerKHR
| spirv::Op::TypeFunction
| spirv::Op::TypeEvent
| spirv::Op::TypeDeviceEvent
Expand Down Expand Up @@ -91,7 +92,7 @@ pub fn is_constant(opcode: spirv::Op) -> bool {

/// Returns true if the given opcode is for a variable-defining instruction.
pub fn is_variable(opcode: spirv::Op) -> bool {
opcode == spirv::Op::Variable
matches!(opcode, spirv::Op::Variable | spirv::Op::UntypedVariableKHR)
}

/// Returns true if the given opcode is a return instruction.
Expand Down