├── .cargo └── config.toml ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── enhancement.md ├── install-spirv-tools │ ├── Cargo.toml │ └── src │ │ └── main.rs └── workflows │ ├── ISSUE_TEMPLATE │ └── bug_report.md │ ├── ci.yaml │ ├── deploy_docs.yml │ ├── docs.sh │ └── lint.sh ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── android.nix ├── clippy.toml ├── crates ├── rustc_codegen_spirv-target-specs │ ├── Cargo.toml │ ├── README.md │ ├── src │ │ ├── include_str.rs │ │ └── lib.rs │ └── target-specs │ │ ├── spirv-unknown-opengl4.0.json │ │ ├── spirv-unknown-opengl4.1.json │ │ ├── spirv-unknown-opengl4.2.json │ │ ├── spirv-unknown-opengl4.3.json │ │ ├── spirv-unknown-opengl4.5.json │ │ ├── spirv-unknown-spv1.0.json │ │ ├── spirv-unknown-spv1.1.json │ │ ├── spirv-unknown-spv1.2.json │ │ ├── spirv-unknown-spv1.3.json │ │ ├── spirv-unknown-spv1.4.json │ │ ├── spirv-unknown-spv1.5.json │ │ ├── spirv-unknown-vulkan1.0.json │ │ ├── spirv-unknown-vulkan1.1.json │ │ ├── spirv-unknown-vulkan1.1spv1.4.json │ │ └── spirv-unknown-vulkan1.2.json ├── rustc_codegen_spirv-types │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── compile_result.rs │ │ └── lib.rs ├── rustc_codegen_spirv │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ └── src │ │ ├── abi.rs │ │ ├── attr.rs │ │ ├── builder │ │ ├── builder_methods.rs │ │ ├── byte_addressable_buffer.rs │ │ ├── ext_inst.rs │ │ ├── intrinsics.rs │ │ ├── libm_intrinsics.rs │ │ ├── mod.rs │ │ └── spirv_asm.rs │ │ ├── builder_spirv.rs │ │ ├── codegen_cx │ │ ├── constant.rs │ │ ├── declare.rs │ │ ├── entry.rs │ │ ├── mod.rs │ │ └── type_.rs │ │ ├── custom_decorations.rs │ │ ├── custom_insts.rs │ │ ├── lib.rs │ │ ├── link.rs │ │ ├── linker │ │ ├── dce.rs │ │ ├── destructure_composites.rs │ │ ├── duplicates.rs │ │ ├── entry_interface.rs │ │ ├── import_export_link.rs │ │ ├── inline.rs │ │ ├── ipo.rs │ │ ├── mem2reg.rs │ │ ├── mod.rs │ │ ├── param_weakening.rs │ │ ├── peephole_opts.rs │ │ ├── simple_passes.rs │ │ ├── specializer.rs │ │ ├── spirt_passes │ │ │ ├── controlflow.rs │ │ │ ├── debuginfo.rs │ │ │ ├── diagnostics.rs │ │ │ ├── fuse_selects.rs │ │ │ ├── mod.rs │ │ │ └── reduce.rs │ │ ├── test.rs │ │ └── zombies.rs │ │ ├── spirv_type.rs │ │ ├── spirv_type_constraints.rs │ │ ├── symbols.rs │ │ ├── target.rs │ │ └── target_feature.rs ├── spirv-builder │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── depfile.rs │ │ ├── lib.rs │ │ └── watch.rs └── spirv-std │ ├── Cargo.toml │ ├── README.md │ ├── macros │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── image.rs │ │ └── lib.rs │ ├── shared │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── image_params.rs │ │ └── lib.rs │ └── src │ ├── arch.rs │ ├── arch │ ├── atomics.rs │ ├── barrier.rs │ ├── demote_to_helper_invocation_ext.rs │ ├── derivative.rs │ ├── mesh_shading.rs │ ├── primitive.rs │ ├── ray_tracing.rs │ └── subgroup.rs │ ├── byte_addressable_buffer.rs │ ├── float.rs │ ├── image.rs │ ├── image │ ├── params.rs │ └── sample_with.rs │ ├── indirect_command.rs │ ├── integer.rs │ ├── lib.rs │ ├── memory.rs │ ├── number.rs │ ├── ray_tracing.rs │ ├── runtime_array.rs │ ├── sampler.rs │ ├── scalar.rs │ ├── sealed.rs │ ├── typed_buffer.rs │ └── vector.rs ├── default.nix ├── deny.toml ├── docs ├── .gitignore ├── assets │ └── sky.jpg ├── book.toml └── src │ ├── SUMMARY.md │ ├── attributes.md │ ├── building-rust-gpu.md │ ├── codegen-args.md │ ├── image.md │ ├── inline-asm.md │ ├── introduction.md │ ├── migration-to-register-tool.md │ ├── platform-support.md │ ├── publishing-rust-gpu.md │ ├── rfcs │ ├── 000-template.md │ └── 001-resource-binding-syntax.md │ ├── spirv-minimization.md │ ├── testing.md │ ├── tracing.md │ └── writing-shader-crates.md ├── examples ├── README.md ├── multibuilder │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── runners │ ├── ash │ │ ├── Cargo.toml │ │ ├── build.rs │ │ └── src │ │ │ └── main.rs │ ├── cpu │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ └── wgpu │ │ ├── Cargo.toml │ │ ├── build.rs │ │ ├── builder │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ └── src │ │ ├── compute.rs │ │ ├── graphics.rs │ │ ├── lib.rs │ │ └── main.rs └── shaders │ ├── compute-shader │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── main.rs │ ├── mouse-shader │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── reduce │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── shared │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── simplest-shader │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ └── sky-shader │ ├── Cargo.toml │ └── src │ └── lib.rs ├── rust-toolchain.toml ├── rustfmt.toml └── tests ├── compiletests ├── Cargo.toml ├── README.md ├── deps-helper │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── src │ └── main.rs └── ui │ ├── arch │ ├── all.rs │ ├── all.stderr │ ├── all_memory_barrier.rs │ ├── all_memory_barrier.stderr │ ├── all_memory_barrier_with_group_sync.rs │ ├── all_memory_barrier_with_group_sync.stderr │ ├── any.rs │ ├── any.stderr │ ├── atomic_i_increment.rs │ ├── control_barrier.rs │ ├── convert_u_to_acceleration_structure_khr.rs │ ├── debug_printf.rs │ ├── debug_printf_type_checking.rs │ ├── debug_printf_type_checking.stderr │ ├── demote_to_helper_invocation.rs │ ├── derivative.rs │ ├── derivative.stderr │ ├── derivative_control.rs │ ├── derivative_control.stderr │ ├── device_memory_barrier.rs │ ├── device_memory_barrier.stderr │ ├── device_memory_barrier_with_group_sync.rs │ ├── device_memory_barrier_with_group_sync.stderr │ ├── emit_stream_vertex.rs │ ├── emit_vertex.rs │ ├── end_primitive.rs │ ├── end_stream_primitive.rs │ ├── execute_callable.rs │ ├── ignore_intersection_khr.rs │ ├── index_unchecked.rs │ ├── integer_min_and_max.rs │ ├── kill.rs │ ├── memory_barrier.rs │ ├── mesh_shader_output_lines.rs │ ├── mesh_shader_output_points.rs │ ├── mesh_shader_output_triangles.rs │ ├── mesh_shader_payload.rs │ ├── mesh_shader_per_primitive.rs │ ├── ray_query_confirm_intersection_khr.rs │ ├── ray_query_get_intersection_barycentrics_khr.rs │ ├── ray_query_get_intersection_candidate_aabb_opaque_khr.rs │ ├── ray_query_get_intersection_front_face_khr.rs │ ├── ray_query_get_intersection_geometry_index_khr.rs │ ├── ray_query_get_intersection_instance_custom_index_khr.rs │ ├── ray_query_get_intersection_instance_id_khr.rs │ ├── ray_query_get_intersection_object_ray_direction_khr.rs │ ├── ray_query_get_intersection_object_ray_origin_khr.rs │ ├── ray_query_get_intersection_object_to_world_khr.rs │ ├── ray_query_get_intersection_primitive_index_khr.rs │ ├── ray_query_get_intersection_shader_binding_table_record_offset_khr.rs │ ├── ray_query_get_intersection_t_khr.rs │ ├── ray_query_get_intersection_type_khr.rs │ ├── ray_query_get_ray_flags_khr.rs │ ├── ray_query_get_ray_t_min_khr.rs │ ├── ray_query_get_world_ray_direction_khr.rs │ ├── ray_query_get_world_ray_origin_khr.rs │ ├── ray_query_initialize_khr.rs │ ├── ray_query_terminate_khr.rs │ ├── read_clock_khr.rs │ ├── report_intersection_khr.rs │ ├── subgroup │ │ ├── subgroup_ballot.rs │ │ ├── subgroup_ballot.stderr │ │ ├── subgroup_ballot_bit_count.rs │ │ ├── subgroup_ballot_bit_count.stderr │ │ ├── subgroup_broadcast_first.rs │ │ ├── subgroup_broadcast_first.stderr │ │ ├── subgroup_builtins.rs │ │ ├── subgroup_elect.rs │ │ ├── subgroup_elect.stderr │ │ ├── subgroup_i_add_clustered.rs │ │ ├── subgroup_i_add_clustered.stderr │ │ ├── subgroup_i_add_exclusive_scan.rs │ │ ├── subgroup_i_add_exclusive_scan.stderr │ │ ├── subgroup_i_add_inclusive_scan.rs │ │ ├── subgroup_i_add_inclusive_scan.stderr │ │ ├── subgroup_i_add_reduce.rs │ │ └── subgroup_i_add_reduce.stderr │ ├── task_shader.rs │ ├── task_shader_mispile.rs │ ├── task_shader_payload.rs │ ├── terminate_ray_khr.rs │ ├── trace_ray_khr.rs │ ├── vector_extract_dynamic.rs │ ├── vector_insert_dynamic.rs │ ├── workgroup_memory_barrier.rs │ ├── workgroup_memory_barrier.stderr │ ├── workgroup_memory_barrier_with_group_sync.rs │ └── workgroup_memory_barrier_with_group_sync.stderr │ ├── byte_addressable_buffer │ ├── arr.rs │ ├── big_struct.rs │ ├── complex.rs │ ├── empty_struct.rs │ ├── f32.rs │ ├── small_struct.rs │ ├── u32.rs │ └── vec.rs │ ├── dis │ ├── add_two_ints.rs │ ├── add_two_ints.stderr │ ├── asm.rs │ ├── asm.stderr │ ├── asm_add_two_ints.rs │ ├── asm_add_two_ints.stderr │ ├── asm_op_decorate.rs │ ├── asm_op_decorate.stderr │ ├── complex_image_sample_inst.rs │ ├── complex_image_sample_inst.stderr │ ├── custom_entry_point.rs │ ├── custom_entry_point.stderr │ ├── entry-pass-mode-cast-array.rs │ ├── entry-pass-mode-cast-array.stderr │ ├── generic-fn-op-name.rs │ ├── generic-fn-op-name.stderr │ ├── index_user_dst.rs │ ├── index_user_dst.stderr │ ├── issue-1062.rs │ ├── issue-1062.stderr │ ├── issue-373.rs │ ├── issue-373.stderr │ ├── issue-723-output.rs │ ├── issue-723-output.stderr │ ├── issue-731.rs │ ├── issue-731.stderr │ ├── non-writable-storage_buffer.rs │ ├── non-writable-storage_buffer.stderr │ ├── panic_builtin_bounds_check.rs │ ├── panic_builtin_bounds_check.stderr │ ├── panic_sequential_many.rs │ ├── panic_sequential_many.stderr │ ├── pass-mode-cast-struct.rs │ ├── pass-mode-cast-struct.stderr │ ├── ptr_copy.normal.stderr │ ├── ptr_copy.rs │ ├── ptr_copy.via_intrinsic.stderr │ ├── ptr_read.rs │ ├── ptr_read.stderr │ ├── ptr_read_method.rs │ ├── ptr_read_method.stderr │ ├── ptr_write.rs │ ├── ptr_write.stderr │ ├── ptr_write_method.rs │ ├── ptr_write_method.stderr │ ├── spec_constant-attr.rs │ ├── spec_constant-attr.stderr │ └── target_features.stderr │ ├── glam │ └── mat3_vec3_multiply.rs │ ├── hello_world.rs │ ├── image │ ├── components.rs │ ├── fetch.rs │ ├── format.rs │ ├── gather.rs │ ├── gather_err.rs │ ├── gather_err.stderr │ ├── image_with.rs │ ├── implicit_not_in_fragment.rs │ ├── implicit_not_in_fragment.stderr │ ├── issue-330.rs │ ├── issue_527.rs │ ├── query │ │ ├── query_levels.rs │ │ ├── query_levels_err.rs │ │ ├── query_levels_err.stderr │ │ ├── query_lod.rs │ │ ├── query_lod_err.rs │ │ ├── query_lod_err.stderr │ │ ├── query_samples.rs │ │ ├── query_size.rs │ │ ├── query_size_err.rs │ │ ├── query_size_err.stderr │ │ ├── query_size_lod.rs │ │ ├── query_size_lod_err.rs │ │ └── query_size_lod_err.stderr │ ├── read.rs │ ├── read_subpass.rs │ ├── sample.rs │ ├── sample_bias.rs │ ├── sample_depth_reference │ │ ├── sample.rs │ │ ├── sample_gradient.rs │ │ └── sample_lod.rs │ ├── sample_depth_reference_with_project_coordinate │ │ ├── sample.rs │ │ ├── sample_gradient.rs │ │ └── sample_lod.rs │ ├── sample_gradient.rs │ ├── sample_lod.rs │ ├── sample_with_project_coordinate │ │ ├── sample.rs │ │ ├── sample_gradient.rs │ │ └── sample_lod.rs │ └── write.rs │ ├── lang │ ├── asm │ │ ├── block_tracking_fail.rs │ │ ├── block_tracking_fail.stderr │ │ ├── block_tracking_pass.rs │ │ ├── const_args.rs │ │ ├── infer-access-chain-array.rs │ │ ├── infer-access-chain-slice.rs │ │ ├── issue-1002.rs │ │ └── issue-1002.stderr │ ├── consts │ │ ├── issue-1024.rs │ │ ├── issue-329.rs │ │ ├── issue-834.rs │ │ ├── nested-ref-in-composite.rs │ │ ├── nested-ref-in-composite.stderr │ │ ├── nested-ref.rs │ │ ├── nested-ref.stderr │ │ └── shallow-ref.rs │ ├── control_flow │ │ ├── closure_multi.rs │ │ ├── defer.rs │ │ ├── for_range.rs │ │ ├── for_range_signed.rs │ │ ├── for_with_custom_range_iter.rs │ │ ├── if.rs │ │ ├── if_else.rs │ │ ├── if_else_if_else.rs │ │ ├── if_if.rs │ │ ├── if_return_else.rs │ │ ├── if_return_else_return.rs │ │ ├── if_while.rs │ │ ├── ifx2.rs │ │ ├── issue_283.rs │ │ ├── issue_764.rs │ │ ├── issue_764.stderr │ │ ├── loop.rs │ │ ├── while.rs │ │ ├── while_break.rs │ │ ├── while_continue.rs │ │ ├── while_if_break.rs │ │ ├── while_if_break_else_break.rs │ │ ├── while_if_break_if_break.rs │ │ ├── while_if_continue.rs │ │ ├── while_if_continue_else_continue.rs │ │ ├── while_return.rs │ │ ├── while_while.rs │ │ ├── while_while_break.rs │ │ ├── while_while_continue.rs │ │ ├── while_while_if_break.rs │ │ └── while_while_if_continue.rs │ ├── core │ │ ├── array │ │ │ ├── init_array_i16.rs │ │ │ ├── init_array_i32.rs │ │ │ ├── init_array_i64.rs │ │ │ └── init_array_i8.rs │ │ ├── intrinsics │ │ │ ├── bswap.rs │ │ │ ├── leading_zeros.rs │ │ │ ├── log10.rs │ │ │ └── trailing_zeros.rs │ │ ├── mem │ │ │ └── create_unitialized_memory.rs │ │ ├── ops │ │ │ ├── logical_and.rs │ │ │ └── range-contains.rs │ │ ├── ptr │ │ │ ├── allocate_const_scalar.rs │ │ │ ├── allocate_const_scalar.stderr │ │ │ ├── allocate_null.rs │ │ │ ├── allocate_vec_like.rs │ │ │ └── allocate_vec_like.stderr │ │ ├── ref │ │ │ ├── member_ref_arg-broken.rs │ │ │ ├── member_ref_arg-broken.stderr │ │ │ ├── member_ref_arg.rs │ │ │ ├── member_ref_arg.stderr │ │ │ ├── zst_member_ref_arg-broken.rs │ │ │ ├── zst_member_ref_arg-broken.stderr │ │ │ └── zst_member_ref_arg.rs │ │ ├── unwrap_or.rs │ │ └── unwrap_or.stderr │ ├── f32 │ │ ├── packing.rs │ │ └── signum.rs │ ├── issue-415.rs │ ├── issue-46.rs │ ├── issue-836.rs │ ├── panic │ │ ├── builtin.rs │ │ ├── builtin_bounds_check.rs │ │ ├── simple.rs │ │ ├── track_caller.rs │ │ └── track_caller.stderr │ └── u32 │ │ ├── bit_reverse.rs │ │ └── count_ones.rs │ ├── spirv-attr │ ├── all-builtins.rs │ ├── bad-deduce-storage-class.rs │ ├── bad-deduce-storage-class.stderr │ ├── bool-inputs-err.rs │ ├── bool-inputs-err.stderr │ ├── bool-inputs.rs │ ├── int-without-flat.rs │ ├── int-without-flat.stderr │ ├── invalid-matrix-type-empty.rs │ ├── invalid-matrix-type-empty.stderr │ ├── invalid-matrix-type.rs │ ├── invalid-matrix-type.stderr │ ├── invalid-storage-class.rs │ ├── invalid-storage-class.stderr │ ├── invalid-target.rs │ ├── invalid-target.stderr │ ├── invariant-invalid.rs │ ├── invariant-invalid.stderr │ ├── invariant.rs │ ├── matrix-type.rs │ ├── multiple.rs │ └── multiple.stderr │ ├── storage_class │ ├── mutability-errors.rs │ ├── mutability-errors.stderr │ ├── push_constant.rs │ ├── runtime_descriptor_array.rs │ ├── runtime_descriptor_array_error.rs │ ├── runtime_descriptor_array_error.stderr │ ├── storage_buffer-dst.rs │ ├── typed_buffer.rs │ ├── typed_buffer_descriptor_array.rs │ ├── typed_buffer_descriptor_array_slice.rs │ └── typed_buffer_slice.rs │ ├── target_features_err.rs │ └── target_features_err.stderr └── difftests ├── README.md ├── bin ├── Cargo.toml └── src │ ├── main.rs │ └── runner.rs ├── lib ├── Cargo.toml └── src │ ├── config.rs │ ├── lib.rs │ └── scaffold │ ├── compute │ ├── mod.rs │ └── wgpu.rs │ └── mod.rs └── tests ├── Cargo.lock ├── Cargo.toml └── simple-compute ├── simple-compute-rust ├── Cargo.toml └── src │ ├── lib.rs │ └── main.rs └── simple-compute-wgsl ├── Cargo.toml ├── shader.wgsl └── src └── main.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | # configure GitHub linguist (language bar) https://github.com/github/linguist#overrides 2 | docs/* linguist-documentation 3 | * text=auto eol=lf 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @eddyb @LegNeato @Firestar99 @schell 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug with using rust-gpu. 4 | title: "(my bug report)" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | ### Expected Behaviour 13 | 14 | 15 | ### Example & Steps To Reproduce 16 | 20 | 21 | 1. 22 | 2. 23 | 3. 24 | 25 | ## System Info 26 | 31 | 32 | - Rust: [e.g. 1.49.0-nightly (1eaadebb3 2020-10-21)] 33 | - OS: [e.g. macOS 10.15.7] 34 | - GPU: [e.g. Intel(R) UHD Graphics 630] 35 | - SPIR-V: [e.g. v2020.3 unknown hash, 2020-06-12T01:06:18] 36 | 37 | 38 | ## Backtrace 39 | 40 | 41 |
Backtrace 42 |

43 | 44 | ``` 45 | 46 | ``` 47 | 48 |

