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 222 #[allow(clippy::too_many_arguments)] type_image( id: Word, sampled_type_id: Word, dim: spirv::Dim, flags: super::ImageTypeFlags, image_format: spirv::ImageFormat, ) -> Self223 pub(super) fn type_image( 224 id: Word, 225 sampled_type_id: Word, 226 dim: spirv::Dim, 227 flags: super::ImageTypeFlags, 228 image_format: spirv::ImageFormat, 229 ) -> Self { 230 let mut instruction = Self::new(Op::TypeImage); 231 instruction.set_result(id); 232 instruction.add_operand(sampled_type_id); 233 instruction.add_operand(dim as u32); 234 instruction.add_operand(flags.contains(super::ImageTypeFlags::DEPTH) as u32); 235 instruction.add_operand(flags.contains(super::ImageTypeFlags::ARRAYED) as u32); 236 instruction.add_operand(flags.contains(super::ImageTypeFlags::MULTISAMPLED) as u32); 237 instruction.add_operand(if flags.contains(super::ImageTypeFlags::SAMPLED) { 238 1 239 } else { 240 2 241 }); 242 instruction.add_operand(image_format as u32); 243 instruction 244 } 245 type_sampler(id: Word) -> Self246 pub(super) fn type_sampler(id: Word) -> Self { 247 let mut instruction = Self::new(Op::TypeSampler); 248 instruction.set_result(id); 249 instruction 250 } 251 type_sampled_image(id: Word, image_type_id: Word) -> Self252 pub(super) fn type_sampled_image(id: Word, image_type_id: Word) -> Self { 253 let mut instruction = Self::new(Op::TypeSampledImage); 254 instruction.set_result(id); 255 instruction.add_operand(image_type_id); 256 instruction 257 } 258 type_array(id: Word, element_type_id: Word, length_id: Word) -> Self259 pub(super) fn type_array(id: Word, element_type_id: Word, length_id: Word) -> Self { 260 let mut instruction = Self::new(Op::TypeArray); 261 instruction.set_result(id); 262 instruction.add_operand(element_type_id); 263 instruction.add_operand(length_id); 264 instruction 265 } 266 type_runtime_array(id: Word, element_type_id: Word) -> Self267 pub(super) fn type_runtime_array(id: Word, element_type_id: Word) -> Self { 268 let mut instruction = Self::new(Op::TypeRuntimeArray); 269 instruction.set_result(id); 270 instruction.add_operand(element_type_id); 271 instruction 272 } 273 type_struct(id: Word, member_ids: &[Word]) -> Self274 pub(super) fn type_struct(id: Word, member_ids: &[Word]) -> Self { 275 let mut instruction = Self::new(Op::TypeStruct); 276 instruction.set_result(id); 277 278 for member_id in member_ids { 279 instruction.add_operand(*member_id) 280 } 281 282 instruction 283 } 284 type_pointer( id: Word, storage_class: spirv::StorageClass, type_id: Word, ) -> Self285 pub(super) fn type_pointer( 286 id: Word, 287 storage_class: spirv::StorageClass, 288 type_id: Word, 289 ) -> Self { 290 let mut instruction = Self::new(Op::TypePointer); 291 instruction.set_result(id); 292 instruction.add_operand(storage_class as u32); 293 instruction.add_operand(type_id); 294 instruction 295 } 296 type_function(id: Word, return_type_id: Word, parameter_ids: &[Word]) -> Self297 pub(super) fn type_function(id: Word, return_type_id: Word, parameter_ids: &[Word]) -> Self { 298 let mut instruction = Self::new(Op::TypeFunction); 299 instruction.set_result(id); 300 instruction.add_operand(return_type_id); 301 302 for parameter_id in parameter_ids { 303 instruction.add_operand(*parameter_id); 304 } 305 306 instruction 307 } 308 309 // 310 // Constant-Creation Instructions 311 // 312 constant_null(result_type_id: Word, id: Word) -> Self313 pub(super) fn constant_null(result_type_id: Word, id: Word) -> Self { 314 let mut instruction = Self::new(Op::ConstantNull); 315 instruction.set_type(result_type_id); 316 instruction.set_result(id); 317 instruction 318 } 319 constant_true(result_type_id: Word, id: Word) -> Self320 pub(super) fn constant_true(result_type_id: Word, id: Word) -> Self { 321 let mut instruction = Self::new(Op::ConstantTrue); 322 instruction.set_type(result_type_id); 323 instruction.set_result(id); 324 instruction 325 } 326 constant_false(result_type_id: Word, id: Word) -> Self327 pub(super) fn constant_false(result_type_id: Word, id: Word) -> Self { 328 let mut instruction = Self::new(Op::ConstantFalse); 329 instruction.set_type(result_type_id); 330 instruction.set_result(id); 331 instruction 332 } 333 constant(result_type_id: Word, id: Word, values: &[Word]) -> Self334 pub(super) fn constant(result_type_id: Word, id: Word, values: &[Word]) -> Self { 335 let mut instruction = Self::new(Op::Constant); 336 instruction.set_type(result_type_id); 337 instruction.set_result(id); 338 339 for value in values { 340 instruction.add_operand(*value); 341 } 342 343 instruction 344 } 345 constant_composite( result_type_id: Word, id: Word, constituent_ids: &[Word], ) -> Self346 pub(super) fn constant_composite( 347 result_type_id: Word, 348 id: Word, 349 constituent_ids: &[Word], 350 ) -> Self { 351 let mut instruction = Self::new(Op::ConstantComposite); 352 instruction.set_type(result_type_id); 353 instruction.set_result(id); 354 355 for constituent_id in constituent_ids { 356 instruction.add_operand(*constituent_id); 357 } 358 359 instruction 360 } 361 362 // 363 // Memory Instructions 364 // 365 variable( result_type_id: Word, id: Word, storage_class: spirv::StorageClass, initializer_id: Option<Word>, ) -> Self366 pub(super) fn variable( 367 result_type_id: Word, 368 id: Word, 369 storage_class: spirv::StorageClass, 370 initializer_id: Option<Word>, 371 ) -> Self { 372 let mut instruction = Self::new(Op::Variable); 373 instruction.set_type(result_type_id); 374 instruction.set_result(id); 375 instruction.add_operand(storage_class as u32); 376 377 if let Some(initializer_id) = initializer_id { 378 instruction.add_operand(initializer_id); 379 } 380 381 instruction 382 } 383 load( result_type_id: Word, id: Word, pointer_id: Word, memory_access: Option<spirv::MemoryAccess>, ) -> Self384 pub(super) fn load( 385 result_type_id: Word, 386 id: Word, 387 pointer_id: Word, 388 memory_access: Option<spirv::MemoryAccess>, 389 ) -> Self { 390 let mut instruction = Self::new(Op::Load); 391 instruction.set_type(result_type_id); 392 instruction.set_result(id); 393 instruction.add_operand(pointer_id); 394 395 if let Some(memory_access) = memory_access { 396 instruction.add_operand(memory_access.bits()); 397 } 398 399 instruction 400 } 401 atomic_load( result_type_id: Word, id: Word, pointer_id: Word, scope_id: Word, semantics_id: Word, ) -> Self402 pub(super) fn atomic_load( 403 result_type_id: Word, 404 id: Word, 405 pointer_id: Word, 406 scope_id: Word, 407 semantics_id: Word, 408 ) -> Self { 409 let mut instruction = Self::new(Op::AtomicLoad); 410 instruction.set_type(result_type_id); 411 instruction.set_result(id); 412 instruction.add_operand(pointer_id); 413 instruction.add_operand(scope_id); 414 instruction.add_operand(semantics_id); 415 instruction 416 } 417 store( pointer_id: Word, value_id: Word, memory_access: Option<spirv::MemoryAccess>, ) -> Self418 pub(super) fn store( 419 pointer_id: Word, 420 value_id: Word, 421 memory_access: Option<spirv::MemoryAccess>, 422 ) -> Self { 423 let mut instruction = Self::new(Op::Store); 424 instruction.add_operand(pointer_id); 425 instruction.add_operand(value_id); 426 427 if let Some(memory_access) = memory_access { 428 instruction.add_operand(memory_access.bits()); 429 } 430 431 instruction 432 } 433 atomic_store( pointer_id: Word, scope_id: Word, semantics_id: Word, value_id: Word, ) -> Self434 pub(super) fn atomic_store( 435 pointer_id: Word, 436 scope_id: Word, 437 semantics_id: Word, 438 value_id: Word, 439 ) -> Self { 440 let mut instruction = Self::new(Op::AtomicStore); 441 instruction.add_operand(pointer_id); 442 instruction.add_operand(scope_id); 443 instruction.add_operand(semantics_id); 444 instruction.add_operand(value_id); 445 instruction 446 } 447 access_chain( result_type_id: Word, id: Word, base_id: Word, index_ids: &[Word], ) -> Self448 pub(super) fn access_chain( 449 result_type_id: Word, 450 id: Word, 451 base_id: Word, 452 index_ids: &[Word], 453 ) -> Self { 454 let mut instruction = Self::new(Op::AccessChain); 455 instruction.set_type(result_type_id); 456 instruction.set_result(id); 457 instruction.add_operand(base_id); 458 459 for index_id in index_ids { 460 instruction.add_operand(*index_id); 461 } 462 463 instruction 464 } 465 array_length( result_type_id: Word, id: Word, structure_id: Word, array_member: Word, ) -> Self466 pub(super) fn array_length( 467 result_type_id: Word, 468 id: Word, 469 structure_id: Word, 470 array_member: Word, 471 ) -> Self { 472 let mut instruction = Self::new(Op::ArrayLength); 473 instruction.set_type(result_type_id); 474 instruction.set_result(id); 475 instruction.add_operand(structure_id); 476 instruction.add_operand(array_member); 477 instruction 478 } 479 480 // 481 // Function Instructions 482 // 483 function( return_type_id: Word, id: Word, function_control: spirv::FunctionControl, function_type_id: Word, ) -> Self484 pub(super) fn function( 485 return_type_id: Word, 486 id: Word, 487 function_control: spirv::FunctionControl, 488 function_type_id: Word, 489 ) -> Self { 490 let mut instruction = Self::new(Op::Function); 491 instruction.set_type(return_type_id); 492 instruction.set_result(id); 493 instruction.add_operand(function_control.bits()); 494 instruction.add_operand(function_type_id); 495 instruction 496 } 497 function_parameter(result_type_id: Word, id: Word) -> Self498 pub(super) fn function_parameter(result_type_id: Word, id: Word) -> Self { 499 let mut instruction = Self::new(Op::FunctionParameter); 500 instruction.set_type(result_type_id); 501 instruction.set_result(id); 502 instruction 503 } 504 function_end() -> Self505 pub(super) fn function_end() -> Self { 506 Self::new(Op::FunctionEnd) 507 } 508 function_call( result_type_id: Word, id: Word, function_id: Word, argument_ids: &[Word], ) -> Self509 pub(super) fn function_call( 510 result_type_id: Word, 511 id: Word, 512 function_id: Word, 513 argument_ids: &[Word], 514 ) -> Self { 515 let mut instruction = Self::new(Op::FunctionCall); 516 instruction.set_type(result_type_id); 517 instruction.set_result(id); 518 instruction.add_operand(function_id); 519 520 for argument_id in argument_ids { 521 instruction.add_operand(*argument_id); 522 } 523 524 instruction 525 } 526 527 // 528 // Image Instructions 529 // 530 sampled_image( result_type_id: Word, id: Word, image: Word, sampler: Word, ) -> Self531 pub(super) fn sampled_image( 532 result_type_id: Word, 533 id: Word, 534 image: Word, 535 sampler: Word, 536 ) -> Self { 537 let mut instruction = Self::new(Op::SampledImage); 538 instruction.set_type(result_type_id); 539 instruction.set_result(id); 540 instruction.add_operand(image); 541 instruction.add_operand(sampler); 542 instruction 543 } 544 image_sample( result_type_id: Word, id: Word, lod: SampleLod, sampled_image: Word, coordinates: Word, depth_ref: Option<Word>, ) -> Self545 pub(super) fn image_sample( 546 result_type_id: Word, 547 id: Word, 548 lod: SampleLod, 549 sampled_image: Word, 550 coordinates: Word, 551 depth_ref: Option<Word>, 552 ) -> Self { 553 let op = match (lod, depth_ref) { 554 (SampleLod::Explicit, None) => Op::ImageSampleExplicitLod, 555 (SampleLod::Implicit, None) => Op::ImageSampleImplicitLod, 556 (SampleLod::Explicit, Some(_)) => Op::ImageSampleDrefExplicitLod, 557 (SampleLod::Implicit, Some(_)) => Op::ImageSampleDrefImplicitLod, 558 }; 559 560 let mut instruction = Self::new(op); 561 instruction.set_type(result_type_id); 562 instruction.set_result(id); 563 instruction.add_operand(sampled_image); 564 instruction.add_operand(coordinates); 565 if let Some(dref) = depth_ref { 566 instruction.add_operand(dref); 567 } 568 569 instruction 570 } 571 image_gather( result_type_id: Word, id: Word, sampled_image: Word, coordinates: Word, component_id: Word, depth_ref: Option<Word>, ) -> Self572 pub(super) fn image_gather( 573 result_type_id: Word, 574 id: Word, 575 sampled_image: Word, 576 coordinates: Word, 577 component_id: Word, 578 depth_ref: Option<Word>, 579 ) -> Self { 580 let op = match depth_ref { 581 None => Op::ImageGather, 582 Some(_) => Op::ImageDrefGather, 583 }; 584 585 let mut instruction = Self::new(op); 586 instruction.set_type(result_type_id); 587 instruction.set_result(id); 588 instruction.add_operand(sampled_image); 589 instruction.add_operand(coordinates); 590 if let Some(dref) = depth_ref { 591 instruction.add_operand(dref); 592 } else { 593 instruction.add_operand(component_id); 594 } 595 596 instruction 597 } 598 image_fetch_or_read( op: Op, result_type_id: Word, id: Word, image: Word, coordinates: Word, ) -> Self599 pub(super) fn image_fetch_or_read( 600 op: Op, 601 result_type_id: Word, 602 id: Word, 603 image: Word, 604 coordinates: Word, 605 ) -> Self { 606 let mut instruction = Self::new(op); 607 instruction.set_type(result_type_id); 608 instruction.set_result(id); 609 instruction.add_operand(image); 610 instruction.add_operand(coordinates); 611 instruction 612 } 613 image_write(image: Word, coordinates: Word, value: Word) -> Self614 pub(super) fn image_write(image: Word, coordinates: Word, value: Word) -> Self { 615 let mut instruction = Self::new(Op::ImageWrite); 616 instruction.add_operand(image); 617 instruction.add_operand(coordinates); 618 instruction.add_operand(value); 619 instruction 620 } 621 image_query(op: Op, result_type_id: Word, id: Word, image: Word) -> Self622 pub(super) fn image_query(op: Op, result_type_id: Word, id: Word, image: Word) -> Self { 623 let mut instruction = Self::new(op); 624 instruction.set_type(result_type_id); 625 instruction.set_result(id); 626 instruction.add_operand(image); 627 instruction 628 } 629 630 // 631 // Conversion Instructions 632 // unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Self633 pub(super) fn unary(op: Op, result_type_id: Word, id: Word, value: Word) -> Self { 634 let mut instruction = Self::new(op); 635 instruction.set_type(result_type_id); 636 instruction.set_result(id); 637 instruction.add_operand(value); 638 instruction 639 } 640 641 // 642 // Composite Instructions 643 // 644 composite_construct( result_type_id: Word, id: Word, constituent_ids: &[Word], ) -> Self645 pub(super) fn composite_construct( 646 result_type_id: Word, 647 id: Word, 648 constituent_ids: &[Word], 649 ) -> Self { 650 let mut instruction = Self::new(Op::CompositeConstruct); 651 instruction.set_type(result_type_id); 652 instruction.set_result(id); 653 654 for constituent_id in constituent_ids { 655 instruction.add_operand(*constituent_id); 656 } 657 658 instruction 659 } 660 composite_extract( result_type_id: Word, id: Word, composite_id: Word, indices: &[Word], ) -> Self661 pub(super) fn composite_extract( 662 result_type_id: Word, 663 id: Word, 664 composite_id: Word, 665 indices: &[Word], 666 ) -> Self { 667 let mut instruction = Self::new(Op::CompositeExtract); 668 instruction.set_type(result_type_id); 669 instruction.set_result(id); 670 671 instruction.add_operand(composite_id); 672 for index in indices { 673 instruction.add_operand(*index); 674 } 675 676 instruction 677 } 678 vector_extract_dynamic( result_type_id: Word, id: Word, vector_id: Word, index_id: Word, ) -> Self679 pub(super) fn vector_extract_dynamic( 680 result_type_id: Word, 681 id: Word, 682 vector_id: Word, 683 index_id: Word, 684 ) -> Self { 685 let mut instruction = Self::new(Op::VectorExtractDynamic); 686 instruction.set_type(result_type_id); 687 instruction.set_result(id); 688 689 instruction.add_operand(vector_id); 690 instruction.add_operand(index_id); 691 692 instruction 693 } 694 vector_shuffle( result_type_id: Word, id: Word, v1_id: Word, v2_id: Word, components: &[Word], ) -> Self695 pub(super) fn vector_shuffle( 696 result_type_id: Word, 697 id: Word, 698 v1_id: Word, 699 v2_id: Word, 700 components: &[Word], 701 ) -> Self { 702 let mut instruction = Self::new(Op::VectorShuffle); 703 instruction.set_type(result_type_id); 704 instruction.set_result(id); 705 instruction.add_operand(v1_id); 706 instruction.add_operand(v2_id); 707 708 for &component in components { 709 instruction.add_operand(component); 710 } 711 712 instruction 713 } 714 715 // 716 // Arithmetic Instructions 717 // binary( op: Op, result_type_id: Word, id: Word, operand_1: Word, operand_2: Word, ) -> Self718 pub(super) fn binary( 719 op: Op, 720 result_type_id: Word, 721 id: Word, 722 operand_1: Word, 723 operand_2: Word, 724 ) -> Self { 725 let mut instruction = Self::new(op); 726 instruction.set_type(result_type_id); 727 instruction.set_result(id); 728 instruction.add_operand(operand_1); 729 instruction.add_operand(operand_2); 730 instruction 731 } 732 ternary( op: Op, result_type_id: Word, id: Word, operand_1: Word, operand_2: Word, operand_3: Word, ) -> Self733 pub(super) fn ternary( 734 op: Op, 735 result_type_id: Word, 736 id: Word, 737 operand_1: Word, 738 operand_2: Word, 739 operand_3: Word, 740 ) -> Self { 741 let mut instruction = Self::new(op); 742 instruction.set_type(result_type_id); 743 instruction.set_result(id); 744 instruction.add_operand(operand_1); 745 instruction.add_operand(operand_2); 746 instruction.add_operand(operand_3); 747 instruction 748 } 749 quaternary( op: Op, result_type_id: Word, id: Word, operand_1: Word, operand_2: Word, operand_3: Word, operand_4: Word, ) -> Self750 pub(super) fn quaternary( 751 op: Op, 752 result_type_id: Word, 753 id: Word, 754 operand_1: Word, 755 operand_2: Word, 756 operand_3: Word, 757 operand_4: Word, 758 ) -> Self { 759 let mut instruction = Self::new(op); 760 instruction.set_type(result_type_id); 761 instruction.set_result(id); 762 instruction.add_operand(operand_1); 763 instruction.add_operand(operand_2); 764 instruction.add_operand(operand_3); 765 instruction.add_operand(operand_4); 766 instruction 767 } 768 relational(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self769 pub(super) fn relational(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self { 770 let mut instruction = Self::new(op); 771 instruction.set_type(result_type_id); 772 instruction.set_result(id); 773 instruction.add_operand(expr_id); 774 instruction 775 } 776 atomic_binary( op: Op, result_type_id: Word, id: Word, pointer: Word, scope_id: Word, semantics_id: Word, value: Word, ) -> Self777 pub(super) fn atomic_binary( 778 op: Op, 779 result_type_id: Word, 780 id: Word, 781 pointer: Word, 782 scope_id: Word, 783 semantics_id: Word, 784 value: Word, 785 ) -> Self { 786 let mut instruction = Self::new(op); 787 instruction.set_type(result_type_id); 788 instruction.set_result(id); 789 instruction.add_operand(pointer); 790 instruction.add_operand(scope_id); 791 instruction.add_operand(semantics_id); 792 instruction.add_operand(value); 793 instruction 794 } 795 796 // 797 // Bit Instructions 798 // 799 800 // 801 // Relational and Logical Instructions 802 // 803 804 // 805 // Derivative Instructions 806 // 807 derivative(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self808 pub(super) fn derivative(op: Op, result_type_id: Word, id: Word, expr_id: Word) -> Self { 809 let mut instruction = Self::new(op); 810 instruction.set_type(result_type_id); 811 instruction.set_result(id); 812 instruction.add_operand(expr_id); 813 instruction 814 } 815 816 // 817 // Control-Flow Instructions 818 // 819 phi( result_type_id: Word, result_id: Word, var_parent_pairs: &[(Word, Word)], ) -> Self820 pub(super) fn phi( 821 result_type_id: Word, 822 result_id: Word, 823 var_parent_pairs: &[(Word, Word)], 824 ) -> Self { 825 let mut instruction = Self::new(Op::Phi); 826 instruction.add_operand(result_type_id); 827 instruction.add_operand(result_id); 828 for &(variable, parent) in var_parent_pairs { 829 instruction.add_operand(variable); 830 instruction.add_operand(parent); 831 } 832 instruction 833 } 834 selection_merge( merge_id: Word, selection_control: spirv::SelectionControl, ) -> Self835 pub(super) fn selection_merge( 836 merge_id: Word, 837 selection_control: spirv::SelectionControl, 838 ) -> Self { 839 let mut instruction = Self::new(Op::SelectionMerge); 840 instruction.add_operand(merge_id); 841 instruction.add_operand(selection_control.bits()); 842 instruction 843 } 844 loop_merge( merge_id: Word, continuing_id: Word, selection_control: spirv::SelectionControl, ) -> Self845 pub(super) fn loop_merge( 846 merge_id: Word, 847 continuing_id: Word, 848 selection_control: spirv::SelectionControl, 849 ) -> Self { 850 let mut instruction = Self::new(Op::LoopMerge); 851 instruction.add_operand(merge_id); 852 instruction.add_operand(continuing_id); 853 instruction.add_operand(selection_control.bits()); 854 instruction 855 } 856 label(id: Word) -> Self857 pub(super) fn label(id: Word) -> Self { 858 let mut instruction = Self::new(Op::Label); 859 instruction.set_result(id); 860 instruction 861 } 862 branch(id: Word) -> Self863 pub(super) fn branch(id: Word) -> Self { 864 let mut instruction = Self::new(Op::Branch); 865 instruction.add_operand(id); 866 instruction 867 } 868 869 // TODO Branch Weights not implemented. branch_conditional( condition_id: Word, true_label: Word, false_label: Word, ) -> Self870 pub(super) fn branch_conditional( 871 condition_id: Word, 872 true_label: Word, 873 false_label: Word, 874 ) -> Self { 875 let mut instruction = Self::new(Op::BranchConditional); 876 instruction.add_operand(condition_id); 877 instruction.add_operand(true_label); 878 instruction.add_operand(false_label); 879 instruction 880 } 881 switch(selector_id: Word, default_id: Word, cases: &[Case]) -> Self882 pub(super) fn switch(selector_id: Word, default_id: Word, cases: &[Case]) -> Self { 883 let mut instruction = Self::new(Op::Switch); 884 instruction.add_operand(selector_id); 885 instruction.add_operand(default_id); 886 for case in cases { 887 instruction.add_operand(case.value); 888 instruction.add_operand(case.label_id); 889 } 890 instruction 891 } 892 select( result_type_id: Word, id: Word, condition_id: Word, accept_id: Word, reject_id: Word, ) -> Self893 pub(super) fn select( 894 result_type_id: Word, 895 id: Word, 896 condition_id: Word, 897 accept_id: Word, 898 reject_id: Word, 899 ) -> Self { 900 let mut instruction = Self::new(Op::Select); 901 instruction.add_operand(result_type_id); 902 instruction.add_operand(id); 903 instruction.add_operand(condition_id); 904 instruction.add_operand(accept_id); 905 instruction.add_operand(reject_id); 906 instruction 907 } 908 kill() -> Self909 pub(super) fn kill() -> Self { 910 Self::new(Op::Kill) 911 } 912 return_void() -> Self913 pub(super) fn return_void() -> Self { 914 Self::new(Op::Return) 915 } 916 return_value(value_id: Word) -> Self917 pub(super) fn return_value(value_id: Word) -> Self { 918 let mut instruction = Self::new(Op::ReturnValue); 919 instruction.add_operand(value_id); 920 instruction 921 } 922 923 // 924 // Atomic Instructions 925 // 926 927 // 928 // Primitive Instructions 929 // 930 931 // Barriers 932 control_barrier( exec_scope_id: Word, mem_scope_id: Word, semantics_id: Word, ) -> Self933 pub(super) fn control_barrier( 934 exec_scope_id: Word, 935 mem_scope_id: Word, 936 semantics_id: Word, 937 ) -> Self { 938 let mut instruction = Self::new(Op::ControlBarrier); 939 instruction.add_operand(exec_scope_id); 940 instruction.add_operand(mem_scope_id); 941 instruction.add_operand(semantics_id); 942 instruction 943 } 944 } 945 946 impl From<crate::StorageFormat> for spirv::ImageFormat { from(format: crate::StorageFormat) -> Self947 fn from(format: crate::StorageFormat) -> Self { 948 use crate::StorageFormat as Sf; 949 match format { 950 Sf::R8Unorm => Self::R8, 951 Sf::R8Snorm => Self::R8Snorm, 952 Sf::R8Uint => Self::R8ui, 953 Sf::R8Sint => Self::R8i, 954 Sf::R16Uint => Self::R16ui, 955 Sf::R16Sint => Self::R16i, 956 Sf::R16Float => Self::R16f, 957 Sf::Rg8Unorm => Self::Rg8, 958 Sf::Rg8Snorm => Self::Rg8Snorm, 959 Sf::Rg8Uint => Self::Rg8ui, 960 Sf::Rg8Sint => Self::Rg8i, 961 Sf::R32Uint => Self::R32ui, 962 Sf::R32Sint => Self::R32i, 963 Sf::R32Float => Self::R32f, 964 Sf::Rg16Uint => Self::Rg16ui, 965 Sf::Rg16Sint => Self::Rg16i, 966 Sf::Rg16Float => Self::Rg16f, 967 Sf::Rgba8Unorm => Self::Rgba8, 968 Sf::Rgba8Snorm => Self::Rgba8Snorm, 969 Sf::Rgba8Uint => Self::Rgba8ui, 970 Sf::Rgba8Sint => Self::Rgba8i, 971 Sf::Rgb10a2Unorm => Self::Rgb10a2ui, 972 Sf::Rg11b10Float => Self::R11fG11fB10f, 973 Sf::Rg32Uint => Self::Rg32ui, 974 Sf::Rg32Sint => Self::Rg32i, 975 Sf::Rg32Float => Self::Rg32f, 976 Sf::Rgba16Uint => Self::Rgba16ui, 977 Sf::Rgba16Sint => Self::Rgba16i, 978 Sf::Rgba16Float => Self::Rgba16f, 979 Sf::Rgba32Uint => Self::Rgba32ui, 980 Sf::Rgba32Sint => Self::Rgba32i, 981 Sf::Rgba32Float => Self::Rgba32f, 982 } 983 } 984 } 985 986 impl From<crate::ImageDimension> for spirv::Dim { from(dim: crate::ImageDimension) -> Self987 fn from(dim: crate::ImageDimension) -> Self { 988 use crate::ImageDimension as Id; 989 match dim { 990 Id::D1 => Self::Dim1D, 991 Id::D2 => Self::Dim2D, 992 Id::D3 => Self::Dim3D, 993 Id::Cube => Self::DimCube, 994 } 995 } 996 } 997