1 use super::helpers; 2 use spirv::{Op, Word}; 3 4 pub(super) enum Signedness { 5 Unsigned = 0, 6 Signed = 1, 7 } 8 9 pub(super) enum SampleLod { 10 Explicit, 11 Implicit, 12 } 13 14 pub(super) struct Case { 15 pub value: Word, 16 pub label_id: Word, 17 } 18 19 impl super::Instruction { 20 // 21 // Debug Instructions 22 // 23 source(source_language: spirv::SourceLanguage, version: u32) -> Self24 pub(super) fn source(source_language: spirv::SourceLanguage, version: u32) -> Self { 25 let mut instruction = Self::new(Op::Source); 26 instruction.add_operand(source_language as u32); 27 instruction.add_operands(helpers::bytes_to_words(&version.to_le_bytes())); 28 instruction 29 } 30 name(target_id: Word, name: &str) -> Self31 pub(super) fn name(target_id: Word, name: &str) -> Self { 32 let mut instruction = Self::new(Op::Name); 33 instruction.add_operand(target_id); 34 instruction.add_operands(helpers::string_to_words(name)); 35 instruction 36 } 37 member_name(target_id: Word, member: Word, name: &str) -> Self38 pub(super) fn member_name(target_id: Word, member: Word, name: &str) -> Self { 39 let mut instruction = Self::new(Op::MemberName); 40 instruction.add_operand(target_id); 41 instruction.add_operand(member); 42 instruction.add_operands(helpers::string_to_words(name)); 43 instruction 44 } 45 46 // 47 // Annotation Instructions 48 // 49 decorate( target_id: Word, decoration: spirv::Decoration, operands: &[Word], ) -> Self50 pub(super) fn decorate( 51 target_id: Word, 52 decoration: spirv::Decoration, 53 operands: &[Word], 54 ) -> Self { 55 let mut instruction = Self::new(Op::Decorate); 56 instruction.add_operand(target_id); 57 instruction.add_operand(decoration as u32); 58 for operand in operands { 59 instruction.add_operand(*operand) 60 } 61 instruction 62 } 63 member_decorate( target_id: Word, member_index: Word, decoration: spirv::Decoration, operands: &[Word], ) -> Self64 pub(super) fn member_decorate( 65 target_id: Word, 66 member_index: Word, 67 decoration: spirv::Decoration, 68 operands: &[Word], 69 ) -> Self { 70 let mut instruction = Self::new(Op::MemberDecorate); 71 instruction.add_operand(target_id); 72 instruction.add_operand(member_index); 73 instruction.add_operand(decoration as u32); 74 for operand in operands { 75 instruction.add_operand(*operand) 76 } 77 instruction 78 } 79 80 // 81 // Extension Instructions 82 // 83 extension(name: &str) -> Self84 pub(super) fn extension(name: &str) -> Self { 85 let mut instruction = Self::new(Op::Extension); 86 instruction.add_operands(helpers::string_to_words(name)); 87 instruction 88 } 89 ext_inst_import(id: Word, name: &str) -> Self90 pub(super) fn ext_inst_import(id: Word, name: &str) -> Self { 91 let mut instruction = Self::new(Op::ExtInstImport); 92 instruction.set_result(id); 93 instruction.add_operands(helpers::string_to_words(name)); 94 instruction 95 } 96 ext_inst( set_id: Word, op: spirv::GLOp, result_type_id: Word, id: Word, operands: &[Word], ) -> Self97 pub(super) fn ext_inst( 98 set_id: Word, 99 op: spirv::GLOp, 100 result_type_id: Word, 101 id: Word, 102 operands: &[Word], 103 ) -> Self { 104 let mut instruction = Self::new(Op::ExtInst); 105 instruction.set_type(result_type_id); 106 instruction.set_result(id); 107 instruction.add_operand(set_id); 108 instruction.add_operand(op as u32); 109 for operand in operands { 110 instruction.add_operand(*operand) 111 } 112 instruction 113 } 114 115 // 116 // Mode-Setting Instructions 117 // 118 memory_model( addressing_model: spirv::AddressingModel, memory_model: spirv::MemoryModel, ) -> Self119 pub(super) fn memory_model( 120 addressing_model: spirv::AddressingModel, 121 memory_model: spirv::MemoryModel, 122 ) -> Self { 123 let mut instruction = Self::new(Op::MemoryModel); 124 instruction.add_operand(addressing_model as u32); 125 instruction.add_operand(memory_model as u32); 126 instruction 127 } 128 entry_point( execution_model: spirv::ExecutionModel, entry_point_id: Word, name: &str, interface_ids: &[Word], ) -> Self129 pub(super) fn entry_point( 130 execution_model: spirv::ExecutionModel, 131 entry_point_id: Word, 132 name: &str, 133 interface_ids: &[Word], 134 ) -> Self { 135 let mut instruction = Self::new(Op::EntryPoint); 136 instruction.add_operand(execution_model as u32); 137 instruction.add_operand(entry_point_id); 138 instruction.add_operands(helpers::string_to_words(name)); 139 140 for interface_id in interface_ids { 141 instruction.add_operand(*interface_id); 142 } 143 144 instruction 145 } 146 execution_mode( entry_point_id: Word, execution_mode: spirv::ExecutionMode, args: &[Word], ) -> Self147 pub(super) fn execution_mode( 148 entry_point_id: Word, 149 execution_mode: spirv::ExecutionMode, 150 args: &[Word], 151 ) -> Self { 152 let mut instruction = Self::new(Op::ExecutionMode); 153 instruction.add_operand(entry_point_id); 154 instruction.add_operand(execution_mode as u32); 155 for arg in args { 156 instruction.add_operand(*arg); 157 } 158 instruction 159 } 160 capability(capability: spirv::Capability) -> Self161 pub(super) fn capability(capability: spirv::Capability) -> Self { 162 let mut instruction = Self::new(Op::Capability); 163 instruction.add_operand(capability as u32); 164 instruction 165 } 166 167 // 168 // Type-Declaration Instructions 169 // 170 type_void(id: Word) -> Self171 pub(super) fn type_void(id: Word) -> Self { 172 let mut instruction = Self::new(Op::TypeVoid); 173 instruction.set_result(id); 174 instruction 175 } 176 type_bool(id: Word) -> Self177 pub(super) fn type_bool(id: Word) -> Self { 178 let mut instruction = Self::new(Op::TypeBool); 179 instruction.set_result(id); 180 instruction 181 } 182 type_int(id: Word, width: Word, signedness: Signedness) -> Self183 pub(super) fn type_int(id: Word, width: Word, signedness: Signedness) -> Self { 184 let mut instruction = Self::new(Op::TypeInt); 185 instruction.set_result(id); 186 instruction.add_operand(width); 187 instruction.add_operand(signedness as u32); 188 instruction 189 } 190 type_float(id: Word, width: Word) -> Self191 pub(super) fn type_float(id: Word, width: Word) -> Self { 192 let mut instruction = Self::new(Op::TypeFloat); 193 instruction.set_result(id); 194 instruction.add_operand(width); 195 instruction 196 } 197 type_vector( id: Word, component_type_id: Word, component_count: crate::VectorSize, ) -> Self198 pub(super) fn type_vector( 199 id: Word, 200 component_type_id: Word, 201 component_count: crate::VectorSize, 202 ) -> Self { 203 let mut instruction = Self::new(Op::TypeVector); 204 instruction.set_result(id); 205 instruction.add_operand(component_type_id); 206 instruction.add_operand(component_count as u32); 207 instruction 208 } 209 type_matrix( id: Word, column_type_id: Word, column_count: crate::VectorSize, ) -> Self210 pub(super) fn type_matrix( 211 id: Word, 212 column_type_id: Word, 213 column_count: crate::VectorSize, 214 ) -> Self { 215 let mut instruction = Self::new(Op::TypeMatrix); 216 instruction.set_result(id); 217 instruction.add_operand(column_type_id); 218 instruction.add_operand(column_count as u32); 219 instruction 220 } 221 type_image( id: Word, sampled_type_id: Word, dim: spirv::Dim, arrayed: bool, image_class: crate::ImageClass, ) -> Self222 pub(super) fn type_image( 223 id: Word, 224 sampled_type_id: Word, 225 dim: spirv::Dim, 226 arrayed: bool, 227 image_class: crate::ImageClass, 228 ) -> Self { 229 let mut instruction = Self::new(Op::TypeImage); 230 instruction.set_result(id); 231 instruction.add_operand(sampled_type_id); 232 instruction.add_operand(dim as u32); 233 234 let (depth, multi, sampled) = match image_class { 235 crate::ImageClass::Sampled { kind: _, multi } => (false, multi, true), 236 crate::ImageClass::Depth => (true, false, true), 237 crate::ImageClass::Storage(_) => (false, false, false), 238 }; 239 instruction.add_operand(depth as u32); 240 instruction.add_operand(arrayed as u32); 241 instruction.add_operand(multi as u32); 242 instruction.add_operand(if sampled { 1 } else { 2 }); 243 244 let format = match image_class { 245 crate::ImageClass::Storage(format) => match format { 246 crate::StorageFormat::R8Unorm => spirv::ImageFormat::R8, 247 crate::StorageFormat::R8Snorm => spirv::ImageFormat::R8Snorm, 248 crate::StorageFormat::R8Uint => spirv::ImageFormat::R8ui, 249 crate::StorageFormat::R8Sint => spirv::ImageFormat::R8i, 250 crate::StorageFormat::R16Uint => spirv::ImageFormat::R16ui, 251 crate::StorageFormat::R16Sint => spirv::ImageFormat::R16i, 252 crate::StorageFormat::R16Float => spirv::ImageFormat::R16f, 253 crate::StorageFormat::Rg8Unorm => spirv::ImageFormat::Rg8, 254 crate::StorageFormat::Rg8Snorm => spirv::ImageFormat::Rg8Snorm, 255 crate::StorageFormat::Rg8Uint => spirv::ImageFormat::Rg8ui, 256 crate::StorageFormat::Rg8Sint => spirv::ImageFormat::Rg8i, 257 crate::StorageFormat::R32Uint => spirv::ImageFormat::R32ui, 258 crate::StorageFormat::R32Sint => spirv::ImageFormat::R32i, 259 crate::StorageFormat::R32Float => spirv::ImageFormat::R32f, 260 crate::StorageFormat::Rg16Uint => spirv::ImageFormat::Rg16ui, 261 crate::StorageFormat::Rg16Sint => spirv::ImageFormat::Rg16i, 262 crate::StorageFormat::Rg16Float => spirv::ImageFormat::Rg16f, 263 crate::StorageFormat::Rgba8Unorm => spirv::ImageFormat::Rgba8, 264 crate::StorageFormat::Rgba8Snorm => spirv::ImageFormat::Rgba8Snorm, 265 crate::StorageFormat::Rgba8Uint => spirv::ImageFormat::Rgba8ui, 266 crate::StorageFormat::Rgba8Sint => spirv::ImageFormat::Rgba8i, 267 crate::StorageFormat::Rgb10a2Unorm => spirv::ImageFormat::Rgb10a2ui, 268 crate::StorageFormat::Rg11b10Float => spirv::ImageFormat::R11fG11fB10f, 269 crate::StorageFormat::Rg32Uint => spirv::ImageFormat::Rg32ui, 270 crate::StorageFormat::Rg32Sint => spirv::ImageFormat::Rg32i, 271 crate::StorageFormat::Rg32Float => spirv::ImageFormat::Rg32f, 272 crate::StorageFormat::Rgba16Uint => spirv::ImageFormat::Rgba16ui, 273 crate::StorageFormat::Rgba16Sint => spirv::ImageFormat::Rgba16i, 274 crate::StorageFormat::Rgba16Float => spirv::ImageFormat::Rgba16f, 275 crate::StorageFormat::Rgba32Uint => spirv::ImageFormat::Rgba32ui, 276 crate::StorageFormat::Rgba32Sint => spirv::ImageFormat::Rgba32i, 277 crate::StorageFormat::Rgba32Float => spirv::ImageFormat::Rgba32f, 278 }, 279 _ => spirv::ImageFormat::Unknown, 280 }; 281 282 instruction.add_operand(format as u32); 283 instruction 284 } 285 type_sampler(id: Word) -> Self286 pub(super) fn type_sampler(id: Word) -> Self { 287 let mut instruction = Self::new(Op::TypeSampler); 288 instruction.set_result(id); 289 instruction 290 } 291 type_sampled_image(id: Word, image_type_id: Word) -> Self292 pub(super) fn type_sampled_image(id: Word, image_type_id: Word) -> Self { 293 let mut instruction = Self::new(Op::TypeSampledImage); 294 instruction.set_result(id); 295 instruction.add_operand(image_type_id); 296 instruction 297 } 298 type_array(id: Word, element_type_id: Word, length_id: Word) -> Self299 pub(super) fn type_array(id: Word, element_type_id: Word, length_id: Word) -> Self { 300 let mut instruction = Self::new(Op::TypeArray); 301 instruction.set_result(id); 302 instruction.add_operand(element_type_id); 303 instruction.add_operand(length_id); 304 instruction 305 } 306 type_runtime_array(id: Word, element_type_id: Word) -> Self307 pub(super) fn type_runtime_array(id: Word, element_type_id: Word) -> Self { 308 let mut instruction = Self::new(Op::TypeRuntimeArray); 309 instruction.set_result(id); 310 instruction.add_operand(element_type_id); 311 instruction 312 } 313 type_struct(id: Word, member_ids: &[Word]) -> Self314 pub(super) fn type_struct(id: Word, member_ids: &[Word]) -> Self { 315 let mut instruction = Self::new(Op::TypeStruct); 316 instruction.set_result(id); 317 318 for member_id in member_ids { 319 instruction.add_operand(*member_id) 320 } 321 322 instruction 323 } 324 type_pointer( id: Word, storage_class: spirv::StorageClass, type_id: Word, ) -> Self325 pub(super) fn type_pointer( 326 id: Word, 327 storage_class: spirv::StorageClass, 328 type_id: Word, 329 ) -> Self { 330 let mut instruction = Self::new(Op::TypePointer); 331 instruction.set_result(id); 332 instruction.add_operand(storage_class as u32); 333 instruction.add_operand(type_id); 334 instruction 335 } 336 type_function(id: Word, return_type_id: Word, parameter_ids: &[Word]) -> Self337 pub(super) fn type_function(id: Word, return_type_id: Word, parameter_ids: &[Word]) -> Self { 338 let mut instruction = Self::new(Op::TypeFunction); 339 instruction.set_result(id); 340 instruction.add_operand(return_type_id); 341 342 for parameter_id in parameter_ids { 343 instruction.add_operand(*parameter_id); 344 } 345 346 instruction 347 } 348 349 // 350 // Constant-Creation Instructions 351 // 352 constant_null(result_type_id: Word, id: Word) -> Self353 pub(super) fn constant_null(result_type_id: Word, id: Word) -> Self { 354 let mut instruction = Self::new(Op::ConstantNull); 355 instruction.set_type(result_type_id); 356 instruction.set_result(id); 357 instruction 358 } 359 constant_true(result_type_id: Word, id: Word) -> Self360 pub(super) fn constant_true(result_type_id: Word, id: Word) -> Self { 361 let mut instruction = Self::new(Op::ConstantTrue); 362 instruction.set_type(result_type_id); 363 instruction.set_result(id); 364 instruction 365 } 366 constant_false(result_type_id: Word, id: Word) -> Self367 pub(super) fn constant_false(result_type_id: Word, id: Word) -> Self { 368 let mut instruction = Self::new(Op::ConstantFalse); 369 instruction.set_type(result_type_id); 370 instruction.set_result(id); 371 instruction 372 } 373 constant(result_type_id: Word, id: Word, values: &[Word]) -> Self374 pub(super) fn constant(result_type_id: Word, id: Word, values: &[Word]) -> Self { 375 let mut instruction = Self::new(Op::Constant); 376 instruction.set_type(result_type_id); 377 instruction.set_result(id); 378 379 for value in values { 380 instruction.add_operand(*value); 381 } 382 383 instruction 384 } 385 constant_composite( result_type_id: Word, id: Word, constituent_ids: &[Word], ) -> Self386 pub(super) fn constant_composite( 387 result_type_id: Word, 388 id: Word, 389 constituent_ids: &[Word], 390 ) -> Self { 391 let mut instruction = Self::new(Op::ConstantComposite); 392 instruction.set_type(result_type_id); 393 instruction.set_result(id); 394 395 for constituent_id in constituent_ids { 396 instruction.add_operand(*constituent_id); 397 } 398 399 instruction 400 } 401 402 // 403 // Memory Instructions 404 // 405 variable( result_type_id: Word, id: Word, storage_class: spirv::StorageClass, initializer_id: Option<Word>, ) -> Self406 pub(super) fn variable( 407 result_type_id: Word, 408 id: Word, 409 storage_class: spirv::StorageClass, 410 initializer_id: Option<Word>, 411 ) -> Self { 412 let mut instruction = Self::new(Op::Variable); 413 instruction.set_type(result_type_id); 414 instruction.set_result(id); 415 instruction.add_operand(storage_class as u32); 416 417 if let Some(initializer_id) = initializer_id { 418 instruction.add_operand(initializer_id); 419 } 420 421 instruction 422 } 423 load( result_type_id: Word, id: Word, pointer_id: Word, memory_access: Option<spirv::MemoryAccess>, ) -> Self424 pub(super) fn load( 425 result_type_id: Word, 426 id: Word, 427 pointer_id: Word, 428 memory_access: Option<spirv::MemoryAccess>, 429 ) -> Self { 430 let mut instruction = Self::new(Op::Load); 431 instruction.set_type(result_type_id); 432 instruction.set_result(id); 433 instruction.add_operand(pointer_id); 434 435 if let Some(memory_access) = memory_access { 436 instruction.add_operand(memory_access.bits()); 437 } 438 439 instruction 440 } 441 store( pointer_id: Word, object_id: Word, memory_access: Option<spirv::MemoryAccess>, ) -> Self442 pub(super) fn store( 443 pointer_id: Word, 444 object_id: Word, 445 memory_access: Option<spirv::MemoryAccess>, 446 ) -> Self { 447 let mut instruction = Self::new(Op::Store); 448 instruction.add_operand(pointer_id); 449 instruction.add_operand(object_id); 450 451 if let Some(memory_access) = memory_access { 452 instruction.add_operand(memory_access.bits()); 453 } 454 455 instruction 456 } 457 access_chain( result_type_id: Word, id: Word, base_id: Word, index_ids: &[Word], ) -> Self458 pub(super) fn access_chain( 459 result_type_id: Word, 460 id: Word, 461 base_id: Word, 462 index_ids: &[Word], 463 ) -> Self { 464 let mut instruction = Self::new(Op::AccessChain); 465 instruction.set_type(result_type_id); 466 instruction.set_result(id); 467 instruction.add_operand(base_id); 468 469 for index_id in index_ids { 470 instruction.add_operand(*index_id); 471 } 472 473 instruction 474 } 475 array_length( result_type_id: Word, id: Word, structure_id: Word, array_member: Word, ) -> Self476 pub(super) fn array_length( 477 result_type_id: Word, 478 id: Word, 479 structure_id: Word, 480 array_member: Word, 481 ) -> Self { 482 let mut instruction = Self::new(Op::ArrayLength); 483 instruction.set_type(result_type_id); 484 instruction.set_result(id); 485 instruction.add_operand(structure_id); 486 instruction.add_operand(array_member); 487 instruction 488 } 489 490 // 491 // Function Instructions 492 // 493 function( return_type_id: Word, id: Word, function_control: spirv::FunctionControl, function_type_id: Word, ) -> Self494 pub(super) fn function( 495 return_type_id: Word, 496 id: Word, 497 function_control: spirv::FunctionControl, 498 function_type_id: Word, 499 ) -> Self { 500 let mut instruction = Self::new(Op::Function); 501 instruction.set_type(return_type_id); 502 instruction.set_result(id); 503 instruction.add_operand(function_control.bits()); 504 instruction.add_operand(function_type_id); 505 instruction 506 } 507 function_parameter(result_type_id: Word, id: Word) -> Self508 pub(super) fn function_parameter(result_type_id: Word, id: Word) -> Self { 509 let mut instruction = Self::new(Op::FunctionParameter); 510 instruction.set_type(result_type_id); 511 instruction.set_result(id); 512 instruction 513 } 514 function_end() -> Self515 pub(super) fn function_end() -> Self { 516 Self::new(Op::FunctionEnd) 517 } 518 function_call( result_type_id: Word, id: Word, function_id: Word, argument_ids: &[Word], ) -> Self519 pub(super) fn function_call( 520 result_type_id: Word, 521 id: Word, 522 function_id: Word, 523 argument_ids: &[Word], 524 ) -> Self { 525 let mut instruction = Self::new(Op::FunctionCall); 526 instruction.set_type(result_type_id); 527 instruction.set_result(id); 528 instruction.add_operand(function_id); 529 530 for argument_id in argument_ids { 531 instruction.add_operand(*argument_id); 532 } 533 534 instruction 535 } 536 537 // 538 // Image Instructions 539 // 540 sampled_image( result_type_id: Word, id: Word, image: Word, sampler: Word, ) -> Self541 pub(super) fn sampled_image( 542 result_type_id: Word, 543 id: Word, 544 image: Word, 545 sampler: Word, 546 ) -> Self { 547 let mut instruction = Self::new(Op::SampledImage); 548 instruction.set_type(result_type_id); 549 instruction.set_result(id); 550 instruction.add_operand(image); 551 instruction.add_operand(sampler); 552 instruction 553 } 554 image_sample( result_type_id: Word, id: Word, lod: SampleLod, sampled_image: Word, coordinates: Word, depth_ref: Option<Word>, ) -> Self555 pub(super) fn image_sample( 556 result_type_id: Word, 557 id: Word, 558 lod: SampleLod, 559 sampled_image: Word, 560 coordinates: Word, 561 depth_ref: Option<Word>, 562 ) -> Self { 563 let op = match (lod, depth_ref) { 564 (SampleLod::Explicit, None) => Op::ImageSampleExplicitLod, 565 (SampleLod::Implicit, None) => Op::ImageSampleImplicitLod, 566 (SampleLod::Explicit, Some(_)) => Op::ImageSampleDrefExplicitLod, 567 (SampleLod::Implicit, Some(_)) => Op::ImageSampleDrefImplicitLod, 568 }; 569 570 let mut instruction = Self::new(op); 571 instruction.set_type(result_type_id); 572 instruction.set_result(id); 573 instruction.add_operand(sampled_image); 574 instruction.add_operand(coordinates); 575 if let Some(dref) = depth_ref { 576 instruction.add_operand(dref); 577 } 578 579 instruction 580 } 581 image_fetch( result_type_id: Word, id: Word, image: Word, coordinates: Word, ) -> Self582 pub(super) fn image_fetch( 583 result_type_id: Word, 584 id: Word, 585 image: Word, 586 coordinates: Word, 587 ) -> Self { 588 let mut instruction = Self::new(Op::ImageFetch); 589 instruction.set_type(result_type_id); 590 instruction.set_result(id); 591 instruction.add_operand(image); 592 instruction.add_operand(coordinates); 593 instruction 594 } 595 image_read( result_type_id: Word, id: Word, image: Word, coordinates: Word, ) -> Self596 pub(super) fn image_read( 597 result_type_id: Word, 598 id: Word, 599 image: Word, 600 coordinates: Word, 601 ) -> Self { 602 let mut instruction = Self::new(Op::ImageRead); 603 instruction.set_type(result_type_id); 604 instruction.set_result(id); 605 instruction.add_operand(image); 606 instruction.add_operand(coordinates); 607 instruction 608 } 609 image_write(image: Word, coordinates: Word, value: Word) -> Self610 pub(super) fn image_write(image: Word, coordinates: Word, value: Word) -> Self { 611 let mut instruction = Self::new(Op::ImageWrite); 612 instruction.add_operand(image); 613 instruction.add_operand(coordinates); 614 instruction.add_operand(value); 615 instruction 616 } 617 image_query(op: Op, result_type_id: Word, id: Word, image: Word) -> Self618 pub(super) fn image_query(op: Op, result_type_id: Word, id: Word, image: Word) -> Self { 619 let mut instruction = Self::new(op); 620 instruction.set_type(result_type_id); 621 instruction.set_result(id); 622 instruction.add_operand(image); 623 instruction 624 } 625 626 // 627 // Conversion Instructions 628 // unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Self629 pub(super) fn unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Self { 630 let mut instruction = Self::new(op); 631 instruction.set_type(result_type_id); 632 instruction.set_result(id); 633 instruction.add_operand(value); 634 instruction 635 } 636 637 // 638 // Composite Instructions 639 // 640 composite_construct( result_type_id: Word, id: Word, constituent_ids: &[Word], ) -> Self641 pub(super) fn composite_construct( 642 result_type_id: Word, 643 id: Word, 644 constituent_ids: &[Word], 645 ) -> Self { 646 let mut instruction = Self::new(Op::CompositeConstruct); 647 instruction.set_type(result_type_id); 648 instruction.set_result(id); 649 650 for constituent_id in constituent_ids { 651 instruction.add_operand(*constituent_id); 652 } 653 654 instruction 655 } 656 composite_extract( result_type_id: Word, id: Word, composite_id: Word, indices: &[Word], ) -> Self657 pub(super) fn composite_extract( 658 result_type_id: Word, 659 id: Word, 660 composite_id: Word, 661 indices: &[Word], 662 ) -> Self { 663 let mut instruction = Self::new(Op::CompositeExtract); 664 instruction.set_type(result_type_id); 665 instruction.set_result(id); 666 667 instruction.add_operand(composite_id); 668 for index in indices { 669 instruction.add_operand(*index); 670 } 671 672 instruction 673 } 674 vector_extract_dynamic( result_type_id: Word, id: Word, vector_id: Word, index_id: Word, ) -> Self675 pub(super) fn vector_extract_dynamic( 676 result_type_id: Word, 677 id: Word, 678 vector_id: Word, 679 index_id: Word, 680 ) -> Self { 681 let mut instruction = Self::new(Op::VectorExtractDynamic); 682 instruction.set_type(result_type_id); 683 instruction.set_result(id); 684 685 instruction.add_operand(vector_id); 686 instruction.add_operand(index_id); 687 688 instruction 689 } 690 vector_shuffle( result_type_id: Word, id: Word, v1_id: Word, v2_id: Word, components: &[Word], ) -> Self691 pub(super) fn vector_shuffle( 692 result_type_id: Word, 693 id: Word, 694 v1_id: Word, 695 v2_id: Word, 696 components: &[Word], 697 ) -> Self { 698 let mut instruction = Self::new(Op::VectorShuffle); 699 instruction.set_type(result_type_id); 700 instruction.set_result(id); 701 instruction.add_operand(v1_id); 702 instruction.add_operand(v2_id); 703 704 for &component in components { 705 instruction.add_operand(component); 706 } 707 708 instruction 709 } 710 711 // 712 // Arithmetic Instructions 713 // binary( op: Op, result_type_id: Word, id: Word, operand_1: Word, operand_2: Word, ) -> Self714 pub(super) fn binary( 715 op: Op, 716 result_type_id: Word, 717 id: Word, 718 operand_1: Word, 719 operand_2: Word, 720 ) -> Self { 721 let mut instruction = Self::new(op); 722 instruction.set_type(result_type_id); 723 instruction.set_result(id); 724 instruction.add_operand(operand_1); 725 instruction.add_operand(operand_2); 726 instruction 727 } 728 relational(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self729 pub(super) fn relational(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self { 730 let mut instruction = Self::new(op); 731 instruction.set_type(result_type_id); 732 instruction.set_result(id); 733 instruction.add_operand(expr_id); 734 instruction 735 } 736 737 // 738 // Bit Instructions 739 // 740 741 // 742 // Relational and Logical Instructions 743 // 744 745 // 746 // Derivative Instructions 747 // 748 derivative(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self749 pub(super) fn derivative(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self { 750 let mut instruction = Self::new(op); 751 instruction.set_type(result_type_id); 752 instruction.set_result(id); 753 instruction.add_operand(expr_id); 754 instruction 755 } 756 757 // 758 // Control-Flow Instructions 759 // 760 selection_merge( merge_id: Word, selection_control: spirv::SelectionControl, ) -> Self761 pub(super) fn selection_merge( 762 merge_id: Word, 763 selection_control: spirv::SelectionControl, 764 ) -> Self { 765 let mut instruction = Self::new(Op::SelectionMerge); 766 instruction.add_operand(merge_id); 767 instruction.add_operand(selection_control.bits()); 768 instruction 769 } 770 loop_merge( merge_id: Word, continuing_id: Word, selection_control: spirv::SelectionControl, ) -> Self771 pub(super) fn loop_merge( 772 merge_id: Word, 773 continuing_id: Word, 774 selection_control: spirv::SelectionControl, 775 ) -> Self { 776 let mut instruction = Self::new(Op::LoopMerge); 777 instruction.add_operand(merge_id); 778 instruction.add_operand(continuing_id); 779 instruction.add_operand(selection_control.bits()); 780 instruction 781 } 782 label(id: Word) -> Self783 pub(super) fn label(id: Word) -> Self { 784 let mut instruction = Self::new(Op::Label); 785 instruction.set_result(id); 786 instruction 787 } 788 branch(id: Word) -> Self789 pub(super) fn branch(id: Word) -> Self { 790 let mut instruction = Self::new(Op::Branch); 791 instruction.add_operand(id); 792 instruction 793 } 794 795 // TODO Branch Weights not implemented. branch_conditional( condition_id: Word, true_label: Word, false_label: Word, ) -> Self796 pub(super) fn branch_conditional( 797 condition_id: Word, 798 true_label: Word, 799 false_label: Word, 800 ) -> Self { 801 let mut instruction = Self::new(Op::BranchConditional); 802 instruction.add_operand(condition_id); 803 instruction.add_operand(true_label); 804 instruction.add_operand(false_label); 805 instruction 806 } 807 switch(selector_id: Word, default_id: Word, cases: &[Case]) -> Self808 pub(super) fn switch(selector_id: Word, default_id: Word, cases: &[Case]) -> Self { 809 let mut instruction = Self::new(Op::Switch); 810 instruction.add_operand(selector_id); 811 instruction.add_operand(default_id); 812 for case in cases { 813 instruction.add_operand(case.value); 814 instruction.add_operand(case.label_id); 815 } 816 instruction 817 } 818 select( result_type_id: Word, id: Word, condition_id: Word, accept_id: Word, reject_id: Word, ) -> Self819 pub(super) fn select( 820 result_type_id: Word, 821 id: Word, 822 condition_id: Word, 823 accept_id: Word, 824 reject_id: Word, 825 ) -> Self { 826 let mut instruction = Self::new(Op::Select); 827 instruction.add_operand(result_type_id); 828 instruction.add_operand(id); 829 instruction.add_operand(condition_id); 830 instruction.add_operand(accept_id); 831 instruction.add_operand(reject_id); 832 instruction 833 } 834 kill() -> Self835 pub(super) fn kill() -> Self { 836 Self::new(Op::Kill) 837 } 838 return_void() -> Self839 pub(super) fn return_void() -> Self { 840 Self::new(Op::Return) 841 } 842 return_value(value_id: Word) -> Self843 pub(super) fn return_value(value_id: Word) -> Self { 844 let mut instruction = Self::new(Op::ReturnValue); 845 instruction.add_operand(value_id); 846 instruction 847 } 848 849 // 850 // Atomic Instructions 851 // 852 853 // 854 // Primitive Instructions 855 // 856 857 // Barriers 858 control_barrier( exec_scope_id: Word, mem_scope_id: Word, semantics_id: Word, ) -> Self859 pub(super) fn control_barrier( 860 exec_scope_id: Word, 861 mem_scope_id: Word, 862 semantics_id: Word, 863 ) -> Self { 864 let mut instruction = Self::new(Op::ControlBarrier); 865 instruction.add_operand(exec_scope_id); 866 instruction.add_operand(mem_scope_id); 867 instruction.add_operand(semantics_id); 868 instruction 869 } 870 } 871