49 |
50 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement 3 | about: Propose a minor improvement or feature to the project. 4 | title: "(My enhancement)" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | 20 | -------------------------------------------------------------------------------- /.github/install-spirv-tools/Cargo.toml: -------------------------------------------------------------------------------- 1 | # We make this tool its own workspace as it doesn't share dependencies with the 2 | # rest of the workspace, and it shouldn't be built normally, only as a helper 3 | # for CI so it would just slow down local development for no reason 4 | [workspace] 5 | 6 | [package] 7 | name = "install-spirv-tools" 8 | edition = "2021" 9 | version = "0.1.0" 10 | publish = false 11 | 12 | [dependencies] 13 | tar = "0.4" 14 | zstd = "0.13" 15 | -------------------------------------------------------------------------------- /.github/workflows/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rust-GPU/rust-gpu/77070b70b4af3afd7d12d980f6c997e9b77e6f9c/.github/workflows/ISSUE_TEMPLATE/bug_report.md -------------------------------------------------------------------------------- /.github/workflows/deploy_docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | build: 8 | runs-on: macos-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - run: brew install mdbook spirv-tools 12 | - run: mkdir docs-build/ 13 | - run: $(cd docs && mdbook build -d ../docs-build/book) 14 | - run: .github/workflows/docs.sh 15 | - run: mv target/doc docs-build/api 16 | - uses: JamesIves/github-pages-deploy-action@3.7.1 17 | with: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | BRANCH: gh-pages # The branch the action should deploy to. 20 | FOLDER: docs-build # The folder the action should deploy. 21 | CLEAN: true # Automatically remove deleted files from the deploy branch 22 | -------------------------------------------------------------------------------- /.github/workflows/docs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [[ -z "${CI}" ]]; then 5 | FEAT="use-compiled-tools" 6 | else 7 | FEAT="use-installed-tools" 8 | fi 9 | 10 | function doc() { 11 | echo ::group::"$1" 12 | cargo doc \ 13 | --manifest-path "$1/Cargo.toml" \ 14 | --no-default-features \ 15 | --features "$FEAT" 16 | echo ::endgroup:: 17 | } 18 | 19 | # Core crates only! 20 | cargo doc --manifest-path "crates/spirv-std/Cargo.toml" --all-features 21 | doc crates/rustc_codegen_spirv 22 | doc crates/spirv-builder 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .vscode/ 3 | .vim/ 4 | tests/Cargo.lock 5 | .github/install-spirv-tools/Cargo.lock 6 | rustc-ice-*.txt 7 | .idea 8 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | avoid-breaking-exported-api = false 2 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc_codegen_spirv-target-specs" 3 | description = "target spec json files of rust-gpu for the rustc compiler" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [features] 11 | include_str = [] 12 | dir_path = [] 13 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/README.md: -------------------------------------------------------------------------------- 1 | # `rustc_codegen_spirv-target-specs` 2 | 3 | The target spec json files of rust-gpu to hand to the rustc compiler, declaring various metadata about our codegen backend. 4 | 5 | ## Features 6 | * `include_str`: include target specs as string constants, for bundling with `cargo-gpu` 7 | * `dir_path`: export a path to the target specs dir, for `spirv-builder` and `compiletest` in this repo 8 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | /// directory with all the `target-specs` jsons for our codegen backend 4 | #[cfg(feature = "dir_path")] 5 | pub const TARGET_SPEC_DIR_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/target-specs"); 6 | 7 | #[cfg(feature = "include_str")] 8 | mod include_str; 9 | #[cfg(feature = "include_str")] 10 | pub use include_str::TARGET_SPECS; 11 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "opengl4.0", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-opengl4.0", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "opengl4.1", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-opengl4.1", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "opengl4.2", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-opengl4.2", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "opengl4.3", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-opengl4.3", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-opengl4.5.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "opengl4.5", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-opengl4.5", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.0", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.0", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.1", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.1", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.2", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.2", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.3.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.3", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.3", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.4", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.4", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-spv1.5.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "spv1.5", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-spv1.5", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.0.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "vulkan1.0", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-vulkan1.0", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "vulkan1.1", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-vulkan1.1", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.1spv1.4.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "vulkan1.1spv1.4", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-vulkan1.1spv1.4", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-target-specs/target-specs/spirv-unknown-vulkan1.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "allows-weak-linkage": false, 3 | "arch": "spirv", 4 | "crt-objects-fallback": "false", 5 | "crt-static-allows-dylibs": true, 6 | "data-layout": "e-m:e-p:32:32:32-i64:64-n8:16:32:64", 7 | "dll-prefix": "", 8 | "dll-suffix": ".spv.json", 9 | "dynamic-linking": true, 10 | "emit-debug-gdb-scripts": false, 11 | "env": "vulkan1.2", 12 | "linker-flavor": "unix", 13 | "linker-is-gnu": false, 14 | "llvm-target": "spirv-unknown-vulkan1.2", 15 | "main-needs-argc-argv": false, 16 | "metadata": { 17 | "description": null, 18 | "host_tools": null, 19 | "std": null, 20 | "tier": null 21 | }, 22 | "os": "unknown", 23 | "panic-strategy": "abort", 24 | "simd-types-indirect": false, 25 | "target-pointer-width": "32" 26 | } 27 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-types/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustc_codegen_spirv-types" 3 | description = "SPIR-V backend types shared between rustc_codegen_spirv and spirv-builder" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [dependencies] 11 | spirv = { version = "0.3.0", features = ["serialize", "deserialize"] } 12 | rspirv = "0.12" 13 | serde = { version = "1.0", features = ["derive"] } 14 | serde_json = "1.0" 15 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-types/README.md: -------------------------------------------------------------------------------- 1 | # `rustc_codegen_spirv-types` 2 | 3 | SPIR-V backend types shared between `rustc_codegen_spirv` and `spirv-builder`. Please refer to [`spirv-builder`](https://docs.rs/spirv-builder/) for more information. 4 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv-types/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | pub use rspirv::spirv::Capability; 4 | 5 | mod compile_result; 6 | pub use compile_result::*; 7 | 8 | // HACK(eddyb) allows downstream crates to access the correct version directly. 9 | pub use serde; 10 | pub use serde_json; 11 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv/README.md: -------------------------------------------------------------------------------- 1 | # `rustc_codegen_spirv` 2 | 3 | Compiler backend for the `SPIR-V` target architecture. This crate is not intended to be used directly. Please refer to [`spirv-builder`](https://docs.rs/spirv-builder/) for more information. 4 | 5 | ## Documentation 6 | 7 | Because of its nature, this crate can only be built using a very specific nightly version of the Rust toolchain. As such, the `docs.rs` build of the API documentation will likely fail. Please refer to the [documentation in the `rust-gpu` github repo](https://rust-gpu.github.io/rust-gpu/api/rustc_codegen_spirv/index.html) for properly built docs. 8 | -------------------------------------------------------------------------------- /crates/rustc_codegen_spirv/src/target_feature.rs: -------------------------------------------------------------------------------- 1 | use rustc_span::symbol::Symbol; 2 | 3 | #[derive(Clone, Debug, Eq, PartialEq)] 4 | pub enum TargetFeature { 5 | Extension(Symbol), 6 | Capability(rspirv::spirv::Capability), 7 | } 8 | 9 | impl std::str::FromStr for TargetFeature { 10 | type Err = String; 11 | 12 | fn from_str(input: &str) -> Result { 13 | const EXT_PREFIX: &str = "ext:"; 14 | 15 | if let Some(input) = input.strip_prefix(EXT_PREFIX) { 16 | Ok(Self::Extension(Symbol::intern(input))) 17 | } else { 18 | Ok(Self::Capability(input.parse().map_err(|_err| { 19 | format!("Invalid Capability: `{input}`") 20 | })?)) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /crates/spirv-std/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "spirv-std" 3 | description = "Standard functions and types for SPIR-V" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [dependencies] 14 | spirv-std-types.workspace = true 15 | spirv-std-macros.workspace = true 16 | bitflags = "1.2.1" 17 | bytemuck = { version = "1.18.0", features = ["derive"], optional = true } 18 | 19 | [target.'cfg(target_arch = "spirv")'.dependencies] 20 | num-traits = { workspace = true, features = ["libm"] } 21 | glam = { workspace = true, features = ["libm"] } 22 | libm = { workspace = true } 23 | 24 | [target.'cfg(not(target_arch = "spirv"))'.dependencies] 25 | num-traits = { workspace = true, default-features = true } 26 | glam = { workspace = true, default-features = true } 27 | 28 | [features] 29 | default = [] 30 | bytemuck = ["dep:bytemuck", "glam/bytemuck"] 31 | -------------------------------------------------------------------------------- /crates/spirv-std/macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "spirv-std-macros" 3 | description = "Macros for spirv-std" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | proc-macro = true 15 | 16 | [dependencies] 17 | spirv-std-types.workspace = true 18 | proc-macro2 = "1.0.24" 19 | quote = "1.0.8" 20 | syn = { version = "2.0.90", features = ["full", "visit-mut"] } 21 | -------------------------------------------------------------------------------- /crates/spirv-std/macros/README.md: -------------------------------------------------------------------------------- 1 | # `spirv-std-macros` 2 | 3 | This crate implements macros required for `spirv-std`. Most importantly, it implements the `#![spirv(..)]` attribute macro required for use in shader code. Please refer to [`spirv-std`](https://docs.rs/spirv-std/) for more information. 4 | -------------------------------------------------------------------------------- /crates/spirv-std/shared/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "spirv-std-types" 3 | description = "SPIR-V types shared between spirv-std and spirv-std-macros" 4 | version.workspace = true 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | -------------------------------------------------------------------------------- /crates/spirv-std/shared/README.md: -------------------------------------------------------------------------------- 1 | # `spirv-std-types` 2 | 3 | Small shared crate, to share definitions between [`spirv-std`](https://docs.rs/spirv-std/) and [`spirv-std-macros`](https://docs.rs/spirv-std-macros/). Please refer to [`spirv-std`](https://docs.rs/spirv-std/) for more information. 4 | -------------------------------------------------------------------------------- /crates/spirv-std/shared/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![no_std] 3 | 4 | pub mod image_params; 5 | -------------------------------------------------------------------------------- /crates/spirv-std/src/number.rs: -------------------------------------------------------------------------------- 1 | //! Traits and helper functions related to numbers. 2 | 3 | /// Abstract trait representing a SPIR-V integer or floating-point type. 4 | pub trait Number: crate::scalar::Scalar {} 5 | 6 | impl Number for u8 {} 7 | impl Number for u16 {} 8 | impl Number for u32 {} 9 | impl Number for u64 {} 10 | impl Number for i8 {} 11 | impl Number for i16 {} 12 | impl Number for i32 {} 13 | impl Number for i64 {} 14 | impl Number for f32 {} 15 | impl Number for f64 {} 16 | -------------------------------------------------------------------------------- /crates/spirv-std/src/sampler.rs: -------------------------------------------------------------------------------- 1 | /// An opaque reference to settings that describe how to access, filter, or 2 | /// sample an image. 3 | #[spirv(sampler)] 4 | #[derive(Copy, Clone)] 5 | // HACK(eddyb) avoids "transparent newtype of `_anti_zst_padding`" misinterpretation. 6 | #[repr(C)] 7 | pub struct Sampler { 8 | // HACK(eddyb) avoids the layout becoming ZST (and being elided in one way 9 | // or another, before `#[spirv(sampler)]` can special-case it). 10 | _anti_zst_padding: core::mem::MaybeUninit, 11 | } 12 | -------------------------------------------------------------------------------- /crates/spirv-std/src/scalar.rs: -------------------------------------------------------------------------------- 1 | //! Traits related to scalars. 2 | 3 | use crate::vector::{VectorOrScalar, create_dim}; 4 | use core::num::NonZeroUsize; 5 | 6 | /// Abstract trait representing a SPIR-V scalar type. 7 | /// 8 | /// # Safety 9 | /// Implementing this trait on non-scalar types breaks assumptions of other unsafe code, and should 10 | /// not be done. 11 | pub unsafe trait Scalar: VectorOrScalar + crate::sealed::Sealed {} 12 | 13 | macro_rules! impl_scalar { 14 | ($($ty:ty),+) => { 15 | $( 16 | unsafe impl VectorOrScalar for $ty { 17 | type Scalar = Self; 18 | const DIM: NonZeroUsize = create_dim(1); 19 | } 20 | unsafe impl Scalar for $ty {} 21 | )+ 22 | }; 23 | } 24 | 25 | impl_scalar!(bool, f32, f64, u8, u16, u32, u64, i8, i16, i32, i64); 26 | -------------------------------------------------------------------------------- /crates/spirv-std/src/sealed.rs: -------------------------------------------------------------------------------- 1 | /// A marker trait used to prevent other traits from being implemented outside 2 | /// of `spirv-std`. 3 | pub trait Sealed {} 4 | 5 | impl Sealed for bool {} 6 | impl Sealed for f32 {} 7 | impl Sealed for f64 {} 8 | impl Sealed for u8 {} 9 | impl Sealed for u16 {} 10 | impl Sealed for u32 {} 11 | impl Sealed for u64 {} 12 | impl Sealed for i8 {} 13 | impl Sealed for i16 {} 14 | impl Sealed for i32 {} 15 | impl Sealed for i64 {} 16 | 17 | impl Sealed for glam::Vec2 {} 18 | impl Sealed for glam::Vec3 {} 19 | impl Sealed for glam::Vec4 {} 20 | impl Sealed for glam::DVec2 {} 21 | impl Sealed for glam::DVec3 {} 22 | impl Sealed for glam::DVec4 {} 23 | impl Sealed for glam::UVec2 {} 24 | impl Sealed for glam::UVec3 {} 25 | impl Sealed for glam::UVec4 {} 26 | impl Sealed for glam::IVec2 {} 27 | impl Sealed for glam::IVec3 {} 28 | impl Sealed for glam::IVec4 {} 29 | 30 | impl Sealed for glam::Vec3A {} 31 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let 2 | pkgs = import {}; 3 | in with pkgs; stdenv.mkDerivation rec { 4 | name = "rust-gpu"; 5 | 6 | # Workaround for https://github.com/NixOS/nixpkgs/issues/60919. 7 | # NOTE(eddyb) needed only in debug mode (warnings about needing optimizations 8 | # turn into errors due to `-Werror`, for at least `spirv-tools-sys`). 9 | hardeningDisable = [ "fortify" ]; 10 | 11 | # Allow cargo to download crates (even inside `nix-shell --pure`). 12 | SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; 13 | 14 | nativeBuildInputs = [ rustup ]; 15 | 16 | # Runtime dependencies (for the example runners). 17 | LD_LIBRARY_PATH = with xorg; lib.makeLibraryPath [ 18 | vulkan-loader 19 | 20 | # NOTE(eddyb) winit really wants `libxkbcommon` on Wayland for some reason 21 | # (see https://github.com/rust-windowing/winit/issues/1760 for more info). 22 | wayland libxkbcommon 23 | 24 | libX11 libXcursor libXi libXrandr 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /docs/assets/sky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rust-GPU/rust-gpu/77070b70b4af3afd7d12d980f6c997e9b77e6f9c/docs/assets/sky.jpg -------------------------------------------------------------------------------- /docs/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["The Rust GPU Project Developers"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "Rust GPU Dev Guide" 7 | -------------------------------------------------------------------------------- /docs/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Introduction](./introduction.md) 4 | - [Contributing to Rust-GPU]() 5 | - [Building](./building-rust-gpu.md) 6 | - [Testing](./testing.md) 7 | - [Debugging](./tracing) 8 | - [Tracing](./tracing.md) 9 | - [Minimizing bugs in SPIR-V](./spirv-minimization.md) 10 | - ["Codegen args" (flags/options) supported by the Rust-GPU codegen backend](./codegen-args.md) 11 | - [Publishing Rust-GPU on crates.io](./publishing-rust-gpu.md) 12 | - [Platform Support](./platform-support.md) 13 | - [Writing Shader Crates](./writing-shader-crates.md) 14 | - [Features]() 15 | - [Attribute syntax](./attributes.md) 16 | - [Inline Assembly](./inline-asm.md) 17 | - [Image type syntax](./image.md) 18 | -------------------------------------------------------------------------------- /docs/src/image.md: -------------------------------------------------------------------------------- 1 | # Image type syntax 2 | 3 | There are a huge number of combinations of image types in SPIR-V. They are represented by a const 4 | generic type called `spirv_std::image::Image`, however, specifying the generic parameters of this 5 | type is incredibly tedious, so a wrapper macro, `spirv_std::Image!` can be used to write the type 6 | instead. 7 | 8 | The specific syntax and meaning of the arguments to the `Image!` macro can be found in 9 | [rustdoc](https://rust-gpu.github.io/rust-gpu/api/spirv_std/macro.Image.html). 10 | 11 | Some type aliases for common image formats can be found in the 12 | [`spirv_std::image`](https://rust-gpu.github.io/rust-gpu/api/spirv_std/image/index.html) 13 | module. For example, `Image2d` is a very commonly used type, corresponding to `texture2D` in GLSL, 14 | and is likely what you want if you want a regular old sampled texture. 15 | 16 | ```rust,no_run 17 | type Image2d = Image!(2D, type=f32, sampled); 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/src/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Welcome to the Rust-GPU dev guide! This documentation is meant for documenting 4 | how to use and develop on Rust-GPU. 5 | 6 | If you're looking to get started with writing your own shaders in Rust, 7 | check out the [_"Writing Shader Crates"_](./writing-shader-crates.md) section for 8 | more information on how to get started. 9 | 10 | Alternatively if you're looking to contribute to the `rust-gpu` project, have 11 | a look at [_"Building Rust-GPU"_](./building-rust-gpu.md) section. 12 | -------------------------------------------------------------------------------- /docs/src/rfcs/000-template.md: -------------------------------------------------------------------------------- 1 | 2 | # Summary 3 | 4 | State the problem that this RFC is trying to address clearly but briefly 5 | 6 | # Explanation 7 | 8 | Give examples, elaborate on the proposal 9 | 10 | # Drawbacks 11 | 12 | List potential issues that one would want to have discussed in the RFC comment section 13 | 14 | # Alternatives 15 | 16 | A list of potential alternatives, though sometimes they can arise from the comments as well. 17 | 18 | # Prior art 19 | 20 | Usually this will involve looking at current shading languages out there to see if we can either borrow concepts from them, or if we can improve upon existing concepts. -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | The examples here are split into a few categories: 4 | 5 | - The shaders folder contain various rust-gpu shaders, and are examples of how to use rust-gpu. 6 | - The runners folder contains programs that build and execute the shaders in the shaders folder using, for example, 7 | Vulkan. These programs are not exactly examples of how to use rust-gpu, as they're rather generic vulkan sample apps, 8 | but they do contain some infrastructure examples of how to integrate rust-gpu shaders into a build system (although 9 | both aren't the cleanest of examples, as they're also testing some of the more convoluted ways of consuming rust-gpu). 10 | - Finally, the multibuilder folder is a very short sample app of how to use the `multimodule` feature of `spirv-builder`. 11 | -------------------------------------------------------------------------------- /examples/multibuilder/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multibuilder" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | # See rustc_codegen_spirv/Cargo.toml for details on these features 11 | [features] 12 | default = ["use-compiled-tools"] 13 | use-installed-tools = ["spirv-builder/use-installed-tools"] 14 | use-compiled-tools = ["spirv-builder/use-compiled-tools"] 15 | 16 | [dependencies] 17 | spirv-builder.workspace = true 18 | -------------------------------------------------------------------------------- /examples/multibuilder/src/main.rs: -------------------------------------------------------------------------------- 1 | use spirv_builder::{MetadataPrintout, SpirvBuilder}; 2 | 3 | fn main() { 4 | let result = SpirvBuilder::new( 5 | concat!(env!("CARGO_MANIFEST_DIR"), "/../shaders/sky-shader"), 6 | "spirv-unknown-spv1.3", 7 | ) 8 | .print_metadata(MetadataPrintout::DependencyOnly) 9 | .multimodule(true) 10 | .build() 11 | .unwrap(); 12 | println!("{result:#?}"); 13 | } 14 | -------------------------------------------------------------------------------- /examples/runners/ash/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-runner-ash" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | # See rustc_codegen_spirv/Cargo.toml for details on these features 11 | [features] 12 | default = ["use-compiled-tools"] 13 | use-installed-tools = ["spirv-builder/use-installed-tools"] 14 | use-compiled-tools = ["spirv-builder/use-compiled-tools"] 15 | 16 | [dependencies] 17 | ash = "0.38" 18 | ash-window = "0.13" 19 | raw-window-handle = "0.6.2" 20 | winit = "0.30.0" 21 | clap = { version = "4", features = ["derive"] } 22 | cfg-if = "1.0.0" 23 | shared = { path = "../../shaders/shared" } 24 | spirv-builder = { workspace = true, default-features = false } 25 | 26 | [target.'cfg(target_os = "macos")'.dependencies] 27 | ash-molten = { version = "0.20", features = ["pre-built"] } 28 | -------------------------------------------------------------------------------- /examples/runners/ash/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | // While OUT_DIR is set for both build.rs and compiling the crate, PROFILE is only set in 5 | // build.rs. So, export it to crate compilation as well. 6 | let profile = env::var("PROFILE").unwrap(); 7 | println!("cargo:rustc-env=PROFILE={profile}"); 8 | } 9 | -------------------------------------------------------------------------------- /examples/runners/cpu/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-runner-cpu" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [dependencies] 11 | minifb = "0.25.0" 12 | # bring in the shader as natively compiled code 13 | shared = { path = "../../shaders/shared" } 14 | sky-shader = { path = "../../shaders/sky-shader" } 15 | 16 | # for parallelism, not really needed though 17 | rayon = "1.5" 18 | -------------------------------------------------------------------------------- /examples/runners/wgpu/builder/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example-runner-wgpu-builder" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | # See rustc_codegen_spirv/Cargo.toml for details on these features 11 | [features] 12 | default = ["use-compiled-tools"] 13 | use-installed-tools = ["spirv-builder/use-installed-tools"] 14 | use-compiled-tools = ["spirv-builder/use-compiled-tools"] 15 | 16 | [dependencies] 17 | spirv-builder.workspace = true 18 | -------------------------------------------------------------------------------- /examples/runners/wgpu/src/main.rs: -------------------------------------------------------------------------------- 1 | #[cfg(target_os = "android")] 2 | const _: () = panic!( 3 | "executable not applicable for Android targets, \ 4 | make sure to pass `--lib` when building with `cargo-apk`" 5 | ); 6 | 7 | fn main() { 8 | #[cfg(not(target_os = "android"))] 9 | example_runner_wgpu::main(); 10 | } 11 | -------------------------------------------------------------------------------- /examples/shaders/compute-shader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compute-shader" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | crate-type = ["dylib", "lib"] 15 | 16 | [dependencies] 17 | spirv-std = { workspace = true } 18 | 19 | [target.'cfg(not(target_arch = "spirv"))'.dependencies] 20 | rayon = "1.5" 21 | -------------------------------------------------------------------------------- /examples/shaders/compute-shader/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::time::Instant; 2 | 3 | use compute_shader::collatz; 4 | use rayon::prelude::*; 5 | 6 | fn main() { 7 | let top = 2u32.pow(20); 8 | let src_range = 1..top; 9 | let start = Instant::now(); 10 | let result = src_range 11 | .clone() 12 | .into_par_iter() 13 | .map(collatz) 14 | .collect::>(); 15 | let took = start.elapsed(); 16 | let mut max = 0; 17 | for (src, out) in src_range.zip(result.iter().copied()) { 18 | match out { 19 | Some(out) if out > max => { 20 | max = out; 21 | // Should produce 22 | println!("{src}: {out}"); 23 | } 24 | Some(_) => (), 25 | None => { 26 | println!("{src}: overflowed"); 27 | break; 28 | } 29 | } 30 | } 31 | println!("Took: {took:?}"); 32 | } 33 | -------------------------------------------------------------------------------- /examples/shaders/mouse-shader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mouse-shader" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | crate-type = ["dylib"] 15 | 16 | [dependencies] 17 | shared = { path = "../../shaders/shared" } 18 | spirv-std = { workspace = true } 19 | -------------------------------------------------------------------------------- /examples/shaders/reduce/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "reduce" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | crate-type = ["dylib", "lib"] 15 | 16 | [dependencies] 17 | spirv-std = { workspace = true } 18 | -------------------------------------------------------------------------------- /examples/shaders/shared/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "shared" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [dependencies] 14 | spirv-std = { workspace = true } 15 | bytemuck = { version = "1.18.0", features = ["derive"] } 16 | -------------------------------------------------------------------------------- /examples/shaders/simplest-shader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "simplest-shader" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | crate-type = ["dylib"] 15 | 16 | [dependencies] 17 | spirv-std = { workspace = true } 18 | shared = { path = "../shared" } 19 | -------------------------------------------------------------------------------- /examples/shaders/simplest-shader/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(target_arch = "spirv", no_std)] 2 | // HACK(eddyb) can't easily see warnings otherwise from `spirv-builder` builds. 3 | #![deny(warnings)] 4 | 5 | use shared::glam::{Vec4, vec4}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main_fs(output: &mut Vec4) { 10 | *output = vec4(1.0, 0.0, 0.0, 1.0); 11 | } 12 | 13 | #[spirv(vertex)] 14 | pub fn main_vs( 15 | #[spirv(vertex_index)] vert_id: i32, 16 | #[spirv(position, invariant)] out_pos: &mut Vec4, 17 | ) { 18 | *out_pos = vec4( 19 | (vert_id - 1) as f32, 20 | ((vert_id & 1) * 2 - 1) as f32, 21 | 0.0, 22 | 1.0, 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /examples/shaders/sky-shader/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sky-shader" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | [lints] 11 | workspace = true 12 | 13 | [lib] 14 | crate-type = ["lib", "dylib"] 15 | 16 | [dependencies] 17 | shared = { path = "../../shaders/shared" } 18 | spirv-std = { workspace = true } 19 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2024-11-22" 3 | components = ["rust-src", "rustc-dev", "llvm-tools"] 4 | # commit_hash = b19329a37cedf2027517ae22c87cf201f93d776e 5 | 6 | # Whenever changing the nightly channel, update the commit hash above, and make 7 | # sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also. 8 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | style_edition = "2024" 2 | -------------------------------------------------------------------------------- /tests/compiletests/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compiletests" 3 | version = "0.0.0" 4 | publish = false 5 | authors.workspace = true 6 | edition.workspace = true 7 | license.workspace = true 8 | repository.workspace = true 9 | 10 | # See rustc_codegen_spirv/Cargo.toml for details on these features 11 | [features] 12 | default = ["use-compiled-tools"] 13 | use-installed-tools = ["rustc_codegen_spirv/use-installed-tools"] 14 | use-compiled-tools = ["rustc_codegen_spirv/use-compiled-tools"] 15 | 16 | [dependencies] 17 | compiletest = { version = "0.11.2", package = "compiletest_rs" } 18 | rustc_codegen_spirv = { workspace = true } 19 | rustc_codegen_spirv-target-specs = { workspace = true, features = ["dir_path"] } 20 | clap = { version = "4", features = ["derive"] } 21 | itertools = "0.10.5" 22 | -------------------------------------------------------------------------------- /tests/compiletests/deps-helper/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compiletests-deps-helper" 3 | description = "Shared dependencies of all the compiletest tests" 4 | version = "0.0.0" 5 | publish = false 6 | authors.workspace = true 7 | edition.workspace = true 8 | license.workspace = true 9 | repository.workspace = true 10 | 11 | [dependencies] 12 | spirv-std = { workspace = true } 13 | -------------------------------------------------------------------------------- /tests/compiletests/deps-helper/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/all.stderr: -------------------------------------------------------------------------------- 1 | warning: [Rust-GPU] temporarily re-allowing old-style `#[repr(simd)]` (with fields) 2 | --> $DIR/all.rs:16:1 3 | | 4 | 16 | struct Vec2(T, T); 5 | | ^^^^^^^^^^^^^^ 6 | | 7 | = note: removed upstream by https://github.com/rust-lang/rust/pull/129403 8 | = note: in favor of the new `#[repr(simd)] struct TxN([T; N]);` style 9 | = note: (taking effect since `nightly-2024-09-12` / `1.83.0` stable) 10 | 11 | warning: 1 warning emitted 12 | 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/all_memory_barrier.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn all_memory_barrier() { 8 | spirv_std::arch::all_memory_barrier(); 9 | } 10 | 11 | #[spirv(compute(threads(1, 1, 1)))] 12 | pub fn main() { 13 | unsafe { 14 | all_memory_barrier(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/all_memory_barrier.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 75 4 4 | OpMemoryBarrier %6 %7 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier_with_group_sync::all_memory_barrier_with_group_sync 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn all_memory_barrier_with_group_sync() { 8 | spirv_std::arch::all_memory_barrier_with_group_sync(); 9 | } 10 | 11 | #[spirv(compute(threads(1, 1, 1)))] 12 | pub fn main() { 13 | unsafe { 14 | all_memory_barrier_with_group_sync(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/all_memory_barrier_with_group_sync.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 41 4 4 | OpControlBarrier %6 %7 %8 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/any.stderr: -------------------------------------------------------------------------------- 1 | warning: [Rust-GPU] temporarily re-allowing old-style `#[repr(simd)]` (with fields) 2 | --> $DIR/any.rs:16:1 3 | | 4 | 16 | struct Vec2(T, T); 5 | | ^^^^^^^^^^^^^^ 6 | | 7 | = note: removed upstream by https://github.com/rust-lang/rust/pull/129403 8 | = note: in favor of the new `#[repr(simd)] struct TxN([T; N]);` style 9 | = note: (taking effect since `nightly-2024-09-12` / `1.83.0` stable) 10 | 11 | warning: 1 warning emitted 12 | 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/atomic_i_increment.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::arch::IndexUnchecked; 4 | use spirv_std::spirv; 5 | 6 | #[spirv(compute(threads(64)))] 7 | pub fn main(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buffer: &mut [u32]) { 8 | let reference = unsafe { buffer.index_unchecked_mut(0) }; 9 | 10 | let old = unsafe { 11 | spirv_std::arch::atomic_i_increment::< 12 | _, 13 | { spirv_std::memory::Scope::Workgroup as u32 }, 14 | { spirv_std::memory::Semantics::NONE.bits() as u32 }, 15 | >(reference) 16 | }; 17 | assert!(old == 0); 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/control_barrier.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | #![feature(adt_const_params)] 4 | #![allow(incomplete_features)] 5 | 6 | use spirv_std::memory::{Scope, Semantics}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(fragment)] 10 | pub fn main() { 11 | unsafe { 12 | spirv_std::arch::control_barrier::< 13 | { Scope::Subgroup as u32 }, 14 | { Scope::Subgroup as u32 }, 15 | { Semantics::NONE.bits() }, 16 | >(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/debug_printf_type_checking.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -Ctarget-feature=+ext:SPV_KHR_non_semantic_info 4 | 5 | use spirv_std::spirv; 6 | use spirv_std::{glam::Vec2, macros::debug_printf}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main() { 10 | unsafe { 11 | debug_printf!("%1"); 12 | debug_printf!("%1."); 13 | debug_printf!("%."); 14 | debug_printf!("%.1"); 15 | debug_printf!("%1.1"); 16 | debug_printf!("%1.1v"); 17 | debug_printf!("%1.1v5"); 18 | debug_printf!("%1.1v2"); 19 | debug_printf!("%1.1v2r"); 20 | debug_printf!("%r", 11_i32); 21 | debug_printf!("%f", 11_u32); 22 | debug_printf!("%u", 11.0_f32); 23 | debug_printf!("%v2f", 11.0); 24 | debug_printf!("%f", Vec2::splat(33.3)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/demote_to_helper_invocation.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // 3 | // compile-flags: -C target-feature=+DemoteToHelperInvocationEXT,+ext:SPV_EXT_demote_to_helper_invocation 4 | 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main() { 9 | unsafe { spirv_std::arch::demote_to_helper_invocation() }; 10 | assert!(spirv_std::arch::is_helper_invocation()); 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/derivative.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=derivative::derivative 3 | 4 | use spirv_std::arch::Derivative; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main() { 9 | derivative(); 10 | } 11 | 12 | pub fn derivative() { 13 | Derivative::dfdx(0.); 14 | Derivative::dfdy(0.); 15 | Derivative::fwidth(0.); 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/derivative.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 37 8 4 | %6 = OpDPdx %7 %8 5 | OpLine %5 79 8 6 | %9 = OpDPdy %7 %8 7 | OpLine %5 119 8 8 | %10 = OpFwidth %7 %8 9 | OpNoLine 10 | OpReturn 11 | OpFunctionEnd 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/derivative_control.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+DerivativeControl 3 | // compile-flags: -C llvm-args=--disassemble-fn=derivative_control::derivative 4 | 5 | use spirv_std::arch::Derivative; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main() { 10 | derivative(); 11 | } 12 | 13 | pub fn derivative() { 14 | Derivative::dfdx_fine(0.); 15 | Derivative::dfdy_fine(0.); 16 | Derivative::fwidth_fine(0.); 17 | 18 | Derivative::dfdx_coarse(0.); 19 | Derivative::dfdy_coarse(0.); 20 | Derivative::fwidth_coarse(0.); 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/derivative_control.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 50 8 4 | %6 = OpDPdxFine %7 %8 5 | OpLine %5 92 8 6 | %9 = OpDPdyFine %7 %8 7 | OpLine %5 131 8 8 | %10 = OpFwidthFine %7 %8 9 | OpLine %5 65 8 10 | %11 = OpDPdxCoarse %7 %8 11 | OpLine %5 107 8 12 | %12 = OpDPdyCoarse %7 %8 13 | OpLine %5 143 8 14 | %13 = OpFwidthCoarse %7 %8 15 | OpNoLine 16 | OpReturn 17 | OpFunctionEnd 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/device_memory_barrier.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier::device_memory_barrier 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn device_memory_barrier() { 8 | spirv_std::arch::device_memory_barrier(); 9 | } 10 | 11 | #[spirv(compute(threads(1, 1, 1)))] 12 | pub fn main() { 13 | unsafe { 14 | device_memory_barrier(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/device_memory_barrier.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 75 4 4 | OpMemoryBarrier %6 %7 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier_with_group_sync::device_memory_barrier_with_group_sync 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn device_memory_barrier_with_group_sync() { 8 | spirv_std::arch::device_memory_barrier_with_group_sync(); 9 | } 10 | 11 | #[spirv(compute(threads(1, 1, 1)))] 12 | pub fn main() { 13 | unsafe { 14 | device_memory_barrier_with_group_sync(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/device_memory_barrier_with_group_sync.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 41 4 4 | OpControlBarrier %6 %7 %8 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/emit_stream_vertex.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GeometryStreams 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(geometry(input_lines = 2, output_points = 2))] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::emit_stream_vertex::<2>(); 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/emit_vertex.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+Geometry 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(geometry(input_lines = 2, output_points = 2))] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::emit_vertex(); 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/end_primitive.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+Geometry 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(geometry(input_lines = 2, output_points = 2))] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::end_primitive(); 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/end_stream_primitive.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GeometryStreams 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(geometry(input_lines = 2, output_points = 2))] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::end_stream_primitive::<2>(); 10 | }; 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/execute_callable.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(ray_generation)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0)] 9 | acceleration_structure: &spirv_std::ray_tracing::AccelerationStructure, 10 | #[spirv(callable_data)] payload: &glam::Vec3, 11 | ) { 12 | unsafe { 13 | spirv_std::arch::execute_callable::<_, 5>(payload); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ignore_intersection_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(any_hit)] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::ignore_intersection(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/index_unchecked.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::arch::IndexUnchecked; 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] runtime_array: &mut [u32], 9 | #[spirv(descriptor_set = 1, binding = 1, storage_buffer)] array: &mut [u32; 5], 10 | ) { 11 | unsafe { 12 | *runtime_array.index_unchecked_mut(0) = *array.index_unchecked(0); 13 | *array.index_unchecked_mut(1) = *runtime_array.index_unchecked(1); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/integer_min_and_max.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::arch::{signed_max, signed_min, unsigned_max, unsigned_min}; 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main() { 8 | assert!(unsigned_min(39_u8, 13) == 13); 9 | assert!(unsigned_min(39_u16, 13) == 13); 10 | assert!(unsigned_min(39_u32, 13) == 13); 11 | assert!(unsigned_min(39_u64, 13) == 13); 12 | 13 | assert!(unsigned_max(39_u8, 13) == 39); 14 | assert!(unsigned_max(39_u16, 13) == 39); 15 | assert!(unsigned_max(39_u32, 13) == 39); 16 | assert!(unsigned_max(39_u64, 13) == 39); 17 | 18 | assert!(signed_min(-112_i8, -45) == -112); 19 | assert!(signed_min(-112_i16, -45) == -112); 20 | assert!(signed_min(-112_i32, -45) == -112); 21 | assert!(signed_min(-112_i64, -45) == -112); 22 | 23 | assert!(signed_max(-112_i8, -45) == -45); 24 | assert!(signed_max(-112_i16, -45) == -45); 25 | assert!(signed_max(-112_i32, -45) == -45); 26 | assert!(signed_max(-112_i64, -45) == -45); 27 | } 28 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/kill.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main() { 7 | spirv_std::arch::kill(); 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/memory_barrier.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | #![feature(adt_const_params)] 4 | #![allow(incomplete_features)] 5 | 6 | use spirv_std::memory::{Scope, Semantics}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(fragment)] 10 | pub fn main() { 11 | unsafe { 12 | spirv_std::arch::memory_barrier::< 13 | { Scope::Subgroup as u32 }, 14 | { Semantics::ACQUIRE_RELEASE.bits() | Semantics::UNIFORM_MEMORY.bits() }, 15 | >(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/mesh_shader_output_lines.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::set_mesh_outputs_ext; 6 | use spirv_std::glam::{UVec2, Vec4}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(mesh_ext( 10 | threads(1), 11 | output_vertices = 2, 12 | output_primitives_ext = 1, 13 | output_lines_ext 14 | ))] 15 | pub fn main( 16 | #[spirv(position)] positions: &mut [Vec4; 2], 17 | #[spirv(primitive_line_indices_ext)] indices: &mut [UVec2; 1], 18 | ) { 19 | unsafe { 20 | set_mesh_outputs_ext(2, 1); 21 | } 22 | 23 | positions[0] = Vec4::new(-0.5, 0.5, 0.0, 1.0); 24 | positions[1] = Vec4::new(0.5, 0.5, 0.0, 1.0); 25 | 26 | indices[0] = UVec2::new(0, 1); 27 | } 28 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/mesh_shader_output_points.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::set_mesh_outputs_ext; 6 | use spirv_std::glam::{UVec2, Vec4}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(mesh_ext( 10 | threads(1), 11 | output_vertices = 1, 12 | output_primitives_ext = 1, 13 | output_points 14 | ))] 15 | pub fn main( 16 | #[spirv(position)] positions: &mut [Vec4; 1], 17 | #[spirv(primitive_point_indices_ext)] indices: &mut [u32; 1], 18 | ) { 19 | unsafe { 20 | set_mesh_outputs_ext(1, 1); 21 | } 22 | 23 | positions[0] = Vec4::new(-0.5, 0.5, 0.0, 1.0); 24 | 25 | indices[0] = 0; 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/mesh_shader_output_triangles.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::set_mesh_outputs_ext; 6 | use spirv_std::glam::{UVec3, Vec4}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(mesh_ext( 10 | threads(1), 11 | output_vertices = 3, 12 | output_primitives_ext = 1, 13 | output_triangles_ext 14 | ))] 15 | pub fn main( 16 | #[spirv(position)] positions: &mut [Vec4; 3], 17 | #[spirv(primitive_triangle_indices_ext)] indices: &mut [UVec3; 1], 18 | ) { 19 | unsafe { 20 | set_mesh_outputs_ext(3, 1); 21 | } 22 | 23 | positions[0] = Vec4::new(-0.5, 0.5, 0.0, 1.0); 24 | positions[1] = Vec4::new(0.5, 0.5, 0.0, 1.0); 25 | positions[2] = Vec4::new(0.0, -0.5, 0.0, 1.0); 26 | 27 | indices[0] = UVec3::new(0, 1, 2); 28 | } 29 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/mesh_shader_payload.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::set_mesh_outputs_ext; 6 | use spirv_std::glam::{UVec3, Vec4}; 7 | use spirv_std::spirv; 8 | 9 | pub struct Payload { 10 | pub first: f32, 11 | pub second: f32, 12 | pub third: f32, 13 | } 14 | 15 | #[spirv(mesh_ext( 16 | threads(1), 17 | output_vertices = 3, 18 | output_primitives_ext = 1, 19 | output_triangles_ext 20 | ))] 21 | pub fn main( 22 | #[spirv(position)] positions: &mut [Vec4; 3], 23 | #[spirv(primitive_triangle_indices_ext)] indices: &mut [UVec3; 1], 24 | #[spirv(task_payload_workgroup_ext)] payload: &Payload, 25 | ) { 26 | unsafe { 27 | set_mesh_outputs_ext(3, 1); 28 | } 29 | 30 | positions[0] = payload.first * Vec4::new(-0.5, 0.5, 0.0, 1.0); 31 | positions[1] = payload.second * Vec4::new(0.5, 0.5, 0.0, 1.0); 32 | positions[2] = payload.third * Vec4::new(0.0, -0.5, 0.0, 1.0); 33 | 34 | indices[0] = UVec3::new(0, 1, 2); 35 | } 36 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/mesh_shader_per_primitive.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::set_mesh_outputs_ext; 6 | use spirv_std::glam::{UVec3, Vec4}; 7 | use spirv_std::spirv; 8 | 9 | #[spirv(mesh_ext( 10 | threads(1), 11 | output_vertices = 3, 12 | output_primitives_ext = 1, 13 | output_triangles_ext 14 | ))] 15 | pub fn main( 16 | #[spirv(position)] positions: &mut [Vec4; 3], 17 | out_per_vertex: &mut [u32; 3], 18 | #[spirv(per_primitive_ext)] out_per_primitive: &mut [u32; 1], 19 | #[spirv(primitive_triangle_indices_ext)] indices: &mut [UVec3; 1], 20 | ) { 21 | unsafe { 22 | set_mesh_outputs_ext(3, 1); 23 | } 24 | 25 | positions[0] = Vec4::new(-0.5, 0.5, 0.0, 1.0); 26 | positions[1] = Vec4::new(0.5, 0.5, 0.0, 1.0); 27 | positions[2] = Vec4::new(0.0, -0.5, 0.0, 1.0); 28 | out_per_vertex[0] = 0; 29 | out_per_vertex[1] = 1; 30 | out_per_vertex[2] = 2; 31 | 32 | indices[0] = UVec3::new(0, 1, 2); 33 | out_per_primitive[0] = 42; 34 | } 35 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_confirm_intersection_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | assert!(handle.proceed()); 14 | handle.confirm_intersection(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_barycentrics_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let barycentric_coords: glam::Vec2 = handle.get_candidate_intersection_barycentrics(); 14 | let barycentric_coords: glam::Vec2 = handle.get_committed_intersection_barycentrics(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_candidate_aabb_opaque_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | handle.get_intersection_candidate_aabb_opaque(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_front_face_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | assert!(handle.get_candidate_intersection_front_face()); 14 | assert!(handle.get_committed_intersection_front_face()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_geometry_index_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let t = handle.get_candidate_intersection_geometry_index(); 14 | let t = handle.get_committed_intersection_geometry_index(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_instance_custom_index_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let index = handle.get_candidate_intersection_instance_custom_index(); 14 | let index = handle.get_committed_intersection_instance_custom_index(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_instance_id_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let id = handle.get_candidate_intersection_instance_id(); 14 | let id = handle.get_committed_intersection_instance_id(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_object_ray_direction_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let direction: glam::Vec3 = handle.get_candidate_intersection_object_ray_direction(); 14 | let direction: glam::Vec3 = handle.get_committed_intersection_object_ray_direction(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_object_ray_origin_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let origin: glam::Vec3 = handle.get_candidate_intersection_object_ray_origin(); 14 | let origin: glam::Vec3 = handle.get_committed_intersection_object_ray_origin(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_object_to_world_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let matrix: [glam::Vec3; 4] = handle.get_candidate_intersection_object_to_world(); 14 | let matrix: [glam::Vec3; 4] = handle.get_committed_intersection_object_to_world(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_primitive_index_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | handle.get_candidate_intersection_primitive_index(); 14 | handle.get_committed_intersection_primitive_index(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_shader_binding_table_record_offset_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let offset = handle.get_candidate_intersection_shader_binding_table_record_offset(); 14 | let offset = handle.get_committed_intersection_shader_binding_table_record_offset(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_t_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let t = handle.get_candidate_intersection_t(); 14 | let t = handle.get_committed_intersection_t(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_intersection_type_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | handle.get_candidate_intersection_type(); 14 | handle.get_committed_intersection_type(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_ray_flags_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let flags = handle.get_ray_flags(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_ray_t_min_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let tmin = handle.get_ray_t_min(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_world_ray_direction_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let direction: glam::Vec3 = handle.get_world_ray_direction(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_get_world_ray_origin_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | let origin: glam::Vec3 = handle.get_world_ray_origin(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_initialize_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+RayQueryKHR,+ext:SPV_KHR_ray_tracing,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | #[spirv(descriptor_set = 0, binding = 0)] acceleration_structure: &AccelerationStructure, 11 | #[spirv(ray_payload)] payload: &mut Vec3, 12 | ) { 13 | unsafe { 14 | spirv_std::ray_query!(let mut ray_query); 15 | 16 | ray_query.initialize( 17 | acceleration_structure, 18 | RayFlags::NONE, 19 | 0, 20 | glam::vec3(1.0, 2.0, 3.0), 21 | 0.5, 22 | glam::vec3(3.0, 2.0, 1.0), 23 | 1.0, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/ray_query_terminate_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayQueryKHR,+ext:SPV_KHR_ray_query 3 | 4 | use glam::Vec3; 5 | use spirv_std::ray_tracing::{AccelerationStructure, RayFlags, RayQuery}; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(descriptor_set = 0, binding = 0)] accel: &AccelerationStructure) { 10 | unsafe { 11 | spirv_std::ray_query!(let mut handle); 12 | handle.initialize(accel, RayFlags::NONE, 0, Vec3::ZERO, 0.0, Vec3::ZERO, 0.0); 13 | assert!(handle.proceed()); 14 | handle.terminate(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/read_clock_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+Int64,+ShaderClockKHR,+ext:SPV_KHR_shader_clock 3 | 4 | use glam::UVec2; 5 | use spirv_std::spirv; 6 | use spirv_std::{ 7 | arch::{read_clock_khr, read_clock_uvec2_khr}, 8 | memory::Scope, 9 | }; 10 | 11 | #[spirv(fragment)] 12 | pub fn main() { 13 | let clock_time = unsafe { read_clock_khr::<{ Scope::Subgroup as u32 }>() }; 14 | 15 | let clock_time_uvec2: UVec2 = 16 | unsafe { read_clock_uvec2_khr::<_, { Scope::Subgroup as u32 }>() }; 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/report_intersection_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(intersection)] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::report_intersection(2.0, 4); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_ballot.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformBallot,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_ballot::subgroup_ballot 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn subgroup_ballot(predicate: bool) -> bool { 8 | let ballot = spirv_std::arch::subgroup_ballot(predicate); 9 | spirv_std::arch::subgroup_inverse_ballot(ballot) 10 | } 11 | 12 | #[spirv(compute(threads(1, 1, 1)))] 13 | pub fn main() { 14 | unsafe { 15 | subgroup_ballot(true); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_ballot.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 380 8 5 | %7 = OpGroupNonUniformBallot %8 %9 %4 6 | OpLine %6 416 8 7 | %10 = OpGroupNonUniformInverseBallot %2 %9 %7 8 | OpNoLine 9 | OpReturnValue %10 10 | OpFunctionEnd 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformBallot,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_ballot_bit_count::subgroup_ballot_bit_count 4 | 5 | use spirv_std::arch::{GroupOperation, SubgroupMask}; 6 | use spirv_std::spirv; 7 | 8 | unsafe fn subgroup_ballot_bit_count(ballot: SubgroupMask) -> u32 { 9 | spirv_std::arch::subgroup_ballot_bit_count(ballot) 10 | } 11 | 12 | #[spirv(compute(threads(1, 1, 1)))] 13 | pub fn main() { 14 | unsafe { 15 | subgroup_ballot_bit_count(spirv_std::arch::subgroup_ballot(true)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_ballot_bit_count.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpLabel 4 | OpLine %7 512 0 5 | %8 = OpGroupNonUniformBallotBitCount %2 %9 Reduce %4 6 | OpNoLine 7 | OpReturnValue %8 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformBallot,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_broadcast_first::subgroup_broadcast_first 4 | 5 | use glam::Vec3; 6 | use spirv_std::spirv; 7 | 8 | unsafe fn subgroup_broadcast_first(vec: Vec3) -> Vec3 { 9 | spirv_std::arch::subgroup_broadcast_first::(vec) 10 | } 11 | 12 | #[spirv(compute(threads(1, 1, 1)))] 13 | pub fn main() { 14 | unsafe { 15 | subgroup_broadcast_first(Vec3::new(1., 2., 3.)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_broadcast_first.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 347 8 5 | %7 = OpGroupNonUniformBroadcastFirst %2 %8 %4 6 | OpNoLine 7 | OpReturnValue %7 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_builtins.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniformBallot,+ext:SPV_KHR_vulkan_memory_model 3 | 4 | use spirv_std::arch::SubgroupMask; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(compute(threads(1, 1, 1)))] 8 | pub fn main( 9 | #[spirv(subgroup_id)] subgroup_id: u32, 10 | #[spirv(subgroup_local_invocation_id)] subgroup_local_invocation_id: u32, 11 | #[spirv(subgroup_eq_mask)] subgroup_eq_mask: SubgroupMask, 12 | #[spirv(subgroup_ge_mask)] subgroup_ge_mask: SubgroupMask, 13 | #[spirv(subgroup_gt_mask)] subgroup_gt_mask: SubgroupMask, 14 | #[spirv(subgroup_le_mask)] subgroup_le_mask: SubgroupMask, 15 | #[spirv(subgroup_lt_mask)] subgroup_lt_mask: SubgroupMask, 16 | ) { 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_elect.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_elect::subgroup_elect 4 | 5 | use spirv_std::spirv; 6 | 7 | unsafe fn subgroup_elect() -> bool { 8 | spirv_std::arch::subgroup_elect() 9 | } 10 | 11 | #[spirv(compute(threads(1, 1, 1)))] 12 | pub fn main() { 13 | unsafe { 14 | subgroup_elect(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_elect.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 182 8 4 | %6 = OpGroupNonUniformElect %2 %7 5 | OpNoLine 6 | OpReturnValue %6 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+GroupNonUniformClustered,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_i_add_clustered::subgroup_i_add_clustered 4 | 5 | use glam::UVec3; 6 | use spirv_std::arch::{GroupOperation, SubgroupMask}; 7 | use spirv_std::spirv; 8 | 9 | unsafe fn subgroup_i_add_clustered(value: u32) -> u32 { 10 | spirv_std::arch::subgroup_clustered_i_add::<8, _>(value) 11 | } 12 | 13 | #[spirv(compute(threads(32, 1, 1)))] 14 | pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { 15 | unsafe { 16 | subgroup_i_add_clustered(local_invocation_id.x); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_clustered.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 810 0 5 | %7 = OpGroupNonUniformIAdd %2 %8 ClusteredReduce %4 %9 6 | OpNoLine 7 | OpReturnValue %7 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_i_add_exclusive_scan::subgroup_i_add_exclusive_scan 4 | 5 | use glam::UVec3; 6 | use spirv_std::arch::{GroupOperation, SubgroupMask}; 7 | use spirv_std::spirv; 8 | 9 | unsafe fn subgroup_i_add_exclusive_scan(value: u32) -> u32 { 10 | spirv_std::arch::subgroup_exclusive_i_add(value) 11 | } 12 | 13 | #[spirv(compute(threads(32, 1, 1)))] 14 | pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { 15 | unsafe { 16 | subgroup_i_add_exclusive_scan(local_invocation_id.x); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_exclusive_scan.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 797 0 5 | %7 = OpGroupNonUniformIAdd %2 %8 ExclusiveScan %4 6 | OpNoLine 7 | OpReturnValue %7 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_i_add_inclusive_scan::subgroup_i_add_inclusive_scan 4 | 5 | use glam::UVec3; 6 | use spirv_std::arch::{GroupOperation, SubgroupMask}; 7 | use spirv_std::spirv; 8 | 9 | unsafe fn subgroup_i_add_inclusive_scan(value: u32) -> u32 { 10 | spirv_std::arch::subgroup_inclusive_i_add(value) 11 | } 12 | 13 | #[spirv(compute(threads(32, 1, 1)))] 14 | pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { 15 | unsafe { 16 | subgroup_i_add_inclusive_scan(local_invocation_id.x); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_inclusive_scan.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 797 0 5 | %7 = OpGroupNonUniformIAdd %2 %8 InclusiveScan %4 6 | OpNoLine 7 | OpReturnValue %7 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+GroupNonUniform,+GroupNonUniformArithmetic,+ext:SPV_KHR_vulkan_memory_model 3 | // compile-flags: -C llvm-args=--disassemble-fn=subgroup_i_add_reduce::subgroup_i_add_reduce 4 | 5 | use glam::UVec3; 6 | use spirv_std::arch::{GroupOperation, SubgroupMask}; 7 | use spirv_std::spirv; 8 | 9 | unsafe fn subgroup_i_add_reduce(value: u32) -> u32 { 10 | spirv_std::arch::subgroup_i_add(value) 11 | } 12 | 13 | #[spirv(compute(threads(32, 1, 1)))] 14 | pub fn main(#[spirv(local_invocation_id)] local_invocation_id: UVec3) { 15 | unsafe { 16 | subgroup_i_add_reduce(local_invocation_id.x); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/subgroup/subgroup_i_add_reduce.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpLabel 4 | OpLine %6 797 0 5 | %7 = OpGroupNonUniformIAdd %2 %8 Reduce %4 6 | OpNoLine 7 | OpReturnValue %7 8 | OpFunctionEnd 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/task_shader.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::emit_mesh_tasks_ext; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(task_ext(threads(1)))] 9 | pub fn main() { 10 | unsafe { 11 | emit_mesh_tasks_ext(1, 2, 3); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/task_shader_mispile.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::emit_mesh_tasks_ext; 6 | use spirv_std::spirv; 7 | 8 | #[spirv(task_ext(threads(1)))] 9 | pub fn main(#[spirv(push_constant)] push: &u32) { 10 | let count = 20 / *push; 11 | unsafe { 12 | emit_mesh_tasks_ext(1, 2, 3); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/task_shader_payload.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // only-vulkan1.2 3 | // compile-flags: -Ctarget-feature=+MeshShadingEXT,+ext:SPV_EXT_mesh_shader 4 | 5 | use spirv_std::arch::emit_mesh_tasks_ext_payload; 6 | use spirv_std::spirv; 7 | 8 | pub struct Payload { 9 | pub first: u32, 10 | pub second: i32, 11 | } 12 | 13 | #[spirv(task_ext(threads(1)))] 14 | pub fn main(#[spirv(task_payload_workgroup_ext)] payload: &mut Payload) { 15 | payload.first = 1; 16 | payload.second = 2; 17 | 18 | unsafe { 19 | emit_mesh_tasks_ext_payload(3, 4, 5, payload); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/terminate_ray_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(any_hit)] 7 | pub fn main() { 8 | unsafe { 9 | spirv_std::arch::terminate_ray(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/trace_ray_khr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+RayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(ray_generation)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0)] 9 | acceleration_structure: &spirv_std::ray_tracing::AccelerationStructure, 10 | #[spirv(ray_payload)] payload: &mut glam::Vec3, 11 | ) { 12 | unsafe { 13 | acceleration_structure.trace_ray( 14 | spirv_std::ray_tracing::RayFlags::NONE, 15 | 0, 16 | 0, 17 | 0, 18 | 0, 19 | glam::vec3(1.0, 2.0, 3.0), 20 | 0.5, 21 | glam::vec3(3.0, 2.0, 1.0), 22 | 1.0, 23 | payload, 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/vector_extract_dynamic.rs: -------------------------------------------------------------------------------- 1 | // Test `OpVectorExtractDynamic` 2 | // build-pass 3 | 4 | use spirv_std::arch; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main() { 9 | let vector = glam::Vec2::new(1.0, 2.0); 10 | let element = unsafe { arch::vector_extract_dynamic(vector, 1) }; 11 | assert!(2.0 == element); 12 | let uvector = glam::UVec2::new(1, 2); 13 | let uelement = unsafe { arch::vector_extract_dynamic(uvector, 1) }; 14 | assert!(2 == uelement); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/vector_insert_dynamic.rs: -------------------------------------------------------------------------------- 1 | // Test `OpVectorInsertDynamic` 2 | // build-pass 3 | 4 | use spirv_std::arch; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main() { 9 | let vector = glam::Vec2::new(1.0, 2.0); 10 | let expected = glam::Vec2::new(1.0, 3.0); 11 | let new_vector = unsafe { arch::vector_insert_dynamic(vector, 1, 3.0) }; 12 | assert!(new_vector == expected); 13 | let uvector = glam::UVec2::new(1, 2); 14 | let uexpected = glam::UVec2::new(1, 3); 15 | let unew_vector = unsafe { arch::vector_insert_dynamic(uvector, 1, 3) }; 16 | assert!(unew_vector == uexpected); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/workgroup_memory_barrier.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier::workgroup_memory_barrier 3 | 4 | use spirv_std::spirv; 5 | 6 | unsafe fn workgroup_memory_barrier() { 7 | spirv_std::arch::workgroup_memory_barrier(); 8 | } 9 | 10 | #[spirv(compute(threads(1, 1, 1)))] 11 | pub fn main() { 12 | unsafe { 13 | workgroup_memory_barrier(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/workgroup_memory_barrier.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 75 4 4 | OpMemoryBarrier %6 %7 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=workgroup_memory_barrier_with_group_sync::workgroup_memory_barrier_with_group_sync 3 | 4 | use spirv_std::spirv; 5 | 6 | unsafe fn workgroup_memory_barrier_with_group_sync() { 7 | spirv_std::arch::workgroup_memory_barrier_with_group_sync(); 8 | } 9 | 10 | #[spirv(compute(threads(1, 1, 1)))] 11 | pub fn main() { 12 | unsafe { 13 | workgroup_memory_barrier_with_group_sync(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/arch/workgroup_memory_barrier_with_group_sync.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 41 4 4 | OpControlBarrier %6 %6 %7 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/byte_addressable_buffer/arr.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | use spirv_std::{ByteAddressableBuffer, glam::Vec4}; 5 | 6 | #[spirv(fragment)] 7 | pub fn load( 8 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], 9 | out: &mut [i32; 4], 10 | ) { 11 | unsafe { 12 | let buf = ByteAddressableBuffer::from_slice(buf); 13 | *out = buf.load(5); 14 | } 15 | } 16 | 17 | #[spirv(fragment)] 18 | pub fn load_mut( 19 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 20 | out: &mut [i32; 4], 21 | ) { 22 | unsafe { 23 | let buf = ByteAddressableBuffer::from_mut_slice(buf); 24 | *out = buf.load(5); 25 | } 26 | } 27 | 28 | #[spirv(fragment)] 29 | pub fn store( 30 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 31 | #[spirv(flat)] val: [i32; 4], 32 | ) { 33 | unsafe { 34 | let mut buf = ByteAddressableBuffer::from_mut_slice(buf); 35 | buf.store(5, val); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/compiletests/ui/byte_addressable_buffer/big_struct.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::ByteAddressableBuffer; 4 | use spirv_std::spirv; 5 | 6 | pub struct BigStruct { 7 | a: u32, 8 | b: u32, 9 | c: u32, 10 | d: u32, 11 | e: u32, 12 | f: u32, 13 | } 14 | 15 | #[spirv(fragment)] 16 | pub fn load( 17 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], 18 | out: &mut BigStruct, 19 | ) { 20 | unsafe { 21 | let buf = ByteAddressableBuffer::from_slice(buf); 22 | *out = buf.load(5); 23 | } 24 | } 25 | 26 | #[spirv(fragment)] 27 | pub fn load_mut( 28 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 29 | out: &mut BigStruct, 30 | ) { 31 | unsafe { 32 | let buf = ByteAddressableBuffer::from_mut_slice(buf); 33 | *out = buf.load(5); 34 | } 35 | } 36 | 37 | #[spirv(fragment)] 38 | pub fn store( 39 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 40 | #[spirv(flat)] val: BigStruct, 41 | ) { 42 | unsafe { 43 | let mut buf = ByteAddressableBuffer::from_mut_slice(buf); 44 | buf.store(5, val); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/compiletests/ui/byte_addressable_buffer/empty_struct.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::ByteAddressableBuffer; 4 | use spirv_std::spirv; 5 | 6 | pub struct EmptyStruct {} 7 | 8 | #[spirv(fragment)] 9 | pub fn load( 10 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], 11 | out: &mut EmptyStruct, 12 | ) { 13 | unsafe { 14 | let buf = ByteAddressableBuffer::from_slice(buf); 15 | *out = buf.load(5); 16 | } 17 | } 18 | 19 | #[spirv(fragment)] 20 | pub fn load_mut( 21 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 22 | out: &mut EmptyStruct, 23 | ) { 24 | unsafe { 25 | let buf = ByteAddressableBuffer::from_mut_slice(buf); 26 | *out = buf.load(5); 27 | } 28 | } 29 | 30 | #[spirv(fragment)] 31 | pub fn store(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32]) { 32 | let val = EmptyStruct {}; 33 | unsafe { 34 | let mut buf = ByteAddressableBuffer::from_mut_slice(buf); 35 | buf.store(5, val); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/compiletests/ui/byte_addressable_buffer/f32.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::ByteAddressableBuffer; 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn load(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], out: &mut f32) { 8 | unsafe { 9 | let buf = ByteAddressableBuffer::from_slice(buf); 10 | *out = buf.load(5); 11 | } 12 | } 13 | 14 | #[spirv(fragment)] 15 | pub fn load_mut( 16 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 17 | out: &mut f32, 18 | ) { 19 | unsafe { 20 | let buf = ByteAddressableBuffer::from_mut_slice(buf); 21 | *out = buf.load(5); 22 | } 23 | } 24 | 25 | #[spirv(fragment)] 26 | pub fn store(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], val: f32) { 27 | unsafe { 28 | let mut buf = ByteAddressableBuffer::from_mut_slice(buf); 29 | buf.store(5, val); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/compiletests/ui/byte_addressable_buffer/u32.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::ByteAddressableBuffer; 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn load(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &[u32], out: &mut u32) { 8 | unsafe { 9 | let buf = ByteAddressableBuffer::from_slice(buf); 10 | *out = buf.load(5); 11 | } 12 | } 13 | 14 | #[spirv(fragment)] 15 | pub fn load_mut( 16 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 17 | out: &mut u32, 18 | ) { 19 | unsafe { 20 | let buf = ByteAddressableBuffer::from_mut_slice(buf); 21 | *out = buf.load(5); 22 | } 23 | } 24 | 25 | #[spirv(fragment)] 26 | pub fn store( 27 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] buf: &mut [u32], 28 | #[spirv(flat)] val: u32, 29 | ) { 30 | unsafe { 31 | let mut buf = ByteAddressableBuffer::from_mut_slice(buf); 32 | buf.store(5, val); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/add_two_ints.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=add_two_ints::add_two_ints 3 | 4 | use spirv_std::spirv; 5 | 6 | fn add_two_ints(x: u32, y: u32) -> u32 { 7 | x + y 8 | } 9 | #[spirv(fragment)] 10 | pub fn main() { 11 | add_two_ints(2, 3); 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/add_two_ints.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpFunctionParameter %2 4 | %6 = OpLabel 5 | OpLine %7 7 4 6 | %8 = OpIAdd %2 %4 %5 7 | OpNoLine 8 | OpReturnValue %8 9 | OpFunctionEnd 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/asm.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=asm::asm 3 | 4 | use core::arch::asm; 5 | use spirv_std::spirv; 6 | 7 | fn asm() { 8 | unsafe { 9 | asm!( 10 | "%int = OpTypeInt 32 0", 11 | "%scope = OpConstant %int 3", 12 | "%semantics = OpConstant %int 72", 13 | "OpMemoryBarrier %scope %semantics", 14 | ); 15 | } 16 | } 17 | #[spirv(fragment)] 18 | pub fn main() { 19 | asm(); 20 | } 21 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/asm.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 9 8 4 | OpMemoryBarrier %6 %7 5 | OpNoLine 6 | OpReturn 7 | OpFunctionEnd 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/asm_add_two_ints.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=asm_add_two_ints::add_two_ints 3 | 4 | use core::arch::asm; 5 | use spirv_std::spirv; 6 | 7 | fn add_two_ints(x: u32, y: u32) -> u32 { 8 | let result; 9 | unsafe { 10 | asm!( 11 | "{0} = OpIAdd typeof{0} {1} {2}", 12 | out(reg) result, 13 | in(reg) x, 14 | in(reg) y, 15 | ); 16 | } 17 | result 18 | } 19 | #[spirv(fragment)] 20 | pub fn main() { 21 | add_two_ints(2, 3); 22 | } 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/asm_add_two_ints.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpFunctionParameter %2 4 | %6 = OpLabel 5 | OpLine %7 10 8 6 | %8 = OpIAdd %2 %4 %5 7 | OpNoLine 8 | OpReturnValue %8 9 | OpFunctionEnd 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/asm_op_decorate.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpCapability RuntimeDescriptorArray 8 | OpExtension "SPV_EXT_descriptor_indexing" 9 | OpExtension "SPV_KHR_shader_clock" 10 | OpMemoryModel Logical Simple 11 | OpEntryPoint Fragment %1 "main" 12 | OpExecutionMode %1 OriginUpperLeft 13 | %2 = OpString "$OPSTRING_FILENAME/asm_op_decorate.rs" 14 | OpName %3 "asm_op_decorate::main" 15 | OpName %4 "asm_op_decorate::add_decorate" 16 | OpDecorate %5 Binding 0 17 | OpDecorate %5 DescriptorSet 0 18 | %6 = OpTypeVoid 19 | %7 = OpTypeFunction %6 20 | %8 = OpTypeFloat 32 21 | %9 = OpTypeImage %8 2D 0 0 0 1 Unknown 22 | %10 = OpTypeSampledImage %9 23 | %11 = OpTypePointer UniformConstant %10 24 | %12 = OpTypeRuntimeArray %10 25 | %13 = OpTypePointer UniformConstant %12 26 | %5 = OpVariable %13 UniformConstant 27 | %14 = OpTypeInt 32 0 28 | %15 = OpConstant %14 1 29 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/complex_image_sample_inst.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %2 3 | %5 = OpFunctionParameter %6 4 | %7 = OpFunctionParameter %6 5 | %8 = OpFunctionParameter %9 6 | %10 = OpFunctionParameter %9 7 | %11 = OpLabel 8 | OpLine %12 18 8 9 | %13 = OpAccessChain %14 %15 %16 10 | %17 = OpLoad %18 %13 11 | %19 = OpImageSampleProjExplicitLod %2 %17 %4 Grad|ConstOffset %5 %7 %20 12 | OpNoLine 13 | OpReturnValue %19 14 | OpFunctionEnd 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/custom_entry_point.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "custom_entry_point"] 2 | 3 | // build-pass 4 | // compile-flags: -C llvm-args=--disassemble-globals 5 | // normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> "" 6 | // normalize-stderr-test "OpSource .*\n" -> "" 7 | // normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> "" 8 | // normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple" 9 | 10 | use spirv_std::spirv; 11 | 12 | #[spirv(fragment(entry_point_name = "hello_world"))] 13 | pub fn main() {} 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/custom_entry_point.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpExtension "SPV_KHR_shader_clock" 8 | OpMemoryModel Logical Simple 9 | OpEntryPoint Fragment %1 "hello_world" 10 | OpExecutionMode %1 OriginUpperLeft 11 | %2 = OpString "$OPSTRING_FILENAME/custom_entry_point.rs" 12 | OpName %3 "custom_entry_point::main" 13 | %4 = OpTypeVoid 14 | %5 = OpTypeFunction %4 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/entry-pass-mode-cast-array.rs: -------------------------------------------------------------------------------- 1 | // This is a similar setup to the `issue-731` test, but instead of "just" the 2 | // missing copy out of the global (`Input`) `OpVariable`, small enough types 3 | // would fail much earlier (by generating unsupported pointer casts). 4 | // (Just like `issue-373`, the problem was the use of `PassMode::Cast`, through 5 | // the default Rust ABI adjustments, that we now override through query hooks) 6 | 7 | // build-pass 8 | // compile-flags: -C llvm-args=--disassemble-entry=main 9 | 10 | use spirv_std::spirv; 11 | 12 | #[spirv(fragment)] 13 | pub fn main(mut in_array: [f32; 2], out_array: &mut [f32; 2]) { 14 | in_array[0] += 1.0; 15 | *out_array = in_array; 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/entry-pass-mode-cast-array.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 13 12 4 | %6 = OpLoad %7 %8 5 | OpLine %5 14 4 6 | %9 = OpULessThan %10 %11 %12 7 | OpNoLine 8 | OpSelectionMerge %13 None 9 | OpBranchConditional %9 %14 %15 10 | %14 = OpLabel 11 | OpBranch %13 12 | %15 = OpLabel 13 | OpReturn 14 | %13 = OpLabel 15 | OpLine %5 14 4 16 | %16 = OpCompositeExtract %17 %6 0 17 | %18 = OpFAdd %17 %16 %19 18 | %20 = OpCompositeInsert %7 %18 %6 0 19 | OpLine %5 15 4 20 | OpStore %21 %20 21 | OpNoLine 22 | OpReturn 23 | OpFunctionEnd 24 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/generic-fn-op-name.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "generic_fn_op_name"] 2 | // 3 | // Test that generic functions' `OpName` correctly include generic arguments. 4 | 5 | // build-pass 6 | // compile-flags: -C llvm-args=--disassemble-globals 7 | // normalize-stderr-test "OpCapability VulkanMemoryModel\n" -> "" 8 | // normalize-stderr-test "OpSource .*\n" -> "" 9 | // normalize-stderr-test "OpExtension .SPV_KHR_vulkan_memory_model.\n" -> "" 10 | // normalize-stderr-test "OpMemoryModel Logical Vulkan" -> "OpMemoryModel Logical Simple" 11 | #![feature(adt_const_params)] 12 | #![allow(incomplete_features)] 13 | 14 | use spirv_std::spirv; 15 | 16 | // HACK(eddyb) not using `spirv_std::image::Dimensionality` as that `enum` doesn't 17 | // actually implement `ConstParamTy` (nor do we need *that* `enum`, just any). 18 | #[derive(PartialEq, Eq, PartialOrd, Ord, core::marker::ConstParamTy)] 19 | enum Dimensionality { 20 | OneD, 21 | TwoD, 22 | ThreeD, 23 | } 24 | 25 | fn generic() {} 26 | 27 | #[spirv(fragment)] 28 | pub fn main() { 29 | generic::(); 30 | } 31 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/generic-fn-op-name.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpExtension "SPV_KHR_shader_clock" 8 | OpMemoryModel Logical Simple 9 | OpEntryPoint Fragment %1 "main" 10 | OpExecutionMode %1 OriginUpperLeft 11 | %2 = OpString "$OPSTRING_FILENAME/generic-fn-op-name.rs" 12 | OpName %3 "generic_fn_op_name::main" 13 | OpName %4 "generic_fn_op_name::generic::" 14 | %5 = OpTypeVoid 15 | %6 = OpTypeFunction %5 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/index_user_dst.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "index_user_dst"] 2 | 3 | // build-pass 4 | // compile-flags: -C llvm-args=--disassemble-entry=main 5 | 6 | use spirv_std::spirv; 7 | 8 | #[spirv(fragment)] 9 | pub fn main(#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] slice: &mut [f32]) { 10 | let float: f32 = slice[0]; 11 | let _ = float; 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/index_user_dst.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 9 12 4 | %6 = OpInBoundsAccessChain %7 %8 %9 5 | %10 = OpArrayLength %11 %8 0 6 | OpLine %5 10 21 7 | %12 = OpULessThan %13 %9 %10 8 | OpNoLine 9 | OpSelectionMerge %14 None 10 | OpBranchConditional %12 %15 %16 11 | %15 = OpLabel 12 | OpBranch %14 13 | %16 = OpLabel 14 | OpReturn 15 | %14 = OpLabel 16 | OpLine %5 10 21 17 | %17 = OpInBoundsAccessChain %18 %6 %9 18 | %19 = OpLoad %20 %17 19 | OpNoLine 20 | OpReturn 21 | OpFunctionEnd 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-1062.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "issue_1062"] 2 | 3 | // Test that rotates take the correct path for non-zero bit amounts. 4 | 5 | // build-pass 6 | // compile-flags: -C llvm-args=--disassemble-entry=main 7 | 8 | use spirv_std::spirv; 9 | 10 | #[spirv(fragment)] 11 | pub fn main(#[spirv(flat)] x: u32, #[spirv(flat)] s: u32, out: &mut (u32, u32)) { 12 | *out = (x.rotate_left(s), x.rotate_right(s)); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-1062.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 11 12 4 | %6 = OpLoad %7 %8 5 | OpLine %5 11 35 6 | %9 = OpLoad %7 %10 7 | OpLine %11 1199 4 8 | %12 = OpBitwiseAnd %7 %9 %13 9 | %14 = OpISub %7 %15 %12 10 | %16 = OpShiftLeftLogical %7 %6 %12 11 | %17 = OpShiftRightLogical %7 %6 %14 12 | %18 = OpBitwiseOr %7 %16 %17 13 | %19 = OpIEqual %20 %12 %21 14 | %22 = OpSelect %7 %19 %6 %18 15 | %23 = OpBitwiseAnd %7 %9 %13 16 | %24 = OpISub %7 %15 %23 17 | %25 = OpShiftRightLogical %7 %6 %23 18 | %26 = OpShiftLeftLogical %7 %6 %24 19 | %27 = OpBitwiseOr %7 %25 %26 20 | %28 = OpIEqual %20 %23 %21 21 | %29 = OpSelect %7 %28 %6 %27 22 | OpLine %5 12 4 23 | %30 = OpInBoundsAccessChain %31 %32 %21 24 | OpStore %30 %22 25 | %33 = OpInBoundsAccessChain %31 %32 %34 26 | OpStore %33 %29 27 | OpNoLine 28 | OpReturn 29 | OpFunctionEnd 30 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-373.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "issue_373"] 2 | 3 | // Test that returning a single-scalar-field `#[repr(C)] struct` doesn't generate 4 | // unsupported pointer casts (the problem was the use of `PassMode::Cast`, through 5 | // the default Rust ABI adjustments, that we now override through query hooks). 6 | 7 | // build-pass 8 | // compile-flags: -C llvm-args=--disassemble-entry=main 9 | 10 | use spirv_std::spirv; 11 | 12 | #[derive(Copy, Clone)] 13 | #[repr(C)] 14 | pub struct S { 15 | x: f32, 16 | } 17 | 18 | fn f() -> S { 19 | S { x: 2.0 } 20 | } 21 | 22 | #[spirv(fragment)] 23 | pub fn main(out: &mut f32) { 24 | *out = f().x; 25 | } 26 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-373.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 24 11 4 | %6 = OpFunctionCall %7 %8 5 | %9 = OpCompositeExtract %10 %6 0 6 | OpLine %5 24 4 7 | OpStore %11 %9 8 | OpNoLine 9 | OpReturn 10 | OpFunctionEnd 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-723-output.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpExtension "SPV_KHR_shader_clock" 8 | OpMemoryModel Logical Simple 9 | OpEntryPoint Fragment %1 "main" %2 10 | OpExecutionMode %1 OriginUpperLeft 11 | %3 = OpString "$OPSTRING_FILENAME/issue-723-output.rs" 12 | OpName %4 "issue_723_output::main" 13 | OpDecorate %2 Location 0 14 | %5 = OpTypeFloat 32 15 | %6 = OpTypeVector %5 4 16 | %7 = OpTypePointer Output %6 17 | %8 = OpTypeVoid 18 | %9 = OpTypeFunction %8 19 | %2 = OpVariable %7 Output 20 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-731.rs: -------------------------------------------------------------------------------- 1 | // Test that non-immediate (i.e. not one of scalar/scalar-pair/vector) inputs 2 | // get properly copied out of the global (`Input`) `OpVariable` and mutation is 3 | // only ever done on `fn`-local `OpVariable`s, not on the original global. 4 | 5 | // build-pass 6 | // compile-flags: -C llvm-args=--disassemble-entry=main 7 | 8 | use spirv_std::spirv; 9 | 10 | #[spirv(fragment)] 11 | pub fn main(mut in_array: [f32; 3], out_array: &mut [f32; 3]) { 12 | in_array[0] += 1.0; 13 | *out_array = in_array; 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/issue-731.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 11 12 4 | %6 = OpLoad %7 %8 5 | OpLine %5 12 4 6 | %9 = OpULessThan %10 %11 %12 7 | OpNoLine 8 | OpSelectionMerge %13 None 9 | OpBranchConditional %9 %14 %15 10 | %14 = OpLabel 11 | OpBranch %13 12 | %15 = OpLabel 13 | OpReturn 14 | %13 = OpLabel 15 | OpLine %5 12 4 16 | %16 = OpCompositeExtract %17 %6 0 17 | %18 = OpFAdd %17 %16 %19 18 | %20 = OpCompositeInsert %7 %18 %6 0 19 | OpLine %5 13 4 20 | OpStore %21 %20 21 | OpNoLine 22 | OpReturn 23 | OpFunctionEnd 24 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/non-writable-storage_buffer.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpExtension "SPV_KHR_shader_clock" 8 | OpMemoryModel Logical Simple 9 | OpEntryPoint Fragment %1 "main" 10 | OpExecutionMode %1 OriginUpperLeft 11 | %2 = OpString "$OPSTRING_FILENAME/non-writable-storage_buffer.rs" 12 | OpName %3 "buf_imm" 13 | OpName %4 "buf_mut" 14 | OpName %5 "buf_interior_mut" 15 | OpDecorate %6 Block 16 | OpMemberDecorate %6 0 Offset 0 17 | OpDecorate %3 NonWritable 18 | OpDecorate %3 Binding 0 19 | OpDecorate %3 DescriptorSet 0 20 | OpDecorate %4 Binding 1 21 | OpDecorate %4 DescriptorSet 0 22 | OpDecorate %5 Binding 2 23 | OpDecorate %5 DescriptorSet 0 24 | %7 = OpTypeVoid 25 | %8 = OpTypeFunction %7 26 | %9 = OpTypeInt 32 0 27 | %10 = OpTypePointer StorageBuffer %9 28 | %6 = OpTypeStruct %9 29 | %11 = OpTypePointer StorageBuffer %6 30 | %3 = OpVariable %11 StorageBuffer 31 | %12 = OpConstant %9 0 32 | %4 = OpVariable %11 StorageBuffer 33 | %5 = OpVariable %11 StorageBuffer 34 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/pass-mode-cast-struct.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "pass_mode_cast_struct"] 2 | 3 | // Test that a small enough `struct` doesn't generate unsupported pointer casts. 4 | // (Just like `issue-373`, the problem was the use of `PassMode::Cast`, through 5 | // the default Rust ABI adjustments, that we now override through query hooks) 6 | 7 | // build-pass 8 | // compile-flags: -C llvm-args=--disassemble-entry=main 9 | 10 | use spirv_std::spirv; 11 | 12 | struct Foo { 13 | a: u32, 14 | b: u8, 15 | c: u8, 16 | } 17 | 18 | impl Foo { 19 | fn unpack(data: u64) -> Self { 20 | Self { 21 | a: (data >> 16 & 0xffffff) as u32, 22 | b: (data & 0xff >> 8) as u8, 23 | c: (data & 0xff) as u8, 24 | } 25 | } 26 | } 27 | 28 | #[spirv(fragment)] 29 | pub fn main(#[spirv(flat)] in_packed: u64, out_sum: &mut u32) { 30 | let foo = Foo::unpack(in_packed); 31 | *out_sum = foo.a + (foo.b + foo.c) as u32; 32 | } 33 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/pass-mode-cast-struct.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 29 12 4 | %6 = OpLoad %7 %8 5 | OpLine %5 30 14 6 | %9 = OpFunctionCall %10 %11 %6 7 | OpLine %5 31 15 8 | %12 = OpCompositeExtract %13 %9 0 9 | OpLine %5 31 24 10 | %14 = OpCompositeExtract %15 %9 1 11 | OpLine %5 31 32 12 | %16 = OpCompositeExtract %15 %9 2 13 | OpLine %5 31 23 14 | %17 = OpIAdd %15 %14 %16 15 | %18 = OpUConvert %13 %17 16 | OpLine %5 31 4 17 | %19 = OpIAdd %13 %12 %18 18 | OpStore %20 %19 19 | OpNoLine 20 | OpReturn 21 | OpFunctionEnd 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_copy.via_intrinsic.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpFunctionParameter %5 4 | %7 = OpLabel 5 | OpLine %8 17 17 6 | OpCopyMemory %6 %4 7 | OpNoLine 8 | OpReturn 9 | OpFunctionEnd 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_read.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=ptr_read::copy_via_raw_ptr 3 | 4 | use spirv_std::spirv; 5 | 6 | fn copy_via_raw_ptr(src: &f32, dst: &mut f32) { 7 | unsafe { *dst = core::ptr::read(src) } 8 | } 9 | #[spirv(fragment)] 10 | pub fn main(i: f32, o: &mut f32) { 11 | copy_via_raw_ptr(&i, o); 12 | // FIXME(eddyb) above call results in inlining `copy_via_raw_ptr`, 13 | // due to the to `Output` storage classe, so to get the disassembled 14 | // function we also need `Function`-local pointers: 15 | let (src, mut dst) = (0.0, 0.0); 16 | copy_via_raw_ptr(&src, &mut dst); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_read.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpFunctionParameter %5 4 | %7 = OpLabel 5 | OpLine %8 1374 8 6 | %9 = OpLoad %10 %4 7 | OpLine %11 7 13 8 | OpStore %6 %9 9 | OpNoLine 10 | OpReturn 11 | OpFunctionEnd 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_read_method.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=ptr_read_method::copy_via_raw_ptr 3 | 4 | use spirv_std::spirv; 5 | 6 | fn copy_via_raw_ptr(src: &f32, dst: &mut f32) { 7 | unsafe { *dst = (src as *const f32).read() } 8 | } 9 | #[spirv(fragment)] 10 | pub fn main(i: f32, o: &mut f32) { 11 | copy_via_raw_ptr(&i, o); 12 | // FIXME(eddyb) above call results in inlining `copy_via_raw_ptr`, 13 | // due to the to `Output` storage classe, so to get the disassembled 14 | // function we also need `Function`-local pointers: 15 | let (src, mut dst) = (0.0, 0.0); 16 | copy_via_raw_ptr(&src, &mut dst); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_read_method.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpFunctionParameter %5 4 | %7 = OpLabel 5 | OpLine %8 1374 8 6 | %9 = OpLoad %10 %4 7 | OpLine %11 7 13 8 | OpStore %6 %9 9 | OpNoLine 10 | OpReturn 11 | OpFunctionEnd 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_write.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=ptr_write::copy_via_raw_ptr 3 | 4 | use spirv_std::spirv; 5 | 6 | fn copy_via_raw_ptr(src: &f32, dst: &mut f32) { 7 | unsafe { core::ptr::write(dst, *src) } 8 | } 9 | #[spirv(fragment)] 10 | pub fn main(i: f32, o: &mut f32) { 11 | copy_via_raw_ptr(&i, o); 12 | // FIXME(eddyb) above call results in inlining `copy_via_raw_ptr`, 13 | // due to the to `Output` storage classe, so to get the disassembled 14 | // function we also need `Function`-local pointers: 15 | let (src, mut dst) = (0.0, 0.0); 16 | copy_via_raw_ptr(&src, &mut dst); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_write.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpFunctionParameter %5 4 | %7 = OpLabel 5 | OpLine %8 7 35 6 | %9 = OpLoad %10 %4 7 | OpLine %11 1578 8 8 | OpStore %6 %9 9 | OpNoLine 10 | OpReturn 11 | OpFunctionEnd 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_write_method.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C llvm-args=--disassemble-fn=ptr_write_method::copy_via_raw_ptr 3 | 4 | use spirv_std::spirv; 5 | 6 | fn copy_via_raw_ptr(src: &f32, dst: &mut f32) { 7 | unsafe { (dst as *mut f32).write(*src) } 8 | } 9 | #[spirv(fragment)] 10 | pub fn main(i: f32, o: &mut f32) { 11 | copy_via_raw_ptr(&i, o); 12 | // FIXME(eddyb) above call results in inlining `copy_via_raw_ptr`, 13 | // due to the to `Output` storage classe, so to get the disassembled 14 | // function we also need `Function`-local pointers: 15 | let (src, mut dst) = (0.0, 0.0); 16 | copy_via_raw_ptr(&src, &mut dst); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/ptr_write_method.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpFunctionParameter %5 3 | %6 = OpFunctionParameter %5 4 | %7 = OpLabel 5 | OpLine %8 7 37 6 | %9 = OpLoad %10 %4 7 | OpLine %11 1578 8 8 | OpStore %6 %9 9 | OpNoLine 10 | OpReturn 11 | OpFunctionEnd 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/spec_constant-attr.stderr: -------------------------------------------------------------------------------- 1 | OpCapability Shader 2 | OpCapability Float64 3 | OpCapability Int64 4 | OpCapability Int16 5 | OpCapability Int8 6 | OpCapability ShaderClockKHR 7 | OpExtension "SPV_KHR_shader_clock" 8 | OpMemoryModel Logical Simple 9 | OpEntryPoint Fragment %1 "main" %2 10 | OpExecutionMode %1 OriginUpperLeft 11 | %3 = OpString "$OPSTRING_FILENAME/spec_constant-attr.rs" 12 | OpName %4 "no_default" 13 | OpName %5 "default_0" 14 | OpName %6 "default_123" 15 | OpName %7 "max_id_and_default" 16 | OpName %2 "out" 17 | OpDecorate %4 SpecId 1 18 | OpDecorate %5 SpecId 2 19 | OpDecorate %6 SpecId 123 20 | OpDecorate %7 SpecId 4294967295 21 | OpDecorate %2 Location 0 22 | %8 = OpTypeInt 32 0 23 | %9 = OpTypePointer Output %8 24 | %10 = OpTypeVoid 25 | %11 = OpTypeFunction %10 26 | %4 = OpSpecConstant %8 0 27 | %5 = OpSpecConstant %8 0 28 | %6 = OpSpecConstant %8 123 29 | %7 = OpSpecConstant %8 4294967295 30 | %2 = OpVariable %9 Output 31 | -------------------------------------------------------------------------------- /tests/compiletests/ui/dis/target_features.stderr: -------------------------------------------------------------------------------- 1 | OpCapability RayTracingKHR 2 | OpCapability Shader 3 | OpExtension "SPV_KHR_ray_tracing" 4 | OpMemoryModel Logical Simple 5 | OpEntryPoint AnyHitNV %1 "main" 6 | OpName %2 "target_features::main" 7 | %3 = OpTypeVoid 8 | %4 = OpTypeFunction %3 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/glam/mat3_vec3_multiply.rs: -------------------------------------------------------------------------------- 1 | // Tests multiplying a `Mat3` by a `Vec3`. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(input: glam::Mat3, output: &mut glam::Vec3) { 8 | let vector = input * glam::Vec3::new(1.0, 2.0, 3.0); 9 | *output = vector; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/hello_world.rs: -------------------------------------------------------------------------------- 1 | // Simple single entrypoint function test. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main() {} 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/fetch.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | use spirv_std::{Image, arch}; 5 | 6 | #[spirv(fragment)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 9 | output: &mut glam::Vec4, 10 | ) { 11 | let texel = image.fetch(glam::IVec2::new(0, 1)); 12 | *output = texel; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/format.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | use spirv_std::{Image, arch}; 5 | 6 | #[spirv(fragment)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, format = rgba32f, sampled), 9 | output: &mut glam::Vec4, 10 | ) { 11 | let texel = image.fetch(glam::IVec2::new(0, 1)); 12 | *output = texel; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/gather_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -Ctarget-feature=+Sampled1D 4 | 5 | use spirv_std::{Image, Sampler, arch, spirv}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image1d: &Image!(1D, type=f32, sampled), 10 | #[spirv(descriptor_set = 2, binding = 1)] image3d: &Image!(3D, type=f32, sampled), 11 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 12 | output: &mut glam::Vec4, 13 | ) { 14 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 15 | let r1: glam::Vec4 = image1d.gather(*sampler, 0.0f32, 0); 16 | let r2: glam::Vec4 = image3d.gather(*sampler, v3, 0); 17 | *output = r1 + r2; 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/image_with.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | use spirv_std::{Image, Sampler, arch, image::ImageWithMethods, image::sample_with}; 5 | 6 | #[spirv(fragment)] 7 | pub fn main( 8 | #[spirv(descriptor_set = 0, binding = 0)] sampler: &Sampler, 9 | #[spirv(descriptor_set = 0, binding = 1)] image1: &Image!(2D, type=f32, sampled, multisampled), 10 | #[spirv(descriptor_set = 0, binding = 2)] image2: &Image!(2D, type=f32, sampled), 11 | output: &mut glam::Vec4, 12 | ) { 13 | let t1 = image1.fetch_with(glam::IVec2::new(0, 0), sample_with::sample_index(1)); 14 | let t2 = image2.sample_with(*sampler, glam::Vec2::new(0.5, 0.5), sample_with::bias(1.0)); 15 | let t3 = image2.sample_with(*sampler, glam::Vec2::new(0.5, 0.5), sample_with::lod(2.0)); 16 | let t4 = image2.sample_with( 17 | *sampler, 18 | glam::Vec2::new(0.5, 0.5), 19 | sample_with::grad(glam::Vec2::new(0.5, 0.5), glam::Vec2::new(0.5, 0.5)), 20 | ); 21 | *output = t1 + t2 + t3 + t4; 22 | } 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/implicit_not_in_fragment.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | 3 | use spirv_std::spirv; 4 | use spirv_std::{Image, Sampler, arch}; 5 | 6 | fn deeper_stack(image2d: &Image!(2D, type=f32, sampled), sampler: &Sampler) -> glam::Vec4 { 7 | let v2 = glam::Vec2::new(0.0, 1.0); 8 | image2d.sample(*sampler, v2) 9 | } 10 | fn deep_stack(image2d: &Image!(2D, type=f32, sampled), sampler: &Sampler) -> glam::Vec4 { 11 | deeper_stack(image2d, sampler) 12 | } 13 | 14 | #[spirv(vertex)] 15 | pub fn main( 16 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 17 | #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler, 18 | output: &mut glam::Vec4, 19 | ) { 20 | let v2 = glam::Vec2::new(0.0, 1.0); 21 | let r0 = deep_stack(image2d, sampler); 22 | let r1: glam::Vec4 = image2d.sample(*sampler, v2); 23 | *output = r0 + r1; 24 | } 25 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/implicit_not_in_fragment.stderr: -------------------------------------------------------------------------------- 1 | error: ImageSampleImplicitLod cannot be used outside a fragment shader 2 | | 3 | = note: Stack: 4 | >::sample:: 5 | implicit_not_in_fragment::deeper_stack 6 | implicit_not_in_fragment::deep_stack 7 | implicit_not_in_fragment::main 8 | main 9 | 10 | error: ImageSampleImplicitLod cannot be used outside a fragment shader 11 | | 12 | = note: Stack: 13 | >::sample:: 14 | implicit_not_in_fragment::main 15 | main 16 | 17 | error: aborting due to 2 previous errors 18 | 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/issue-330.rs: -------------------------------------------------------------------------------- 1 | use spirv_std::glam::Vec4; 2 | use spirv_std::spirv; 3 | use spirv_std::{Sampler, image::Image2dArray}; 4 | 5 | #[spirv(fragment)] 6 | pub fn ps_main_stereo( 7 | output: &mut Vec4, 8 | #[spirv(descriptor_set = 0, binding = 0)] in_texture: &Image2dArray, 9 | ) { 10 | let mut color = Vec4::splat(0.0); 11 | 12 | let mut n = 0; 13 | while n < 10 { 14 | let x = *in_texture; 15 | } 16 | 17 | *output = color; 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/issue_527.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+StorageImageWriteWithoutFormat 3 | 4 | use glam::*; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(compute(threads(1)))] 8 | pub fn main_cs( 9 | #[spirv(global_invocation_id)] id: UVec3, 10 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] points_buffer: &mut [UVec2; 100], 11 | #[spirv(descriptor_set = 1, binding = 1)] image: &spirv_std::Image!(2D, type=f32, sampled=false), 12 | ) { 13 | let position = id.xy(); 14 | for i in 0..100usize { 15 | let p0 = &points_buffer[i]; 16 | let p1 = &points_buffer[i + 1]; 17 | if p0.x == position.x && p1.y == position.y { 18 | unsafe { 19 | image.write(position, vec2(1.0, 0.0)); 20 | }; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_levels.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+ImageQuery 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | output: &mut u32, 11 | ) { 12 | *output = image.query_levels(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_levels_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -C target-feature=+ImageQuery 4 | 5 | use spirv_std::{Image, arch, spirv}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(rect, type=f32, sampled), 10 | output: &mut u32, 11 | ) { 12 | *output = image.query_levels(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_lod.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+ImageQuery 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler, 11 | output: &mut glam::Vec2, 12 | ) { 13 | *output = image.query_lod(*sampler, glam::Vec2::new(0.0, 1.0)); 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_lod_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -C target-feature=+ImageQuery 4 | 5 | use spirv_std::{Image, Sampler, arch, spirv}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(rect, type=f32, sampled), 10 | #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler, 11 | output: &mut glam::Vec2, 12 | ) { 13 | *output = image.query_lod(*sampler, glam::Vec2::new(0.0, 1.0)); 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_samples.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+ImageQuery 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled, multisampled), 10 | output: &mut u32, 11 | ) { 12 | *output = image.query_samples(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_size.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+ImageQuery 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), 10 | output: &mut glam::UVec2, 11 | ) { 12 | *output = image.query_size(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_size_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -C target-feature=+ImageQuery 4 | 5 | use spirv_std::{Image, arch, spirv}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | output: &mut glam::UVec2, 11 | ) { 12 | *output = image.query_size(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_size_lod.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+ImageQuery 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | output: &mut glam::UVec2, 11 | ) { 12 | *output = image.query_size_lod(0); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/query/query_size_lod_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // normalize-stderr-test "\S*/crates/spirv-std/src/" -> "$$SPIRV_STD_SRC/" 3 | // compile-flags: -C target-feature=+ImageQuery 4 | 5 | use spirv_std::{Image, arch, spirv}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(rect, type=f32, sampled), 10 | output: &mut glam::UVec2, 11 | ) { 12 | *output = image.query_size_lod(0); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/read.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageRead` 2 | // build-pass 3 | // compile-flags: -C target-feature=+StorageImageReadWithoutFormat 4 | 5 | use spirv_std::spirv; 6 | use spirv_std::{Image, arch}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), 11 | output: &mut glam::Vec4, 12 | ) { 13 | let coords = image.read(glam::IVec2::new(0, 1)); 14 | *output = coords; 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/read_subpass.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+InputAttachment 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0, input_attachment_index = 0)] image: &Image!(subpass, type=f32, sampled=false), 10 | output: &mut glam::Vec4, 11 | ) { 12 | let coords = image.read_subpass(glam::IVec2::new(0, 0)); 13 | *output = coords; 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleImplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] image2d_array: &Image!(2D, type=f32, arrayed, sampled), 11 | #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(3D, type=f32, sampled), 12 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 13 | output: &mut glam::Vec4, 14 | ) { 15 | let v2 = glam::Vec2::new(0.0, 1.0); 16 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 17 | let r1: glam::Vec4 = image2d.sample(*sampler, v2); 18 | let r2: glam::Vec4 = image2d_array.sample(*sampler, v3); 19 | let r3: glam::Vec4 = cubemap.sample(*sampler, v3); 20 | *output = r1 + r2 + r3; 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_bias.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleImplicitLod` Bias 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] image2d_array: &Image!(2D, type=f32, arrayed, sampled), 11 | #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(3D, type=f32, sampled), 12 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 13 | output: &mut glam::Vec4, 14 | ) { 15 | let v2 = glam::Vec2::new(0.0, 1.0); 16 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 17 | let r1: glam::Vec4 = image2d.sample_bias(*sampler, v2, 0.0); 18 | let r2: glam::Vec4 = image2d_array.sample_bias(*sampler, v3, 0.0); 19 | let r3: glam::Vec4 = cubemap.sample_bias(*sampler, v3, 0.0); 20 | *output = r1 + r2 + r3; 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_depth_reference/sample.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleDrefImplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] image_array: &Image!(2D, type=f32, arrayed, sampled), 11 | #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(cube, type=f32, sampled), 12 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 13 | output: &mut f32, 14 | ) { 15 | let v2 = glam::Vec2::new(0.0, 1.0); 16 | let v3 = glam::Vec3A::new(0.0, 0.0, 1.0); 17 | *output = image.sample_depth_reference(*sampler, v2, 1.0); 18 | *output += image_array.sample_depth_reference(*sampler, v3, 1.0); 19 | *output += cubemap.sample_depth_reference(*sampler, v3, 1.0); 20 | } 21 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_depth_reference_with_project_coordinate/sample.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjDrefImplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut f32, 12 | ) { 13 | let v3 = glam::Vec3A::new(0.0, 0.0, 1.0); 14 | *output = image.sample_depth_reference_with_project_coordinate(*sampler, v3, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_depth_reference_with_project_coordinate/sample_gradient.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjDrefExplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut f32, 12 | ) { 13 | let v2_dx = glam::Vec2::new(0.0, 1.0); 14 | let v2_dy = glam::Vec2::new(0.0, 1.0); 15 | let v3 = glam::Vec3A::new(0.0, 0.0, 1.0); 16 | *output = image.sample_depth_reference_with_project_coordinate_by_gradient( 17 | *sampler, v3, 1.0, v2_dx, v2_dy, 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_depth_reference_with_project_coordinate/sample_lod.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjDrefExplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut f32, 12 | ) { 13 | let v3 = glam::Vec3A::new(0.0, 0.0, 1.0); 14 | *output = image.sample_depth_reference_with_project_coordinate_by_lod(*sampler, v3, 1.0, 0.0); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_gradient.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleExplicitLod` Grad 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] image2d_array: &Image!(2D, type=f32, arrayed, sampled), 11 | #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(3D, type=f32, sampled), 12 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 13 | output: &mut glam::Vec4, 14 | ) { 15 | let v2 = glam::Vec2::new(0.0, 1.0); 16 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 17 | let r1: glam::Vec4 = image2d.sample_by_gradient(*sampler, v2, v2, v2); 18 | let r2: glam::Vec4 = image2d_array.sample_by_gradient(*sampler, v3, v2, v2); 19 | let r3: glam::Vec4 = cubemap.sample_by_gradient(*sampler, v3, v3, v3); 20 | *output = r1 + r2 + r3; 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_lod.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleExplicitLod` Lod 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch, image::SampledImage}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] image2d_array: &Image!(2D, type=f32, arrayed, sampled), 11 | #[spirv(descriptor_set = 2, binding = 2)] cubemap: &Image!(3D, type=f32, sampled), 12 | #[spirv(descriptor_set = 3, binding = 3)] sampler: &Sampler, 13 | #[spirv(descriptor_set = 4, binding = 4)] sampled_image: &SampledImage< 14 | Image!(2D, type=f32, sampled), 15 | >, 16 | output: &mut glam::Vec4, 17 | ) { 18 | let v2 = glam::Vec2::new(0.0, 1.0); 19 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 20 | let r1: glam::Vec4 = image2d.sample_by_lod(*sampler, v2, 0.0); 21 | let r2: glam::Vec4 = image2d_array.sample_by_lod(*sampler, v3, 0.0); 22 | let r3: glam::Vec4 = cubemap.sample_by_lod(*sampler, v3, 0.0); 23 | let r4: glam::Vec4 = unsafe { sampled_image.sample_by_lod(v2, 0.0) }; 24 | *output = r1 + r2 + r3 + r4; 25 | } 26 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_with_project_coordinate/sample.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjImplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut glam::Vec4, 12 | ) { 13 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 14 | *output = image2d.sample_with_project_coordinate(*sampler, v3); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_with_project_coordinate/sample_gradient.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjExplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut glam::Vec4, 12 | ) { 13 | let v2 = glam::Vec2::new(0.0, 1.0); 14 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 15 | *output = image2d.sample_with_project_coordinate_by_gradient(*sampler, v3, v2, v2); 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/sample_with_project_coordinate/sample_lod.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageSampleProjExplicitLod` 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, Sampler, arch}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] image2d: &Image!(2D, type=f32, sampled), 10 | #[spirv(descriptor_set = 1, binding = 1)] sampler: &Sampler, 11 | output: &mut glam::Vec4, 12 | ) { 13 | let v3 = glam::Vec3::new(0.0, 1.0, 0.5); 14 | *output = image2d.sample_with_project_coordinate_by_lod(*sampler, v3, 0.0); 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/image/write.rs: -------------------------------------------------------------------------------- 1 | // Test `OpImageWrite` 2 | // build-pass 3 | // compile-flags: -C target-feature=+StorageImageWriteWithoutFormat 4 | 5 | use spirv_std::spirv; 6 | use spirv_std::{Image, arch}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | texels: glam::Vec2, 11 | #[spirv(descriptor_set = 0, binding = 0)] image: &Image!(2D, type=f32, sampled=false), 12 | ) { 13 | unsafe { 14 | image.write(glam::UVec2::new(0, 1), texels); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/asm/block_tracking_fail.rs: -------------------------------------------------------------------------------- 1 | // Tests validating tracking of basic blocks 2 | // within the `asm!` macro. 3 | // build-fail 4 | 5 | use core::arch::asm; 6 | use spirv_std::spirv; 7 | 8 | // Active basic block with `noreturn`. 9 | fn asm_noreturn_open() { 10 | unsafe { 11 | asm!("", options(noreturn)); 12 | } 13 | } 14 | 15 | // No active basic block without `noreturn`. 16 | fn asm_closed() { 17 | unsafe { 18 | asm!("OpUnreachable"); 19 | } 20 | } 21 | 22 | // Invalid op after terminator 23 | fn asm_invalid_op_terminator(x: f32) { 24 | unsafe { 25 | asm!( 26 | "OpKill", 27 | "%sum = OpFAdd _ {x} {x}", 28 | x = in(reg) x, 29 | ); 30 | } 31 | } 32 | 33 | #[spirv(fragment)] 34 | pub fn main() { 35 | asm_closed(); 36 | asm_noreturn_open(); 37 | asm_invalid_op_terminator(1.0); 38 | } 39 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/asm/block_tracking_fail.stderr: -------------------------------------------------------------------------------- 1 | error: `noreturn` requires a terminator at the end 2 | --> $DIR/block_tracking_fail.rs:11:9 3 | | 4 | 11 | asm!("", options(noreturn)); 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: trailing terminator `OpUnreachable` requires `options(noreturn)` 8 | --> $DIR/block_tracking_fail.rs:18:9 9 | | 10 | 18 | asm!("OpUnreachable"); 11 | | ^^^^^^^^^^^^^^^^^^^^^ 12 | 13 | error: expected `OpLabel` after terminator `OpKill` 14 | --> $DIR/block_tracking_fail.rs:25:9 15 | | 16 | 25 | / asm!( 17 | 26 | | "OpKill", 18 | 27 | | "%sum = OpFAdd _ {x} {x}", 19 | 28 | | x = in(reg) x, 20 | 29 | | ); 21 | | |_________^ 22 | 23 | error: aborting due to 3 previous errors 24 | 25 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/asm/block_tracking_pass.rs: -------------------------------------------------------------------------------- 1 | // Tests validating tracking of basic blocks 2 | // within the `asm!` macro. 3 | // build-pass 4 | 5 | use core::arch::asm; 6 | use spirv_std::spirv; 7 | 8 | fn asm_label() { 9 | unsafe { 10 | asm!( 11 | "OpKill", // close active block 12 | "%unused = OpLabel", // open new block 13 | ); 14 | } 15 | } 16 | 17 | fn asm_noreturn_single() -> ! { 18 | unsafe { 19 | asm!( 20 | "OpKill", // close active block 21 | options(noreturn), 22 | ); 23 | } 24 | } 25 | 26 | #[spirv(fragment)] 27 | pub fn main() { 28 | asm_label(); 29 | asm_noreturn_single(); 30 | } 31 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/asm/const_args.rs: -------------------------------------------------------------------------------- 1 | // Tests using `asm!` with a const argument. 2 | // build-pass 3 | 4 | use core::arch::asm; 5 | use spirv_std::spirv; 6 | 7 | fn asm() { 8 | unsafe { 9 | const N: usize = 3; 10 | asm!( 11 | "%int = OpTypeInt 32 0", 12 | "%type = OpTypeVector %int {len}", 13 | len = const N, 14 | ); 15 | } 16 | } 17 | 18 | #[spirv(fragment)] 19 | pub fn main() { 20 | asm(); 21 | } 22 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/asm/infer-access-chain-array.rs: -------------------------------------------------------------------------------- 1 | // Tests that `asm!` can infer the result type of `OpAccessChain`, 2 | // when used to index arrays. 3 | 4 | // build-pass 5 | 6 | use core::arch::asm; 7 | use glam::Vec4; 8 | use spirv_std::spirv; 9 | 10 | #[spirv(fragment)] 11 | pub fn main(#[spirv(push_constant)] array_in: &[Vec4; 16], #[spirv(flat)] i: u32, out: &mut Vec4) { 12 | unsafe { 13 | asm!( 14 | "%val_ptr = OpAccessChain _ {array_ptr} {index}", 15 | "%val = OpLoad _ %val_ptr", 16 | "OpStore {out_ptr} %val", 17 | array_ptr = in(reg) array_in, 18 | index = in(reg) i, 19 | out_ptr = in(reg) out, 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/issue-329.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | const OFFSETS: [f32; 18] = [ 6 | 0.000000, 1.494118, 3.486275, 5.478431, 7.470588, 9.462745, 11.454902, 13.447059, 15.439216, 7 | 17.431373, 19.423529, 21.415686, 23.407843, 25.400000, 27.392157, 29.384314, 31.376471, 8 | 33.368627, 9 | ]; 10 | 11 | #[spirv(fragment)] 12 | pub fn main(x: &mut u32) { 13 | *x = OFFSETS.len() as u32; 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/issue-834.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main() { 7 | let arr = [0u32; 32]; 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/nested-ref-in-composite.rs: -------------------------------------------------------------------------------- 1 | // Test `&'static T` constants where the `T` values themselves contain references, 2 | // nested in `OpConstantComposite` (structs/arrays) - currently these are disallowed. 3 | 4 | // build-fail 5 | 6 | use spirv_std::spirv; 7 | 8 | #[inline(never)] 9 | fn pair_deep_load(r: &'static (&'static u32, &'static f32)) -> (u32, f32) { 10 | (*r.0, *r.1) 11 | } 12 | 13 | #[inline(never)] 14 | fn array3_deep_load(r: &'static [&'static u32; 3]) -> [u32; 3] { 15 | [*r[0], *r[1], *r[2]] 16 | } 17 | 18 | #[spirv(fragment)] 19 | pub fn main_pair(pair_out: &mut (u32, f32)) { 20 | *pair_out = pair_deep_load(&(&123, &3.14)); 21 | } 22 | 23 | #[spirv(fragment)] 24 | pub fn main_array3(array3_out: &mut [u32; 3]) { 25 | *array3_out = array3_deep_load(&[&0, &1, &2]); 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/nested-ref.rs: -------------------------------------------------------------------------------- 1 | // Test `&'static &'static T` constants where the `T` values don't themselves 2 | // contain references, and where the `T` values aren't immediately loaded from. 3 | 4 | // build-pass 5 | // compile-flags: -C target-feature=+VariablePointers 6 | 7 | use spirv_std::spirv; 8 | 9 | use glam::{Mat2, Vec2}; 10 | 11 | #[inline(never)] 12 | fn deep_load(r: &'static &'static u32) -> u32 { 13 | **r 14 | } 15 | 16 | const ROT90: &Mat2 = &Mat2::from_cols_array_2d(&[[0.0, 1.0], [-1.0, 0.0]]); 17 | 18 | #[inline(never)] 19 | fn deep_transpose(r: &'static &'static Mat2) -> Mat2 { 20 | r.transpose() 21 | } 22 | 23 | #[spirv(fragment)] 24 | pub fn main( 25 | scalar_out: &mut u32, 26 | #[spirv(push_constant)] vec_in: &Vec2, 27 | bool_out: &mut u32, 28 | vec_out: &mut Vec2, 29 | ) { 30 | *scalar_out = deep_load(&&123); 31 | *bool_out = (vec_in == &Vec2::ZERO) as u32; 32 | *vec_out = deep_transpose(&ROT90) * *vec_in; 33 | } 34 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/nested-ref.stderr: -------------------------------------------------------------------------------- 1 | warning: `#[inline(never)]` function `nested_ref::deep_load` has been inlined 2 | --> $DIR/nested-ref.rs:12:4 3 | | 4 | 12 | fn deep_load(r: &'static &'static u32) -> u32 { 5 | | ^^^^^^^^^ 6 | | 7 | = note: inlining was required due to illegal parameter type 8 | = note: called from `nested_ref::main` 9 | 10 | warning: `#[inline(never)]` function `nested_ref::deep_transpose` has been inlined 11 | --> $DIR/nested-ref.rs:19:4 12 | | 13 | 19 | fn deep_transpose(r: &'static &'static Mat2) -> Mat2 { 14 | | ^^^^^^^^^^^^^^ 15 | | 16 | = note: inlining was required due to illegal parameter type 17 | = note: called from `nested_ref::main` 18 | 19 | warning: 2 warnings emitted 20 | 21 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/consts/shallow-ref.rs: -------------------------------------------------------------------------------- 1 | // Test `&'static T` constants where the `T` values don't themselves contain 2 | // references, and where the `T` values aren't immediately loaded from. 3 | 4 | // build-pass 5 | 6 | use spirv_std::spirv; 7 | 8 | use glam::{Mat2, Vec2}; 9 | 10 | #[inline(never)] 11 | fn scalar_load(r: &'static u32) -> u32 { 12 | *r 13 | } 14 | 15 | const ROT90: Mat2 = Mat2::from_cols_array_2d(&[[0.0, 1.0], [-1.0, 0.0]]); 16 | 17 | #[spirv(fragment)] 18 | pub fn main(scalar_out: &mut u32, vec_in: Vec2, bool_out: &mut u32, vec_out: &mut Vec2) { 19 | *scalar_out = scalar_load(&123); 20 | *bool_out = (vec_in == Vec2::ZERO) as u32; 21 | *vec_out = ROT90.transpose() * vec_in; 22 | } 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/closure_multi.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std; 4 | use spirv_std::spirv; 5 | 6 | fn closure_user(ptr: &u32, xmax: u32, mut callback: F) { 7 | for i in 0..xmax { 8 | callback(ptr, i); 9 | } 10 | } 11 | 12 | #[spirv(fragment)] 13 | pub fn main(ptr: &mut u32) { 14 | closure_user(ptr, 10, |ptr, i| { 15 | if *ptr == i { 16 | spirv_std::arch::kill(); 17 | } 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/defer.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 32 { 8 | let current_position = 0; 9 | if i < current_position { 10 | break; 11 | } 12 | if i < current_position { 13 | break; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/for_range.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: u32) { 7 | for _ in 0..i {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/for_range_signed.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | for _ in 0..i {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/for_with_custom_range_iter.rs: -------------------------------------------------------------------------------- 1 | // NOTE(eddyb) this tests `for` loop desugaring (with its call to `Iterator::next` 2 | // and matching on the resulting `Option`), without relying on a `Range` iterator. 3 | // More precisely, `Range` used to not compile, due to it using `mem::replace`, 4 | // which, before https://github.com/rust-lang/rust/pull/83022, used to just call 5 | // `mem::swap` (which has a block-wise optimization that can't work on SPIR-V). 6 | 7 | // build-pass 8 | 9 | use core::ops::Range; 10 | use spirv_std::num_traits::Num; 11 | use spirv_std::spirv; 12 | 13 | struct RangeIter(Range); 14 | 15 | impl Iterator for RangeIter { 16 | type Item = T; 17 | fn next(&mut self) -> Option { 18 | let x = self.0.start; 19 | if x >= self.0.end { 20 | None 21 | } else { 22 | self.0.start = x + T::one(); 23 | Some(x) 24 | } 25 | } 26 | } 27 | 28 | #[spirv(fragment)] 29 | pub fn main(#[spirv(flat)] i: i32) { 30 | for _ in RangeIter(0..i) {} 31 | } 32 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i > 0 {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_else.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i > 0 { 8 | } else { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_else_if_else.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i > 0 { 8 | } else if i < 0 { 9 | } else { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_if.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i > 0 { 8 | if i < 10 {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_return_else.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i < 10 { 8 | return; 9 | } else { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_return_else_return.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i < 10 { 8 | return; 9 | } else { 10 | return; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/if_while.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i == 0 { 8 | while i < 10 {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/ifx2.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | if i > 0 {} 8 | if i > 1 {} 9 | } 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/issue_283.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | use glam::*; 6 | 7 | fn sphere_sdf(p: Vec3) -> f32 { 8 | p.length() - 1.0 9 | } 10 | 11 | // Global scene to render 12 | fn scene_sdf(p: Vec3) -> f32 { 13 | sphere_sdf(p) 14 | } 15 | 16 | fn render(eye: Vec3, dir: Vec3, start: f32, end: f32) -> f32 { 17 | let max_marching_steps: i32 = 255; 18 | let epsilon: f32 = 0.0001; 19 | 20 | let mut depth = start; 21 | let mut i = 0; 22 | 23 | loop { 24 | if i < max_marching_steps { 25 | break; 26 | } 27 | 28 | let dist = scene_sdf(eye + depth * dir); 29 | 30 | if dist < epsilon { 31 | return depth; 32 | } 33 | 34 | depth += dist; 35 | 36 | if depth >= end { 37 | return end; 38 | } 39 | 40 | i += 1; 41 | } 42 | 43 | end 44 | } 45 | 46 | #[spirv(fragment)] 47 | pub fn main() { 48 | let v = Vec3::new(1.0, 1.0, 1.0); 49 | render(v, v, 1.0, 2.0); 50 | } 51 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/issue_764.stderr: -------------------------------------------------------------------------------- 1 | error: module has recursion, which is not allowed: `<(i32, issue_764::Transform2D) as issue_764::GivesFinalTransform>::get_final_transform` calls `<(i32, issue_764::Transform2D) as issue_764::GivesFinalTransform>::get_final_transform` 2 | 3 | error: aborting due to 1 previous error 4 | 5 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/loop.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main() { 7 | loop {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 {} 8 | } 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | break; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_continue.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | continue; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_if_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | if i == 0 { 9 | break; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_if_break_else_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | if i == 0 { 9 | break; 10 | } else { 11 | break; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_if_break_if_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | if i == 0 { 9 | break; 10 | } 11 | if i == 1 { 12 | break; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_if_continue.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | if i == 0 { 9 | continue; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_if_continue_else_continue.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | if i == 0 { 9 | continue; 10 | } else { 11 | continue; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_return.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 10 { 8 | return; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_while.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 20 { 8 | while i < 10 {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_while_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 20 { 8 | while i < 10 { 9 | break; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_while_continue.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 20 { 8 | while i < 10 { 9 | continue; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_while_if_break.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 20 { 8 | while i < 10 { 9 | if i > 10 { 10 | break; 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/control_flow/while_while_if_continue.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn main(#[spirv(flat)] i: i32) { 7 | while i < 20 { 8 | while i < 10 { 9 | if i > 5 { 10 | continue; 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/array/init_array_i16.rs: -------------------------------------------------------------------------------- 1 | // Test creating an array. 2 | // build-pass 3 | 4 | use spirv_std::macros::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(o: &mut i16) { 8 | let array = [0i16; 4]; 9 | *o = array[1]; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/array/init_array_i32.rs: -------------------------------------------------------------------------------- 1 | // Test creating an array. 2 | // build-pass 3 | 4 | use spirv_std::macros::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(o: &mut i32) { 8 | let array = [0i32; 4]; 9 | *o = array[1]; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/array/init_array_i64.rs: -------------------------------------------------------------------------------- 1 | // Test creating an array. 2 | // build-pass 3 | 4 | use spirv_std::macros::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(o: &mut i64) { 8 | let array = [0i64; 4]; 9 | *o = array[1]; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/array/init_array_i8.rs: -------------------------------------------------------------------------------- 1 | // Test creating an array. 2 | // build-pass 3 | 4 | use spirv_std::macros::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(o: &mut i8) { 8 | let array = [0i8; 4]; 9 | *o = array[1]; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/intrinsics/log10.rs: -------------------------------------------------------------------------------- 1 | // Test log10 intrinsic 2 | // build-pass 3 | 4 | #![allow(internal_features)] 5 | #![feature(core_intrinsics)] 6 | #![no_std] 7 | 8 | use spirv_std::num_traits::Float as _; 9 | use spirv_std::spirv; 10 | 11 | #[spirv(compute(threads(1)))] 12 | pub fn main( 13 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] input: &[f32], 14 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] output: &mut [f32], 15 | ) { 16 | output[0] = input[0].log10(); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/mem/create_unitialized_memory.rs: -------------------------------------------------------------------------------- 1 | // Test creating uninitialized memory. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | use core::mem::MaybeUninit; 7 | const MAYBEI32: MaybeUninit<&i32> = MaybeUninit::<&i32>::uninit(); 8 | 9 | pub fn create_uninit_and_write() { 10 | let mut maybei32 = MAYBEI32; 11 | unsafe { 12 | maybei32.as_mut_ptr().write(&0); 13 | } 14 | let _maybei32 = unsafe { maybei32.assume_init() }; 15 | } 16 | 17 | #[spirv(fragment)] 18 | pub fn main() {} 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ops/logical_and.rs: -------------------------------------------------------------------------------- 1 | // Test using `&&` operator. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | fn f(x: bool, y: bool) -> bool { 7 | x && y 8 | } 9 | 10 | #[spirv(fragment)] 11 | pub fn main() { 12 | f(false, true); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ops/range-contains.rs: -------------------------------------------------------------------------------- 1 | // Test that using `(a..b).contains(&x)`, which is starting to get used 2 | // in `core` (see https://github.com/rust-lang/rust/pull/87723), cannot 3 | // cause a fatal error, but at most a zombie or SPIR-V validation error. 4 | 5 | // build-pass 6 | 7 | use spirv_std::spirv; 8 | 9 | fn has_two_decimal_digits(x: u32) -> bool { 10 | (10..100).contains(&x) 11 | } 12 | 13 | #[spirv(fragment)] 14 | pub fn main(#[spirv(flat)] i: u32, o: &mut u32) { 15 | *o = has_two_decimal_digits(i) as u32; 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ptr/allocate_const_scalar.rs: -------------------------------------------------------------------------------- 1 | // Doesn't work, only worked before because I think it got optimized away before 2 | // hitting the backend. 3 | 4 | // build-fail 5 | 6 | #![feature(ptr_internals)] 7 | 8 | use spirv_std::spirv; 9 | 10 | use core::ptr::Unique; 11 | 12 | const POINTER: Unique<[u8; 4]> = Unique::<[u8; 4]>::dangling(); 13 | 14 | #[spirv(fragment)] 15 | pub fn main(output: &mut Unique<[u8; 4]>) { 16 | *output = POINTER; 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ptr/allocate_const_scalar.stderr: -------------------------------------------------------------------------------- 1 | warning: the feature `ptr_internals` is internal to the compiler or standard library 2 | --> $DIR/allocate_const_scalar.rs:6:12 3 | | 4 | 6 | #![feature(ptr_internals)] 5 | | ^^^^^^^^^^^^^ 6 | | 7 | = note: using it is strongly discouraged 8 | = note: `#[warn(internal_features)]` on by default 9 | 10 | error: pointer has non-null integer address 11 | | 12 | note: used from within `allocate_const_scalar::main` 13 | --> $DIR/allocate_const_scalar.rs:16:5 14 | | 15 | 16 | *output = POINTER; 16 | | ^^^^^^^^^^^^^^^^^ 17 | note: called by `main` 18 | --> $DIR/allocate_const_scalar.rs:15:8 19 | | 20 | 15 | pub fn main(output: &mut Unique<[u8; 4]>) { 21 | | ^^^^ 22 | 23 | error: aborting due to 1 previous error; 1 warning emitted 24 | 25 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ptr/allocate_null.rs: -------------------------------------------------------------------------------- 1 | // Tests allocating a null pointer at `const` time. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | use core::ptr::null; 7 | const NULL_PTR: *const i32 = null(); 8 | 9 | #[spirv(fragment)] 10 | pub fn main() { 11 | let _null_ptr = NULL_PTR; 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ptr/allocate_vec_like.rs: -------------------------------------------------------------------------------- 1 | // Tests using a vector like pointer at `const` time. 2 | // build-pass 3 | 4 | #![feature(ptr_internals)] 5 | 6 | use spirv_std::spirv; 7 | 8 | use core::ptr::Unique; 9 | const VEC_LIKE: (Unique, usize, usize) = (Unique::::dangling(), 0, 0); 10 | 11 | pub fn assign_vec_like() { 12 | let _vec_like = VEC_LIKE; 13 | } 14 | 15 | #[spirv(fragment)] 16 | pub fn main() {} 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ptr/allocate_vec_like.stderr: -------------------------------------------------------------------------------- 1 | warning: the feature `ptr_internals` is internal to the compiler or standard library 2 | --> $DIR/allocate_vec_like.rs:4:12 3 | | 4 | 4 | #![feature(ptr_internals)] 5 | | ^^^^^^^^^^^^^ 6 | | 7 | = note: using it is strongly discouraged 8 | = note: `#[warn(internal_features)]` on by default 9 | 10 | warning: 1 warning emitted 11 | 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ref/member_ref_arg.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | struct S { 6 | x: u32, 7 | y: u32, 8 | } 9 | 10 | // NOTE(eddyb) `#[inline(never)]` is for blocking inlining at the e.g. MIR level, 11 | // whereas any Rust-GPU-specific legalization will intentionally ignore it. 12 | 13 | #[inline(never)] 14 | fn f(x: &u32) {} 15 | 16 | #[inline(never)] 17 | fn g(xy: (&u32, &u32)) {} 18 | 19 | #[spirv(fragment)] 20 | pub fn main() { 21 | let s = S { x: 2, y: 2 }; 22 | f(&s.x); 23 | g((&s.x, &s.y)); 24 | } 25 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ref/member_ref_arg.stderr: -------------------------------------------------------------------------------- 1 | warning: `#[inline(never)]` function `member_ref_arg::f` has been inlined 2 | --> $DIR/member_ref_arg.rs:14:4 3 | | 4 | 14 | fn f(x: &u32) {} 5 | | ^ 6 | | 7 | = note: inlining was required due to illegal (pointer) argument 8 | = note: called from `member_ref_arg::main` 9 | 10 | warning: `#[inline(never)]` function `member_ref_arg::g` has been inlined 11 | --> $DIR/member_ref_arg.rs:17:4 12 | | 13 | 17 | fn g(xy: (&u32, &u32)) {} 14 | | ^ 15 | | 16 | = note: inlining was required due to illegal (pointer) argument 17 | = note: called from `member_ref_arg::main` 18 | 19 | warning: 2 warnings emitted 20 | 21 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ref/zst_member_ref_arg-broken.rs: -------------------------------------------------------------------------------- 1 | // FIXME(eddyb) this is like `zst_member_ref_arg`, but testing the error messages 2 | // in some broken cases (see issue #1037) - this test should eventually pass, but 3 | // for now we care more that the error messages do not regress too much. 4 | 5 | // build-fail 6 | 7 | use spirv_std::spirv; 8 | struct A; 9 | struct B; 10 | 11 | pub struct S { 12 | x: A, 13 | y: B, 14 | 15 | z: Z, 16 | w: W, 17 | } 18 | 19 | fn f(x: &B) {} 20 | 21 | #[spirv(fragment)] 22 | pub fn main_scalar(#[spirv(push_constant)] s: &S) { 23 | f(&s.y); 24 | } 25 | 26 | #[spirv(fragment)] 27 | pub fn main_scalar_pair(#[spirv(push_constant)] s: &S) { 28 | f(&s.y); 29 | } 30 | 31 | #[spirv(fragment)] 32 | pub fn main_scalar_scalar_pair_nested(#[spirv(push_constant)] s: &S<(usize, usize)>) { 33 | f(&s.y); 34 | } 35 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/ref/zst_member_ref_arg.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | struct A; 5 | struct B; 6 | 7 | struct S { 8 | x: A, 9 | y: B, 10 | } 11 | 12 | fn f(x: &B) {} 13 | 14 | #[spirv(fragment)] 15 | pub fn main() { 16 | let s = S { x: A, y: B }; 17 | f(&s.y); 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/unwrap_or.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "unwrap_or"] 2 | 3 | // unwrap_or generates some memory-bools (as u8). Test to make sure they're fused away. 4 | // OpINotEqual, as well as %bool, should not appear in the output. 5 | 6 | // build-pass 7 | // compile-flags: -C llvm-args=--disassemble-entry=main 8 | 9 | use spirv_std::spirv; 10 | 11 | #[spirv(fragment)] 12 | pub fn main(out: &mut u32) { 13 | *out = None.unwrap_or(15); 14 | } 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/core/unwrap_or.stderr: -------------------------------------------------------------------------------- 1 | %1 = OpFunction %2 None %3 2 | %4 = OpLabel 3 | OpLine %5 13 11 4 | %6 = OpCompositeInsert %7 %8 %9 0 5 | %10 = OpCompositeExtract %11 %6 1 6 | OpLine %12 993 14 7 | %13 = OpBitcast %14 %8 8 | OpLine %12 993 8 9 | %15 = OpIEqual %16 %13 %17 10 | OpNoLine 11 | OpSelectionMerge %18 None 12 | OpBranchConditional %15 %19 %20 13 | %19 = OpLabel 14 | OpBranch %18 15 | %20 = OpLabel 16 | OpBranch %18 17 | %18 = OpLabel 18 | %21 = OpPhi %11 %22 %19 %10 %20 19 | OpLine %5 13 4 20 | OpStore %23 %21 21 | OpNoLine 22 | OpReturn 23 | OpFunctionEnd 24 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/f32/signum.rs: -------------------------------------------------------------------------------- 1 | // Test that `signum` works. 2 | // build-pass 3 | 4 | use spirv_std::num_traits::Float; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main(i: f32, o: &mut f32) { 9 | *o = i.signum(); 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/issue-415.rs: -------------------------------------------------------------------------------- 1 | // Test that zero sized unions don't ICE (even if unions are generally not supported yet) 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | union U { 7 | a: (), 8 | } 9 | 10 | #[spirv(fragment)] 11 | pub fn main() { 12 | let _u = U { a: () }; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/issue-46.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use spirv_std::spirv; 4 | 5 | #[derive(Default)] 6 | struct Foo { 7 | bar: bool, 8 | baz: [[u32; 2]; 1], 9 | } 10 | 11 | #[spirv(fragment)] 12 | pub fn main() { 13 | let x = [[1; 2]; 1]; 14 | let y = [Foo::default(); 1]; 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/issue-836.rs: -------------------------------------------------------------------------------- 1 | // Test that newtypes of `ScalarPair` can have references taken to their field. 2 | 3 | // build-pass 4 | 5 | use spirv_std::spirv; 6 | 7 | struct Newtype(T); 8 | 9 | impl Newtype { 10 | fn get(&self) -> &T { 11 | &self.0 12 | } 13 | } 14 | 15 | impl Newtype<&[u32]> { 16 | fn slice_get(&self) -> &&[u32] { 17 | &self.0 18 | } 19 | } 20 | 21 | impl> Newtype { 22 | fn deref_index(&self, i: usize) -> &u32 { 23 | &self.0[i] 24 | } 25 | } 26 | 27 | struct CustomPair(u32, u32); 28 | 29 | #[spirv(fragment)] 30 | pub fn main( 31 | #[spirv(descriptor_set = 0, binding = 0, storage_buffer)] slice: &[u32], 32 | out: &mut u32, 33 | ) { 34 | let newtype_slice = Newtype(slice); 35 | *out = newtype_slice.get()[0]; 36 | *out += newtype_slice.slice_get()[1]; 37 | *out += newtype_slice.deref_index(2); 38 | 39 | let newtype_custom_pair = Newtype(CustomPair(*out, *out + 1)); 40 | *out += newtype_custom_pair.get().0; 41 | *out += newtype_custom_pair.get().1; 42 | } 43 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/panic/builtin.rs: -------------------------------------------------------------------------------- 1 | // Test panics coming from the Rust language such as `1 / 0`. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | fn int_div(x: usize) -> usize { 7 | 1 / x 8 | } 9 | 10 | #[spirv(fragment)] 11 | pub fn main() { 12 | int_div(0); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/panic/builtin_bounds_check.rs: -------------------------------------------------------------------------------- 1 | // Test that bounds checking causes panics. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | fn array_bounds_check(x: [u32; 4], i: usize) -> u32 { 7 | x[i] 8 | } 9 | 10 | #[spirv(fragment)] 11 | pub fn main() { 12 | array_bounds_check([0, 1, 2, 3], 5); 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/panic/simple.rs: -------------------------------------------------------------------------------- 1 | // Test that calling `panic!` works. 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main() { 8 | panic!("aaa"); 9 | } 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/panic/track_caller.rs: -------------------------------------------------------------------------------- 1 | // Test that propagating `#[track_caller]` doesn't cause constant-related errors. 2 | 3 | // build-pass 4 | 5 | use spirv_std::spirv; 6 | 7 | #[track_caller] 8 | fn track_caller_maybe_panic(x: u32) { 9 | if x > 0 { 10 | panic!(); 11 | } 12 | } 13 | 14 | #[spirv(fragment)] 15 | pub fn main(#[spirv(flat)] x: u32) { 16 | track_caller_maybe_panic(x); 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/lang/panic/track_caller.stderr: -------------------------------------------------------------------------------- 1 | warning: `#[inline(never)]` function `track_caller::track_caller_maybe_panic::panic_cold_explicit` has been inlined 2 | --> $DIR/track_caller.rs:10:9 3 | | 4 | 10 | panic!(); 5 | | ^^^^^^^^ 6 | | 7 | = note: inlining was required due to panicking 8 | = note: called from `track_caller::track_caller_maybe_panic` 9 | 10 | warning: 1 warning emitted 11 | 12 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/bad-deduce-storage-class.rs: -------------------------------------------------------------------------------- 1 | // Tests that storage class deduction (from entry-point signature) fails correctly 2 | // build-fail 3 | 4 | use spirv_std::{Image, spirv}; 5 | 6 | #[spirv(vertex)] 7 | pub fn main( 8 | #[spirv(uniform)] error: &Image!(2D, type=f32), 9 | #[spirv(uniform_constant)] warning: &Image!(2D, type=f32), 10 | ) { 11 | } 12 | 13 | // https://github.com/EmbarkStudios/rust-gpu/issues/585 14 | #[spirv(vertex)] 15 | pub fn issue_585(invalid: Image!(2D, type=f32)) {} 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/bool-inputs-err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | 3 | use spirv_std::spirv; 4 | 5 | pub struct Boolthing { 6 | x: u32, 7 | y: u32, 8 | b: bool, 9 | } 10 | 11 | #[spirv(fragment)] 12 | pub fn fragment( 13 | input: bool, 14 | output: &mut bool, 15 | #[spirv(push_constant)] push: &bool, 16 | #[spirv(uniform)] uniform: &Boolthing, 17 | ) { 18 | } 19 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/bool-inputs-err.stderr: -------------------------------------------------------------------------------- 1 | error: entry-point parameter cannot contain `bool`s 2 | --> $DIR/bool-inputs-err.rs:13:12 3 | | 4 | 13 | input: bool, 5 | | ^^^^ 6 | 7 | error: entry-point parameter cannot contain `bool`s 8 | --> $DIR/bool-inputs-err.rs:14:13 9 | | 10 | 14 | output: &mut bool, 11 | | ^^^^^^^^^ 12 | 13 | error: entry-point parameter cannot contain `bool`s 14 | --> $DIR/bool-inputs-err.rs:15:35 15 | | 16 | 15 | #[spirv(push_constant)] push: &bool, 17 | | ^^^^^ 18 | 19 | error: entry-point parameter cannot contain `bool`s 20 | --> $DIR/bool-inputs-err.rs:16:32 21 | | 22 | 16 | #[spirv(uniform)] uniform: &Boolthing, 23 | | ^^^^^^^^^^ 24 | 25 | error: aborting due to 4 previous errors 26 | 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/bool-inputs.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -Ctarget-feature=+FragmentFullyCoveredEXT,+ext:SPV_EXT_fragment_fully_covered 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn fragment( 8 | #[spirv(front_facing)] front_facing: bool, 9 | #[spirv(fully_covered_ext)] fully_covered_ext: bool, 10 | #[spirv(helper_invocation)] helper_invocation: bool, 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/int-without-flat.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | 3 | use spirv_std::spirv; 4 | 5 | #[spirv(fragment)] 6 | pub fn fragment(int: u32, double: f64) {} 7 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/int-without-flat.stderr: -------------------------------------------------------------------------------- 1 | error: `Fragment` entry-point `Input` parameter must be decorated with `#[spirv(flat)]` 2 | --> $DIR/int-without-flat.rs:6:22 3 | | 4 | 6 | pub fn fragment(int: u32, double: f64) {} 5 | | ^^^ 6 | 7 | error: `Fragment` entry-point `Input` parameter must be decorated with `#[spirv(flat)]` 8 | --> $DIR/int-without-flat.rs:6:35 9 | | 10 | 6 | pub fn fragment(int: u32, double: f64) {} 11 | | ^^^ 12 | 13 | error: aborting due to 2 previous errors 14 | 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-matrix-type-empty.rs: -------------------------------------------------------------------------------- 1 | // Tests that matrix type inference fails correctly, for empty struct 2 | // build-fail 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(matrix)] 7 | pub struct EmptyStruct {} 8 | 9 | #[spirv(fragment)] 10 | pub fn entry(#[spirv(push_constant)] matrix: &EmptyStruct) {} 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-matrix-type-empty.stderr: -------------------------------------------------------------------------------- 1 | error: #[spirv(matrix)] type must have at least two fields 2 | --> $DIR/invalid-matrix-type-empty.rs:7:1 3 | | 4 | 7 | pub struct EmptyStruct {} 5 | | ^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: aborting due to 1 previous error 8 | 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-matrix-type.rs: -------------------------------------------------------------------------------- 1 | // Tests that matrix type inference fails correctly 2 | // build-fail 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(matrix)] 7 | pub struct _FewerFields { 8 | _v: glam::Vec3, 9 | } 10 | 11 | #[spirv(matrix)] 12 | pub struct _NotVectorField { 13 | _x: f32, 14 | _y: f32, 15 | _z: f32, 16 | } 17 | 18 | #[spirv(matrix)] 19 | pub struct _DifferentType { 20 | _x: glam::Vec3, 21 | _y: glam::Vec2, 22 | } 23 | 24 | #[spirv(fragment)] 25 | pub fn _entry(_arg1: _FewerFields, _arg2: _NotVectorField, _arg3: _DifferentType) {} 26 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-matrix-type.stderr: -------------------------------------------------------------------------------- 1 | error: #[spirv(matrix)] type must have at least two fields 2 | --> $DIR/invalid-matrix-type.rs:7:1 3 | | 4 | 7 | pub struct _FewerFields { 5 | | ^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | error: #[spirv(matrix)] type fields must all be vectors 8 | --> $DIR/invalid-matrix-type.rs:12:1 9 | | 10 | 12 | pub struct _NotVectorField { 11 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 12 | | 13 | = note: field type is f32 14 | 15 | error: #[spirv(matrix)] type fields must all be the same type 16 | --> $DIR/invalid-matrix-type.rs:19:1 17 | | 18 | 19 | pub struct _DifferentType { 19 | | ^^^^^^^^^^^^^^^^^^^^^^^^^ 20 | 21 | error: aborting due to 3 previous errors 22 | 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-storage-class.rs: -------------------------------------------------------------------------------- 1 | // Tests that certain storage class `#[spirv(...)]` attributes are disallowed. 2 | 3 | // build-fail 4 | 5 | use spirv_std::spirv; 6 | 7 | #[spirv(vertex)] 8 | fn _entry( 9 | #[spirv(input)] _: (), 10 | #[spirv(output)] _: (), 11 | #[spirv(private)] _: (), 12 | #[spirv(function)] _: (), 13 | #[spirv(generic)] _: (), 14 | ) { 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invalid-storage-class.stderr: -------------------------------------------------------------------------------- 1 | error: `Input` storage class is the default and should not be explicitly specified 2 | --> $DIR/invalid-storage-class.rs:9:13 3 | | 4 | 9 | #[spirv(input)] _: (), 5 | | ^^^^^ 6 | 7 | error: `Output` storage class is the default and should not be explicitly specified 8 | --> $DIR/invalid-storage-class.rs:10:13 9 | | 10 | 10 | #[spirv(output)] _: (), 11 | | ^^^^^^ 12 | 13 | error: `Private` storage class can not be used as part of an entry's interface 14 | --> $DIR/invalid-storage-class.rs:11:13 15 | | 16 | 11 | #[spirv(private)] _: (), 17 | | ^^^^^^^ 18 | 19 | error: `Function` storage class can not be used as part of an entry's interface 20 | --> $DIR/invalid-storage-class.rs:12:13 21 | | 22 | 12 | #[spirv(function)] _: (), 23 | | ^^^^^^^^ 24 | 25 | error: `Generic` storage class can not be used as part of an entry's interface 26 | --> $DIR/invalid-storage-class.rs:13:13 27 | | 28 | 13 | #[spirv(generic)] _: (), 29 | | ^^^^^^^ 30 | 31 | error: aborting due to 5 previous errors 32 | 33 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invariant-invalid.rs: -------------------------------------------------------------------------------- 1 | // Tests that the invariant attribute can't be applied on inputs 2 | // build-fail 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(vertex)] 7 | pub fn main(#[spirv(invariant)] input: f32) {} 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invariant-invalid.stderr: -------------------------------------------------------------------------------- 1 | error: `#[spirv(invariant)]` is only valid on Output variables 2 | --> $DIR/invariant-invalid.rs:7:21 3 | | 4 | 7 | pub fn main(#[spirv(invariant)] input: f32) {} 5 | | ^^^^^^^^^ 6 | 7 | error: aborting due to 1 previous error 8 | 9 | -------------------------------------------------------------------------------- /tests/compiletests/ui/spirv-attr/invariant.rs: -------------------------------------------------------------------------------- 1 | // Tests that the invariant attribute works 2 | // build-pass 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(vertex)] 7 | pub fn main(#[spirv(invariant)] output: &mut f32) {} 8 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/mutability-errors.rs: -------------------------------------------------------------------------------- 1 | // Tests that using `&mut` (or interior mutability) with read-only storage classes 2 | // does actually error (see `mutability-errors.stderr` for the error messages). 3 | // build-fail 4 | 5 | use core::sync::atomic::AtomicU32; 6 | use spirv_std::{image::Image2d, spirv}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | #[spirv(descriptor_set = 0, binding = 0)] implicit_uniform_constant_mut: &mut Image2d, 11 | #[spirv(uniform_constant, descriptor_set = 0, binding = 0)] uniform_constant_mut: &mut Image2d, 12 | #[spirv(uniform, descriptor_set = 0, binding = 0)] uniform_mut: &mut u32, 13 | #[spirv(uniform, descriptor_set = 0, binding = 0)] uniform_interior_mut: &AtomicU32, 14 | #[spirv(push_constant)] push_constant_mut: &mut u32, 15 | #[spirv(push_constant)] push_constant_interior_mut: &AtomicU32, 16 | ) { 17 | } 18 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/push_constant.rs: -------------------------------------------------------------------------------- 1 | // Test that using push constants passes (Vulkan) validation. 2 | 3 | // build-pass 4 | use spirv_std::spirv; 5 | 6 | #[derive(Copy, Clone)] 7 | pub struct ShaderConstants { 8 | pub width: u32, 9 | pub height: u32, 10 | pub time: f32, 11 | } 12 | 13 | #[spirv(fragment)] 14 | pub fn main(#[spirv(push_constant)] constants: &ShaderConstants) { 15 | let _constants = *constants; 16 | } 17 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/runtime_descriptor_array.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing 3 | 4 | use spirv_std::spirv; 5 | use spirv_std::{Image, RuntimeArray, Sampler}; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(descriptor_set = 0, binding = 0)] sampler: &Sampler, 10 | #[spirv(descriptor_set = 0, binding = 1)] slice: &RuntimeArray, 11 | #[spirv(descriptor_set = 0, binding = 2)] sized_slice: &[Image!(2D, type=f32, sampled); 5], 12 | output: &mut glam::Vec4, 13 | ) { 14 | let img = unsafe { slice.index(5) }; 15 | let v2 = glam::Vec2::new(0.0, 1.0); 16 | let r1: glam::Vec4 = img.sample(*sampler, v2); 17 | 18 | let img_2 = &sized_slice[2]; 19 | let r2: glam::Vec4 = img_2.sample(*sampler, v2); 20 | 21 | *output = r1 + r2; 22 | } 23 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/runtime_descriptor_array_error.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | 3 | use spirv_std::{Image, RuntimeArray, spirv}; 4 | 5 | #[spirv(fragment)] 6 | pub fn main( 7 | #[spirv(descriptor_set = 0, binding = 0)] one: &[Image!(2D, type=f32, sampled)], 8 | #[spirv(uniform, descriptor_set = 0, binding = 0)] two: &RuntimeArray, 9 | ) { 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/runtime_descriptor_array_error.stderr: -------------------------------------------------------------------------------- 1 | error: descriptor indexing must use &RuntimeArray, not &[T] 2 | --> $DIR/runtime_descriptor_array_error.rs:7:52 3 | | 4 | 7 | #[spirv(descriptor_set = 0, binding = 0)] one: &[Image!(2D, type=f32, sampled)], 5 | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | warning: use &[T] instead of &RuntimeArray 8 | --> $DIR/runtime_descriptor_array_error.rs:8:61 9 | | 10 | 8 | #[spirv(uniform, descriptor_set = 0, binding = 0)] two: &RuntimeArray, 11 | | ^^^^^^^^^^^^^^^^^^ 12 | 13 | error: aborting due to 1 previous error; 1 warning emitted 14 | 15 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/storage_buffer-dst.rs: -------------------------------------------------------------------------------- 1 | // Test that using DST (i.e. slice) storage buffers passes (Vulkan) validation. 2 | 3 | // build-pass 4 | use spirv_std::spirv; 5 | 6 | #[spirv(fragment)] 7 | pub fn main(#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] slice: &mut [f32]) { 8 | let float: f32 = slice[0]; 9 | let _ = float; 10 | } 11 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/typed_buffer.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use glam::Vec4; 4 | use spirv_std::TypedBuffer; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] single: &TypedBuffer, 10 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] single_mut: &mut TypedBuffer, 11 | ) { 12 | **single_mut = **single; 13 | } 14 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/typed_buffer_descriptor_array.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing 3 | 4 | use glam::Vec4; 5 | use spirv_std::spirv; 6 | use spirv_std::{RuntimeArray, TypedBuffer}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] desc_array: &RuntimeArray< 11 | TypedBuffer, 12 | >, 13 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] desc_array_mut: &mut RuntimeArray< 14 | TypedBuffer, 15 | >, 16 | ) { 17 | unsafe { 18 | for buffer in 0..3 { 19 | let mut buffer_from = desc_array.index(buffer); 20 | let buffer_to = desc_array_mut.index_mut(buffer); 21 | **buffer_to = **buffer_from; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/typed_buffer_descriptor_array_slice.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | // compile-flags: -C target-feature=+RuntimeDescriptorArray,+ext:SPV_EXT_descriptor_indexing 3 | 4 | use glam::Vec4; 5 | use spirv_std::spirv; 6 | use spirv_std::{RuntimeArray, TypedBuffer}; 7 | 8 | #[spirv(fragment)] 9 | pub fn main( 10 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] desc_array: &RuntimeArray< 11 | TypedBuffer<[Vec4]>, 12 | >, 13 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] desc_array_mut: &mut RuntimeArray< 14 | TypedBuffer<[Vec4]>, 15 | >, 16 | ) { 17 | unsafe { 18 | for buffer in 0..3 { 19 | let mut buffer_from = desc_array.index(buffer); 20 | let buffer_to = desc_array_mut.index_mut(buffer); 21 | for i in 42..48 { 22 | buffer_to[i] = buffer_from[i]; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/compiletests/ui/storage_class/typed_buffer_slice.rs: -------------------------------------------------------------------------------- 1 | // build-pass 2 | 3 | use glam::Vec4; 4 | use spirv_std::TypedBuffer; 5 | use spirv_std::spirv; 6 | 7 | #[spirv(fragment)] 8 | pub fn main( 9 | #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] slice: &TypedBuffer<[Vec4]>, 10 | #[spirv(storage_buffer, descriptor_set = 0, binding = 1)] slice_mut: &mut TypedBuffer<[Vec4]>, 11 | ) { 12 | for i in 0..5 { 13 | slice_mut[i] = slice[i]; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/compiletests/ui/target_features_err.rs: -------------------------------------------------------------------------------- 1 | // build-fail 2 | // compile-flags: -Ctarget-feature=+rayTracingKHR,+ext:SPV_KHR_ray_tracing 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(any_hit)] 7 | pub fn main() { 8 | unsafe { spirv_std::arch::terminate_ray() } 9 | } 10 | -------------------------------------------------------------------------------- /tests/compiletests/ui/target_features_err.stderr: -------------------------------------------------------------------------------- 1 | error: Invalid Capability: `rayTracingKHR` 2 | 3 | error: aborting due to 1 previous error 4 | 5 | -------------------------------------------------------------------------------- /tests/difftests/bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "difftests" 3 | version.workspace = true 4 | authors.workspace = true 5 | edition.workspace = true 6 | license.workspace = true 7 | repository.workspace = true 8 | 9 | # See rustc_codegen_spirv/Cargo.toml for details on these features 10 | [features] 11 | default = ["use-compiled-tools"] 12 | use-installed-tools = [] 13 | use-compiled-tools = [] 14 | 15 | [dependencies] 16 | anyhow = "1.0" 17 | tracing = "0.1" 18 | tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] } 19 | tempfile = "3.5" 20 | tester = "0.9.1" 21 | serde = { version = "1.0", features = ["derive"] } 22 | serde_json = "1.0" 23 | thiserror = "1.0" 24 | toml = { version = "0.8.20", default-features = false, features = ["parse"] } 25 | bytesize = "2.0.1" 26 | 27 | [lints] 28 | workspace = true 29 | -------------------------------------------------------------------------------- /tests/difftests/lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "difftest" 3 | version.workspace = true 4 | authors.workspace = true 5 | edition.workspace = true 6 | license.workspace = true 7 | repository.workspace = true 8 | 9 | # See rustc_codegen_spirv/Cargo.toml for details on these features 10 | [features] 11 | use-installed-tools = [ 12 | "spirv-builder/use-installed-tools" 13 | ] 14 | use-compiled-tools = [ 15 | "spirv-builder/use-compiled-tools" 16 | ] 17 | 18 | [dependencies] 19 | spirv-builder.workspace = true 20 | serde = { version = "1.0", features = ["derive"] } 21 | serde_json = "1.0" 22 | wgpu = { version = "23", features = ["spirv", "vulkan-portability"] } 23 | tempfile = "3.5" 24 | futures = "0.3.31" 25 | bytemuck = "1.21.0" 26 | thiserror = "1.0" 27 | 28 | [lints] 29 | workspace = true 30 | -------------------------------------------------------------------------------- /tests/difftests/lib/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use std::{fs, path::Path}; 3 | use thiserror::Error; 4 | 5 | #[derive(Error, Debug)] 6 | pub enum ConfigError { 7 | #[error("I/O error: {0}")] 8 | Io(#[from] std::io::Error), 9 | #[error("JSON error: {0}")] 10 | Json(#[from] serde_json::Error), 11 | } 12 | 13 | #[derive(Debug, Deserialize)] 14 | pub struct Config { 15 | pub output_path: std::path::PathBuf, 16 | } 17 | 18 | impl Config { 19 | pub fn from_path>(path: P) -> Result { 20 | let content = fs::read_to_string(path)?; 21 | let config = serde_json::from_str(&content)?; 22 | Ok(config) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/difftests/lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod scaffold; 3 | 4 | #[cfg(test)] 5 | mod tests { 6 | use super::config::Config; 7 | use std::io::Write; 8 | use tempfile::NamedTempFile; 9 | 10 | #[test] 11 | fn test_config_from_path() { 12 | let mut tmp = NamedTempFile::new().unwrap(); 13 | let config_json = r#"{ "output_path": "/tmp/output.txt" }"#; 14 | write!(tmp, "{}", config_json).unwrap(); 15 | let config = Config::from_path(tmp.path()).unwrap(); 16 | assert_eq!(config.output_path.to_str().unwrap(), "/tmp/output.txt"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/difftests/lib/src/scaffold/compute/mod.rs: -------------------------------------------------------------------------------- 1 | mod wgpu; 2 | pub use wgpu::{RustComputeShader, WgpuComputeTest, WgslComputeShader}; 3 | -------------------------------------------------------------------------------- /tests/difftests/lib/src/scaffold/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod compute; 2 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "simple-compute-rust" 3 | edition.workspace = true 4 | 5 | [lints] 6 | workspace = true 7 | 8 | [lib] 9 | crate-type = ["dylib"] 10 | 11 | # Common deps 12 | [dependencies] 13 | 14 | # GPU deps 15 | [target.'cfg(target_arch = "spirv")'.dependencies] 16 | spirv-std.workspace = true 17 | 18 | # CPU deps 19 | [target.'cfg(not(target_arch = "spirv"))'.dependencies] 20 | difftest.workspace = true 21 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg(target_arch = "spirv")] 2 | #![no_std] 3 | 4 | use spirv_std::spirv; 5 | 6 | #[spirv(compute(threads(1)))] 7 | pub fn main_cs(#[spirv(storage_buffer, descriptor_set = 0, binding = 0)] output: &mut [u32]) { 8 | output[0] = 42; 9 | } 10 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-rust/src/main.rs: -------------------------------------------------------------------------------- 1 | use difftest::config::Config; 2 | use difftest::scaffold::compute::{RustComputeShader, WgpuComputeTest}; 3 | 4 | fn main() { 5 | // Load the config from the harness. 6 | let config = Config::from_path(std::env::args().nth(1).unwrap()).unwrap(); 7 | 8 | // Define test parameters, loading the rust shader from the current crate. 9 | let test = WgpuComputeTest::new(RustComputeShader::default(), [1, 1, 1], 1024); 10 | 11 | // Run the test and write the output to a file. 12 | test.run_test(&config).unwrap(); 13 | } 14 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-wgsl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "simple-compute-wgsl" 3 | edition.workspace = true 4 | 5 | [lints] 6 | workspace = true 7 | 8 | [dependencies] 9 | difftest.workspace = true 10 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-wgsl/shader.wgsl: -------------------------------------------------------------------------------- 1 | @group(0) @binding(0) 2 | var output: array; 3 | 4 | @compute @workgroup_size(1) 5 | fn main_cs() { 6 | output[0] = 42u; 7 | } 8 | -------------------------------------------------------------------------------- /tests/difftests/tests/simple-compute/simple-compute-wgsl/src/main.rs: -------------------------------------------------------------------------------- 1 | use difftest::config::Config; 2 | use difftest::scaffold::compute::{WgpuComputeTest, WgslComputeShader}; 3 | 4 | fn main() { 5 | // Load the config from the harness. 6 | let config = Config::from_path(std::env::args().nth(1).unwrap()).unwrap(); 7 | 8 | // Define test parameters, loading the wgsl shader from the crate directory. 9 | let test = WgpuComputeTest::new(WgslComputeShader::default(), [1, 1, 1], 1024); 10 | 11 | // Run the test and write the output to a file. 12 | test.run_test(&config).unwrap(); 13 | } 14 | --------------------------------------------------------------------------------