diff --git a/src/valid/interface.rs b/src/valid/interface.rs index 7ba60515c6..504a6bab53 100644 --- a/src/valid/interface.rs +++ b/src/valid/interface.rs @@ -63,6 +63,8 @@ pub enum VaryingError { pub enum EntryPointError { #[error("Multiple conflicting entry points")] Conflict, + #[error("Missing position built-in output value")] + MissingVertexOutputPosition, #[error("Early depth test is not applicable")] UnexpectedEarlyDepthTest, #[error("Workgroup size is not applicable")] @@ -353,7 +355,6 @@ impl VaryingContext<'_> { .map_err(|e| e.with_span_context(span_context)), None => { match self.types[ty].inner { - //TODO: check the member types crate::TypeInner::Struct { ref members, .. } => { for (index, member) in members.iter().enumerate() { let span_context = self.types.get_span_context(ty); @@ -369,7 +370,6 @@ impl VaryingContext<'_> { #[cfg(not(feature = "validate"))] let _ = index; } - // TODO: shouldn't this be validate? Some(ref binding) => self .validate_impl(member.ty, binding) .map_err(|e| e.with_span_context(span_context))?, @@ -545,6 +545,33 @@ impl super::Validator { return Err(EntryPointError::UnexpectedWorkgroupSize.with_span()); } + #[cfg(feature = "validate")] + if ep.stage == crate::ShaderStage::Vertex { + let has_position = match ep.function.result { + Some(ref res) => { + const fn is_pos(binding: &crate::Binding) -> bool { + matches!( + binding, + &crate::Binding::BuiltIn(crate::BuiltIn::Position { .. }) + ) + } + match res.binding { + Some(ref binding) => is_pos(binding), + None => match module.types[res.ty].inner { + crate::TypeInner::Struct { ref members, .. } => members + .iter() + .any(|member| member.binding.as_ref().map(is_pos).unwrap_or(false)), + _ => false, + }, + } + } + None => false, + }; + if !has_position { + return Err(EntryPointError::MissingVertexOutputPosition.with_span()); + } + } + let info = self .validate_function(&ep.function, module, mod_info, true) .map_err(WithSpan::into_other)?; diff --git a/tests/in/functions-webgl.wgsl b/tests/in/functions-webgl.wgsl index 9192f68685..2355aa2c99 100644 --- a/tests/in/functions-webgl.wgsl +++ b/tests/in/functions-webgl.wgsl @@ -7,7 +7,7 @@ fn test_fma() -> vec2 { } -@vertex +@fragment fn main() { let a = test_fma(); } diff --git a/tests/in/glsl/277-casting.vert b/tests/in/glsl/277-casting.frag similarity index 100% rename from tests/in/glsl/277-casting.vert rename to tests/in/glsl/277-casting.frag diff --git a/tests/in/glsl/280-matrix-cast.vert b/tests/in/glsl/280-matrix-cast.frag similarity index 100% rename from tests/in/glsl/280-matrix-cast.vert rename to tests/in/glsl/280-matrix-cast.frag diff --git a/tests/in/glsl/484-preprocessor-if.vert b/tests/in/glsl/484-preprocessor-if.frag similarity index 100% rename from tests/in/glsl/484-preprocessor-if.vert rename to tests/in/glsl/484-preprocessor-if.frag diff --git a/tests/in/glsl/896-push-constant.vert b/tests/in/glsl/896-push-constant.frag similarity index 100% rename from tests/in/glsl/896-push-constant.vert rename to tests/in/glsl/896-push-constant.frag diff --git a/tests/in/glsl/900-implicit-conversions.vert b/tests/in/glsl/900-implicit-conversions.frag similarity index 100% rename from tests/in/glsl/900-implicit-conversions.vert rename to tests/in/glsl/900-implicit-conversions.frag diff --git a/tests/in/glsl/901-lhs-field-select.vert b/tests/in/glsl/901-lhs-field-select.frag similarity index 100% rename from tests/in/glsl/901-lhs-field-select.vert rename to tests/in/glsl/901-lhs-field-select.frag diff --git a/tests/in/glsl/931-constant-emitting.vert b/tests/in/glsl/931-constant-emitting.frag similarity index 100% rename from tests/in/glsl/931-constant-emitting.vert rename to tests/in/glsl/931-constant-emitting.frag diff --git a/tests/in/glsl/932-for-loop-if.vert b/tests/in/glsl/932-for-loop-if.frag similarity index 100% rename from tests/in/glsl/932-for-loop-if.vert rename to tests/in/glsl/932-for-loop-if.frag diff --git a/tests/in/glsl/constant-array-size.vert b/tests/in/glsl/constant-array-size.frag similarity index 100% rename from tests/in/glsl/constant-array-size.vert rename to tests/in/glsl/constant-array-size.frag diff --git a/tests/in/glsl/declarations.vert b/tests/in/glsl/declarations.frag similarity index 100% rename from tests/in/glsl/declarations.vert rename to tests/in/glsl/declarations.frag diff --git a/tests/in/glsl/global-constant-array.vert b/tests/in/glsl/global-constant-array.frag similarity index 100% rename from tests/in/glsl/global-constant-array.vert rename to tests/in/glsl/global-constant-array.frag diff --git a/tests/in/glsl/long-form-matrix.vert b/tests/in/glsl/long-form-matrix.frag similarity index 100% rename from tests/in/glsl/long-form-matrix.vert rename to tests/in/glsl/long-form-matrix.frag diff --git a/tests/in/glsl/math-functions.vert b/tests/in/glsl/math-functions.frag similarity index 100% rename from tests/in/glsl/math-functions.vert rename to tests/in/glsl/math-functions.frag diff --git a/tests/in/glsl/vector-functions.vert b/tests/in/glsl/vector-functions.frag similarity index 100% rename from tests/in/glsl/vector-functions.vert rename to tests/in/glsl/vector-functions.frag diff --git a/tests/in/math-functions.wgsl b/tests/in/math-functions.wgsl index db50880d14..da67ca23e0 100644 --- a/tests/in/math-functions.wgsl +++ b/tests/in/math-functions.wgsl @@ -1,4 +1,4 @@ -@vertex +@fragment fn main() { let f = 1.0; let v = vec4(0.0); diff --git a/tests/in/multiview.wgsl b/tests/in/multiview.wgsl index b4531c8a76..0eedd08786 100644 --- a/tests/in/multiview.wgsl +++ b/tests/in/multiview.wgsl @@ -1,2 +1,2 @@ -@vertex +@fragment fn main(@builtin(view_index) view_index: i32) {} diff --git a/tests/in/multiview_webgl.wgsl b/tests/in/multiview_webgl.wgsl index b4531c8a76..0eedd08786 100644 --- a/tests/in/multiview_webgl.wgsl +++ b/tests/in/multiview_webgl.wgsl @@ -1,2 +1,2 @@ -@vertex +@fragment fn main(@builtin(view_index) view_index: i32) {} diff --git a/tests/in/spv/degrees.spv b/tests/in/spv/degrees.spv index 0e5eeab480..b7aa393c07 100644 Binary files a/tests/in/spv/degrees.spv and b/tests/in/spv/degrees.spv differ diff --git a/tests/in/spv/degrees.spvasm b/tests/in/spv/degrees.spvasm new file mode 100644 index 0000000000..de2605a517 --- /dev/null +++ b/tests/in/spv/degrees.spvasm @@ -0,0 +1,47 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 27 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %colour + OpSource GLSL 450 + OpName %main "main" + OpName %deg "deg" + OpName %rad "rad" + OpName %deg_again "deg_again" + OpName %colour "colour" + OpDecorate %colour Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float + %float_15 = OpConstant %float 15 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %colour = OpVariable %_ptr_Output_v4float Output + %v3float = OpTypeVector %float 3 + %float_1 = OpConstant %float 1 + %main = OpFunction %void None %3 + %5 = OpLabel + %deg = OpVariable %_ptr_Function_float Function + %rad = OpVariable %_ptr_Function_float Function + %deg_again = OpVariable %_ptr_Function_float Function + OpStore %deg %float_15 + %11 = OpLoad %float %deg + %12 = OpExtInst %float %1 Radians %11 + OpStore %rad %12 + %14 = OpLoad %float %rad + %15 = OpExtInst %float %1 Degrees %14 + OpStore %deg_again %15 + %19 = OpLoad %float %deg_again + %21 = OpCompositeConstruct %v3float %19 %19 %19 + %23 = OpCompositeExtract %float %21 0 + %24 = OpCompositeExtract %float %21 1 + %25 = OpCompositeExtract %float %21 2 + %26 = OpCompositeConstruct %v4float %23 %24 %25 %float_1 + OpStore %colour %26 + OpReturn + OpFunctionEnd diff --git a/tests/in/spv/inv-hyperbolic-trig-functions.spv b/tests/in/spv/inv-hyperbolic-trig-functions.spv index a87d8deec5..da365355e8 100644 Binary files a/tests/in/spv/inv-hyperbolic-trig-functions.spv and b/tests/in/spv/inv-hyperbolic-trig-functions.spv differ diff --git a/tests/in/spv/inv-hyperbolic-trig-functions.spvasm b/tests/in/spv/inv-hyperbolic-trig-functions.spvasm new file mode 100644 index 0000000000..efa9620893 --- /dev/null +++ b/tests/in/spv/inv-hyperbolic-trig-functions.spvasm @@ -0,0 +1,37 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 19 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" + OpSource GLSL 450 + OpName %main "main" + OpName %b "b" + OpName %a "a" + OpName %c "c" + OpName %d "d" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 +%_ptr_Function_float = OpTypePointer Function %float +%_ptr_Private_float = OpTypePointer Private %float + %a = OpVariable %_ptr_Private_float Private + %main = OpFunction %void None %3 + %5 = OpLabel + %b = OpVariable %_ptr_Function_float Function + %c = OpVariable %_ptr_Function_float Function + %d = OpVariable %_ptr_Function_float Function + %11 = OpLoad %float %a + %12 = OpExtInst %float %1 Asinh %11 + OpStore %b %12 + %14 = OpLoad %float %a + %15 = OpExtInst %float %1 Acosh %14 + OpStore %c %15 + %17 = OpLoad %float %a + %18 = OpExtInst %float %1 Atanh %17 + OpStore %d %18 + OpReturn + OpFunctionEnd diff --git a/tests/in/spv/quad-vert.spvasm b/tests/in/spv/quad-vert.spvasm new file mode 100644 index 0000000000..7633c94c59 --- /dev/null +++ b/tests/in/spv/quad-vert.spvasm @@ -0,0 +1,61 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 31 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %v_uv %a_uv %_ %a_pos + OpSource GLSL 460 + OpName %main "main" + OpName %v_uv "v_uv" + OpName %a_uv "a_uv" + OpName %gl_PerVertex "gl_PerVertex" + OpMemberName %gl_PerVertex 0 "gl_Position" + OpMemberName %gl_PerVertex 1 "gl_PointSize" + OpMemberName %gl_PerVertex 2 "gl_ClipDistance" + OpMemberName %gl_PerVertex 3 "gl_CullDistance" + OpName %_ "" + OpName %a_pos "a_pos" + OpDecorate %v_uv Location 0 + OpDecorate %a_uv Location 1 + OpMemberDecorate %gl_PerVertex 0 BuiltIn Position + OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize + OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance + OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance + OpDecorate %gl_PerVertex Block + OpDecorate %a_pos Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Output_v2float = OpTypePointer Output %v2float + %v_uv = OpVariable %_ptr_Output_v2float Output +%_ptr_Input_v2float = OpTypePointer Input %v2float + %a_uv = OpVariable %_ptr_Input_v2float Input + %v4float = OpTypeVector %float 4 + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 +%_arr_float_uint_1 = OpTypeArray %float %uint_1 +%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1 +%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex + %_ = OpVariable %_ptr_Output_gl_PerVertex Output + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 + %a_pos = OpVariable %_ptr_Input_v2float Input + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %main = OpFunction %void None %3 + %5 = OpLabel + %12 = OpLoad %v2float %a_uv + OpStore %v_uv %12 + %23 = OpLoad %v2float %a_pos + %26 = OpCompositeExtract %float %23 0 + %27 = OpCompositeExtract %float %23 1 + %28 = OpCompositeConstruct %v4float %26 %27 %float_0 %float_1 + %30 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %30 %28 + OpReturn + OpFunctionEnd diff --git a/tests/in/spv/shadow.spvasm b/tests/in/spv/shadow.spvasm new file mode 100644 index 0000000000..e928b71c40 --- /dev/null +++ b/tests/in/spv/shadow.spvasm @@ -0,0 +1,291 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 221 +; Schema: 0 + OpCapability Shader + OpExtension "SPV_KHR_storage_buffer_storage_class" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %fs_main "fs_main" %in_normal_fs %in_position_fs %out_color_fs + OpExecutionMode %fs_main OriginUpperLeft + OpSource GLSL 450 + OpName %t_shadow "t_shadow" + OpName %sampler_shadow "sampler_shadow" + OpName %color "color" + OpName %i "i" + OpName %Globals "Globals" + OpMemberName %Globals 0 "num_lights" + OpName %u_globals "u_globals" + OpName %Light "Light" + OpMemberName %Light 0 "proj" + OpMemberName %Light 1 "pos" + OpMemberName %Light 2 "color" + OpName %Lights "Lights" + OpMemberName %Lights 0 "data" + OpName %s_lights "s_lights" + OpName %in_position_fs "in_position_fs" + OpName %in_normal_fs "in_normal_fs" + OpName %out_color_fs "out_color_fs" + OpName %fs_main "fs_main" + OpDecorate %t_shadow DescriptorSet 0 + OpDecorate %t_shadow Binding 2 + OpDecorate %sampler_shadow DescriptorSet 0 + OpDecorate %sampler_shadow Binding 3 + OpDecorate %Globals Block + OpMemberDecorate %Globals 0 Offset 0 + OpDecorate %u_globals DescriptorSet 0 + OpDecorate %u_globals Binding 0 + OpMemberDecorate %Light 0 Offset 0 + OpMemberDecorate %Light 0 ColMajor + OpMemberDecorate %Light 0 MatrixStride 16 + OpMemberDecorate %Light 1 Offset 64 + OpMemberDecorate %Light 2 Offset 80 + OpDecorate %_runtimearr_Light ArrayStride 96 + OpDecorate %Lights BufferBlock + OpMemberDecorate %Lights 0 Offset 0 + OpMemberDecorate %Lights 0 NonWritable + OpDecorate %s_lights DescriptorSet 0 + OpDecorate %s_lights Binding 1 + OpDecorate %in_position_fs Location 1 + OpDecorate %in_normal_fs Location 0 + OpDecorate %out_color_fs Location 0 + %void = OpTypeVoid + %float = OpTypeFloat 32 + %float_0 = OpConstant %float 0 + %float_1 = OpConstant %float 1 + %float_0_5 = OpConstant %float 0.5 + %float_n0_5 = OpConstant %float -0.5 +%float_0_0500000007 = OpConstant %float 0.0500000007 + %v3float = OpTypeVector %float 3 + %9 = OpConstantComposite %v3float %float_0_0500000007 %float_0_0500000007 %float_0_0500000007 + %uint = OpTypeInt 32 0 + %uint_10 = OpConstant %uint 10 + %uint_0 = OpConstant %uint 0 + %uint_1 = OpConstant %uint 1 + %v4float = OpTypeVector %float 4 + %19 = OpTypeFunction %float %uint %v4float + %bool = OpTypeBool + %27 = OpTypeImage %float 2D 1 1 0 1 Unknown +%_ptr_UniformConstant_27 = OpTypePointer UniformConstant %27 + %t_shadow = OpVariable %_ptr_UniformConstant_27 UniformConstant + %31 = OpTypeSampledImage %27 + %32 = OpTypeSampler +%_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32 +%sampler_shadow = OpVariable %_ptr_UniformConstant_32 UniformConstant + %v2float = OpTypeVector %float 2 + %int = OpTypeInt 32 1 + %float_0_0 = OpConstant %float 0 +%_ptr_Function_v3float = OpTypePointer Function %v3float +%_ptr_Function_uint = OpTypePointer Function %uint + %65 = OpTypeFunction %void + %v4uint = OpTypeVector %uint 4 + %Globals = OpTypeStruct %v4uint +%_ptr_Uniform_Globals = OpTypePointer Uniform %Globals + %u_globals = OpVariable %_ptr_Uniform_Globals Uniform +%_ptr_Uniform_v4uint = OpTypePointer Uniform %v4uint + %int_0 = OpConstant %int 0 +%_ptr_Uniform_uint = OpTypePointer Uniform %uint + %int_0_0 = OpConstant %int 0 +%mat4v4float = OpTypeMatrix %v4float 4 + %Light = OpTypeStruct %mat4v4float %v4float %v4float +%_runtimearr_Light = OpTypeRuntimeArray %Light + %Lights = OpTypeStruct %_runtimearr_Light +%_ptr_StorageBuffer_Lights = OpTypePointer StorageBuffer %Lights + %s_lights = OpVariable %_ptr_StorageBuffer_Lights StorageBuffer +%_ptr_StorageBuffer__runtimearr_Light = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_1 = OpConstant %int 0 +%_ptr_StorageBuffer_Light = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_mat4v4float = OpTypePointer StorageBuffer %mat4v4float + %int_0_2 = OpConstant %int 0 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%in_position_fs = OpVariable %_ptr_Input_v4float Input +%_ptr_Input_v3float = OpTypePointer Input %v3float +%in_normal_fs = OpVariable %_ptr_Input_v3float Input +%_ptr_StorageBuffer__runtimearr_Light_0 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_3 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_0 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float + %int_1 = OpConstant %int 1 +%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float + %int_0_4 = OpConstant %int 0 +%_ptr_StorageBuffer__runtimearr_Light_1 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_5 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_1 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float_0 = OpTypePointer StorageBuffer %v4float + %int_1_0 = OpConstant %int 1 +%_ptr_StorageBuffer_float_0 = OpTypePointer StorageBuffer %float + %int_1_1 = OpConstant %int 1 +%_ptr_StorageBuffer__runtimearr_Light_2 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_6 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_2 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float_1 = OpTypePointer StorageBuffer %v4float + %int_1_2 = OpConstant %int 1 +%_ptr_StorageBuffer_float_1 = OpTypePointer StorageBuffer %float + %int_2 = OpConstant %int 2 +%_ptr_Input_float = OpTypePointer Input %float + %int_0_7 = OpConstant %int 0 +%_ptr_Input_float_0 = OpTypePointer Input %float + %int_1_3 = OpConstant %int 1 +%_ptr_Input_float_1 = OpTypePointer Input %float + %int_2_0 = OpConstant %int 2 +%_ptr_StorageBuffer__runtimearr_Light_3 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_8 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_3 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float_2 = OpTypePointer StorageBuffer %v4float + %int_2_1 = OpConstant %int 2 +%_ptr_StorageBuffer_float_2 = OpTypePointer StorageBuffer %float + %int_0_9 = OpConstant %int 0 +%_ptr_StorageBuffer__runtimearr_Light_4 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_10 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_4 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float_3 = OpTypePointer StorageBuffer %v4float + %int_2_2 = OpConstant %int 2 +%_ptr_StorageBuffer_float_3 = OpTypePointer StorageBuffer %float + %int_1_4 = OpConstant %int 1 +%_ptr_StorageBuffer__runtimearr_Light_5 = OpTypePointer StorageBuffer %_runtimearr_Light + %int_0_11 = OpConstant %int 0 +%_ptr_StorageBuffer_Light_5 = OpTypePointer StorageBuffer %Light +%_ptr_StorageBuffer_v4float_4 = OpTypePointer StorageBuffer %v4float + %int_2_3 = OpConstant %int 2 +%_ptr_StorageBuffer_float_4 = OpTypePointer StorageBuffer %float + %int_2_4 = OpConstant %int 2 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%out_color_fs = OpVariable %_ptr_Output_v4float Output + %18 = OpFunction %float None %19 + %15 = OpFunctionParameter %uint + %16 = OpFunctionParameter %v4float + %20 = OpLabel + %23 = OpCompositeExtract %float %16 3 + %22 = OpFOrdLessThanEqual %bool %23 %float_0 + OpSelectionMerge %24 None + OpBranchConditional %22 %25 %26 + %25 = OpLabel + OpReturnValue %float_1 + %26 = OpLabel + OpBranch %24 + %24 = OpLabel + %30 = OpLoad %27 %t_shadow + %35 = OpLoad %32 %sampler_shadow + %40 = OpCompositeExtract %float %16 0 + %41 = OpCompositeExtract %float %16 1 + %42 = OpCompositeConstruct %v2float %40 %41 + %43 = OpCompositeConstruct %v2float %float_0_5 %float_n0_5 + %39 = OpFMul %v2float %42 %43 + %45 = OpCompositeExtract %float %16 3 + %44 = OpFDiv %float %float_1 %45 + %38 = OpVectorTimesScalar %v2float %39 %44 + %46 = OpCompositeConstruct %v2float %float_0_5 %float_0_5 + %37 = OpFAdd %v2float %38 %46 + %47 = OpCompositeExtract %float %37 0 + %48 = OpCompositeExtract %float %37 1 + %51 = OpBitcast %int %15 + %49 = OpConvertUToF %float %51 + %52 = OpCompositeConstruct %v3float %47 %48 %49 + %53 = OpSampledImage %31 %30 %35 + %56 = OpCompositeExtract %float %16 2 + %58 = OpCompositeExtract %float %16 3 + %57 = OpFDiv %float %float_1 %58 + %55 = OpFMul %float %56 %57 + %54 = OpImageSampleDrefExplicitLod %float %53 %52 %55 Lod %float_0_0 + OpReturnValue %54 + OpFunctionEnd + %fs_main = OpFunction %void None %65 + %66 = OpLabel + %color = OpVariable %_ptr_Function_v3float Function %9 + %i = OpVariable %_ptr_Function_uint Function %uint_0 + OpBranch %67 + %67 = OpLabel + OpLoopMerge %68 %70 None + OpBranch %69 + %69 = OpLabel + %72 = OpLoad %uint %i + %75 = OpAccessChain %_ptr_Uniform_v4uint %u_globals %int_0 + %73 = OpAccessChain %_ptr_Uniform_uint %75 %int_0_0 + %83 = OpLoad %uint %73 + %84 = OpExtInst %uint %1 UMin %83 %uint_10 + %71 = OpUGreaterThanEqual %bool %72 %84 + OpSelectionMerge %85 None + OpBranchConditional %71 %86 %87 + %86 = OpLabel + OpBranch %68 + %87 = OpLabel + OpBranch %85 + %85 = OpLabel + %89 = OpLoad %v3float %color + %93 = OpLoad %uint %i + %100 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light %s_lights %int_0_1 + %106 = OpLoad %uint %i + %98 = OpAccessChain %_ptr_StorageBuffer_Light %100 %106 + %96 = OpAccessChain %_ptr_StorageBuffer_mat4v4float %98 %int_0_2 + %110 = OpLoad %mat4v4float %96 + %113 = OpLoad %v4float %in_position_fs + %94 = OpMatrixTimesVector %v4float %110 %113 + %92 = OpFunctionCall %float %18 %93 %94 + %116 = OpLoad %v3float %in_normal_fs + %117 = OpExtInst %v3float %1 Normalize %116 + %122 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_0 %s_lights %int_0_3 + %125 = OpLoad %uint %i + %121 = OpAccessChain %_ptr_StorageBuffer_Light_0 %122 %125 + %120 = OpAccessChain %_ptr_StorageBuffer_v4float %121 %int_1 + %119 = OpAccessChain %_ptr_StorageBuffer_float %120 %int_0_4 + %131 = OpLoad %float %119 + %135 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_1 %s_lights %int_0_5 + %138 = OpLoad %uint %i + %134 = OpAccessChain %_ptr_StorageBuffer_Light_1 %135 %138 + %133 = OpAccessChain %_ptr_StorageBuffer_v4float_0 %134 %int_1_0 + %132 = OpAccessChain %_ptr_StorageBuffer_float_0 %133 %int_1_1 + %144 = OpLoad %float %132 + %148 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_2 %s_lights %int_0_6 + %151 = OpLoad %uint %i + %147 = OpAccessChain %_ptr_StorageBuffer_Light_2 %148 %151 + %146 = OpAccessChain %_ptr_StorageBuffer_v4float_1 %147 %int_1_2 + %145 = OpAccessChain %_ptr_StorageBuffer_float_1 %146 %int_2 + %157 = OpLoad %float %145 + %158 = OpCompositeConstruct %v3float %131 %144 %157 + %159 = OpAccessChain %_ptr_Input_float %in_position_fs %int_0_7 + %162 = OpLoad %float %159 + %163 = OpAccessChain %_ptr_Input_float_0 %in_position_fs %int_1_3 + %166 = OpLoad %float %163 + %167 = OpAccessChain %_ptr_Input_float_1 %in_position_fs %int_2_0 + %170 = OpLoad %float %167 + %171 = OpCompositeConstruct %v3float %162 %166 %170 + %118 = OpFSub %v3float %158 %171 + %172 = OpExtInst %v3float %1 Normalize %118 + %173 = OpDot %float %117 %172 + %174 = OpExtInst %float %1 FMax %float_0 %173 + %91 = OpFMul %float %92 %174 + %178 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_3 %s_lights %int_0_8 + %181 = OpLoad %uint %i + %177 = OpAccessChain %_ptr_StorageBuffer_Light_3 %178 %181 + %176 = OpAccessChain %_ptr_StorageBuffer_v4float_2 %177 %int_2_1 + %175 = OpAccessChain %_ptr_StorageBuffer_float_2 %176 %int_0_9 + %187 = OpLoad %float %175 + %191 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_4 %s_lights %int_0_10 + %194 = OpLoad %uint %i + %190 = OpAccessChain %_ptr_StorageBuffer_Light_4 %191 %194 + %189 = OpAccessChain %_ptr_StorageBuffer_v4float_3 %190 %int_2_2 + %188 = OpAccessChain %_ptr_StorageBuffer_float_3 %189 %int_1_4 + %200 = OpLoad %float %188 + %204 = OpAccessChain %_ptr_StorageBuffer__runtimearr_Light_5 %s_lights %int_0_11 + %207 = OpLoad %uint %i + %203 = OpAccessChain %_ptr_StorageBuffer_Light_5 %204 %207 + %202 = OpAccessChain %_ptr_StorageBuffer_v4float_4 %203 %int_2_3 + %201 = OpAccessChain %_ptr_StorageBuffer_float_4 %202 %int_2_4 + %213 = OpLoad %float %201 + %214 = OpCompositeConstruct %v3float %187 %200 %213 + %90 = OpVectorTimesScalar %v3float %214 %91 + %88 = OpFAdd %v3float %89 %90 + OpStore %color %88 + OpBranch %70 + %70 = OpLabel + %216 = OpLoad %uint %i + %215 = OpIAdd %uint %216 %uint_1 + OpStore %i %215 + OpBranch %67 + %68 = OpLabel + %219 = OpLoad %v3float %color + %220 = OpCompositeConstruct %v4float %219 %float_1 + OpStore %out_color_fs %220 + OpReturn + OpFunctionEnd diff --git a/tests/out/glsl/functions-webgl.main.Fragment.glsl b/tests/out/glsl/functions-webgl.main.Fragment.glsl new file mode 100644 index 0000000000..9dd084c32a --- /dev/null +++ b/tests/out/glsl/functions-webgl.main.Fragment.glsl @@ -0,0 +1,18 @@ +#version 320 es + +precision highp float; +precision highp int; + + +vec2 test_fma() { + vec2 a = vec2(2.0, 2.0); + vec2 b = vec2(0.5, 0.5); + vec2 c = vec2(0.5, 0.5); + return fma(a, b, c); +} + +void main() { + vec2 _e0 = test_fma(); + return; +} + diff --git a/tests/out/glsl/math-functions.main.Fragment.glsl b/tests/out/glsl/math-functions.main.Fragment.glsl new file mode 100644 index 0000000000..3c5c1dd345 --- /dev/null +++ b/tests/out/glsl/math-functions.main.Fragment.glsl @@ -0,0 +1,31 @@ +#version 310 es + +precision highp float; +precision highp int; + + +void main() { + vec4 v = vec4(0.0); + float a = degrees(1.0); + float b = radians(1.0); + vec4 c = degrees(v); + vec4 d = radians(v); + vec4 e = clamp(v, vec4(0.0), vec4(1.0)); + vec4 g = refract(v, v, 1.0); + int const_dot = ( + ivec2(0, 0).x * ivec2(0, 0).x + ivec2(0, 0).y * ivec2(0, 0).y); + uint first_leading_bit_abs = uint(findMSB(uint(abs(int(0u))))); + uint ctz_a = min(uint(findLSB(0u)), 32u); + int ctz_b = int(min(uint(findLSB(0)), 32u)); + uint ctz_c = min(uint(findLSB(4294967295u)), 32u); + int ctz_d = int(min(uint(findLSB(-1)), 32u)); + uvec2 ctz_e = min(uvec2(findLSB(uvec2(0u))), uvec2(32u)); + ivec2 ctz_f = ivec2(min(uvec2(findLSB(ivec2(0))), uvec2(32u))); + uvec2 ctz_g = min(uvec2(findLSB(uvec2(1u))), uvec2(32u)); + ivec2 ctz_h = ivec2(min(uvec2(findLSB(ivec2(1))), uvec2(32u))); + int clz_a = (-1 < 0 ? 0 : 31 - findMSB(-1)); + uint clz_b = uint(31 - findMSB(1u)); + ivec2 _e40 = ivec2(-1); + ivec2 clz_c = mix(ivec2(31) - findMSB(_e40), ivec2(0), lessThan(_e40, ivec2(0))); + uvec2 clz_d = uvec2(ivec2(31) - findMSB(uvec2(1u))); +} + diff --git a/tests/out/glsl/multiview.main.Fragment.glsl b/tests/out/glsl/multiview.main.Fragment.glsl new file mode 100644 index 0000000000..466aea062f --- /dev/null +++ b/tests/out/glsl/multiview.main.Fragment.glsl @@ -0,0 +1,12 @@ +#version 310 es +#extension GL_EXT_multiview : require + +precision highp float; +precision highp int; + + +void main() { + int view_index = gl_ViewIndex; + return; +} + diff --git a/tests/out/glsl/multiview_webgl.main.Fragment.glsl b/tests/out/glsl/multiview_webgl.main.Fragment.glsl new file mode 100644 index 0000000000..30515289c9 --- /dev/null +++ b/tests/out/glsl/multiview_webgl.main.Fragment.glsl @@ -0,0 +1,12 @@ +#version 300 es +#extension GL_OVR_multiview2 : require + +precision highp float; +precision highp int; + + +void main() { + int view_index = int(gl_ViewID_OVR); + return; +} + diff --git a/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config b/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config index f72fafd91f..98453a04ee 100644 --- a/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config +++ b/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config @@ -1,3 +1,3 @@ -vertex=(main:vs_5_1 ) -fragment=() +vertex=() +fragment=(main:ps_5_1 ) compute=() diff --git a/tests/out/hlsl/math-functions.hlsl.config b/tests/out/hlsl/math-functions.hlsl.config index f72fafd91f..98453a04ee 100644 --- a/tests/out/hlsl/math-functions.hlsl.config +++ b/tests/out/hlsl/math-functions.hlsl.config @@ -1,3 +1,3 @@ -vertex=(main:vs_5_1 ) -fragment=() +vertex=() +fragment=(main:ps_5_1 ) compute=() diff --git a/tests/out/msl/math-functions.msl b/tests/out/msl/math-functions.msl index c2aac6ef98..3db4644cd6 100644 --- a/tests/out/msl/math-functions.msl +++ b/tests/out/msl/math-functions.msl @@ -6,7 +6,7 @@ using metal::uint; constant metal::int2 const_type_1_ = {0, 0}; -vertex void main_( +fragment void main_( ) { metal::float4 v = metal::float4(0.0); float a = ((1.0) * 57.295779513082322865); diff --git a/tests/out/spv/math-functions.spvasm b/tests/out/spv/math-functions.spvasm index 9dbde7ddf0..d8c9c2563b 100644 --- a/tests/out/spv/math-functions.spvasm +++ b/tests/out/spv/math-functions.spvasm @@ -5,7 +5,8 @@ OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %18 "main" +OpEntryPoint Fragment %18 "main" +OpExecutionMode %18 OriginUpperLeft %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 diff --git a/tests/out/spv/multiview.spvasm b/tests/out/spv/multiview.spvasm index bb67d7eba8..792dea5593 100644 --- a/tests/out/spv/multiview.spvasm +++ b/tests/out/spv/multiview.spvasm @@ -7,8 +7,10 @@ OpCapability MultiView OpExtension "SPV_KHR_multiview" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %8 "main" %5 +OpEntryPoint Fragment %8 "main" %5 +OpExecutionMode %8 OriginUpperLeft OpDecorate %5 BuiltIn ViewIndex +OpDecorate %5 Flat %2 = OpTypeVoid %3 = OpTypeInt 32 1 %6 = OpTypePointer Input %3 diff --git a/tests/out/wgsl/277-casting-frag.wgsl b/tests/out/wgsl/277-casting-frag.wgsl new file mode 100644 index 0000000000..26a3db792d --- /dev/null +++ b/tests/out/wgsl/277-casting-frag.wgsl @@ -0,0 +1,12 @@ +fn main_1() { + var a: f32; + + a = f32(1); + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/280-matrix-cast-frag.wgsl b/tests/out/wgsl/280-matrix-cast-frag.wgsl new file mode 100644 index 0000000000..316d936518 --- /dev/null +++ b/tests/out/wgsl/280-matrix-cast-frag.wgsl @@ -0,0 +1,13 @@ +fn main_1() { + var a: mat4x4; + + let _e1 = f32(1); + a = mat4x4(vec4(_e1, 0.0, 0.0, 0.0), vec4(0.0, _e1, 0.0, 0.0), vec4(0.0, 0.0, _e1, 0.0), vec4(0.0, 0.0, 0.0, _e1)); + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/484-preprocessor-if-frag.wgsl b/tests/out/wgsl/484-preprocessor-if-frag.wgsl new file mode 100644 index 0000000000..6b3c4ac973 --- /dev/null +++ b/tests/out/wgsl/484-preprocessor-if-frag.wgsl @@ -0,0 +1,9 @@ +fn main_1() { + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/896-push-constant-frag.wgsl b/tests/out/wgsl/896-push-constant-frag.wgsl new file mode 100644 index 0000000000..729e35a43f --- /dev/null +++ b/tests/out/wgsl/896-push-constant-frag.wgsl @@ -0,0 +1,15 @@ +struct PushConstants { + example: f32, +} + +var c: PushConstants; + +fn main_1() { + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/900-implicit-conversions-frag.wgsl b/tests/out/wgsl/900-implicit-conversions-frag.wgsl new file mode 100644 index 0000000000..97ff5a4fe5 --- /dev/null +++ b/tests/out/wgsl/900-implicit-conversions-frag.wgsl @@ -0,0 +1,69 @@ +fn exact(a: f32) { + var a_1: f32; + + a_1 = a; + return; +} + +fn exact_1(a_2: i32) { + var a_3: i32; + + a_3 = a_2; + return; +} + +fn implicit(a_4: f32) { + var a_5: f32; + + a_5 = a_4; + return; +} + +fn implicit_1(a_6: i32) { + var a_7: i32; + + a_7 = a_6; + return; +} + +fn implicit_dims(v: f32) { + var v_1: f32; + + v_1 = v; + return; +} + +fn implicit_dims_1(v_2: vec2) { + var v_3: vec2; + + v_3 = v_2; + return; +} + +fn implicit_dims_2(v_4: vec3) { + var v_5: vec3; + + v_5 = v_4; + return; +} + +fn implicit_dims_3(v_6: vec4) { + var v_7: vec4; + + v_7 = v_6; + return; +} + +fn main_1() { + exact_1(1); + implicit(f32(1u)); + _ = vec3(1); + implicit_dims_2(vec3(vec3(1))); + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/901-lhs-field-select-frag.wgsl b/tests/out/wgsl/901-lhs-field-select-frag.wgsl new file mode 100644 index 0000000000..196f21d79a --- /dev/null +++ b/tests/out/wgsl/901-lhs-field-select-frag.wgsl @@ -0,0 +1,13 @@ +fn main_1() { + var a: vec4; + + a = vec4(1.0); + a.x = 2.0; + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/931-constant-emitting-frag.wgsl b/tests/out/wgsl/931-constant-emitting-frag.wgsl new file mode 100644 index 0000000000..ba5d223ef7 --- /dev/null +++ b/tests/out/wgsl/931-constant-emitting-frag.wgsl @@ -0,0 +1,15 @@ +const constant: i32 = 10; + +fn function() -> f32 { + return 0.0; +} + +fn main_1() { + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/932-for-loop-if-frag.wgsl b/tests/out/wgsl/932-for-loop-if-frag.wgsl new file mode 100644 index 0000000000..f9a29ae87e --- /dev/null +++ b/tests/out/wgsl/932-for-loop-if-frag.wgsl @@ -0,0 +1,24 @@ +fn main_1() { + var i: i32; + + i = 0; + loop { + let _e2 = i; + if !((_e2 < 1)) { + break; + } + { + } + continuing { + let _e6 = i; + i = (_e6 + 1); + } + } + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/constant-array-size-frag.wgsl b/tests/out/wgsl/constant-array-size-frag.wgsl new file mode 100644 index 0000000000..98d413bdf2 --- /dev/null +++ b/tests/out/wgsl/constant-array-size-frag.wgsl @@ -0,0 +1,44 @@ +struct Data { + vecs: array,42u>, +} + +const NUM_VECS: i32 = 42; + +@group(1) @binding(0) +var global: Data; + +fn function() -> vec4 { + var sum: vec4; + var i: i32; + + sum = vec4(f32(0)); + i = 0; + loop { + let _e9 = i; + if !((_e9 < NUM_VECS)) { + break; + } + { + let _e15 = sum; + let _e16 = i; + let _e18 = global.vecs[_e16]; + sum = (_e15 + _e18); + } + continuing { + let _e12 = i; + i = (_e12 + 1); + } + } + let _e20 = sum; + return _e20; +} + +fn main_1() { + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/declarations-frag.wgsl b/tests/out/wgsl/declarations-frag.wgsl new file mode 100644 index 0000000000..107bcaa4f4 --- /dev/null +++ b/tests/out/wgsl/declarations-frag.wgsl @@ -0,0 +1,69 @@ +struct VertexData { + position: vec2, + a: vec2, +} + +struct FragmentData { + position: vec2, + a: vec2, +} + +struct TestStruct { + a: f32, + b: f32, +} + +struct FragmentOutput { + @location(0) position: vec2, + @location(1) a: vec2, + @location(2) out_array: vec4, + @location(3) out_array_1: vec4, +} + +var vert: VertexData; +var frag: FragmentData; +var in_array_2: array,2u>; +var out_array: array,2u>; +var array_2d: array,2u>; +var array_toomanyd: array,2u>,2u>,2u>,2u>,2u>,2u>; + +fn main_1() { + var positions: array,2u>; + var strct: TestStruct; + var from_input_array: vec4; + var a_1: f32; + var b: f32; + + _ = (&vert.position); + _ = (&vert.a); + _ = (&frag.position); + _ = (&frag.a); + positions = array,2u>(vec3(-(1.0), 1.0, 0.0), vec3(-(1.0), -(1.0), 0.0)); + strct = TestStruct(f32(1), f32(2)); + let _e35 = in_array_2[1]; + from_input_array = _e35; + let _e41 = array_2d[0][0]; + a_1 = _e41; + let _e57 = array_toomanyd[0][0][0][0][0][0][0]; + b = _e57; + out_array[0] = vec4(2.0); + return; +} + +@fragment +fn main(@location(0) position: vec2, @location(1) a: vec2, @location(2) in_array: vec4, @location(3) in_array_1: vec4) -> FragmentOutput { + vert.position = position; + vert.a = a; + in_array_2[0] = in_array; + in_array_2[1] = in_array_1; + _ = (&vert.position); + _ = (&vert.a); + _ = (&frag.position); + _ = (&frag.a); + main_1(); + let _e30 = frag.position; + let _e32 = frag.a; + let _e35 = out_array[0]; + let _e37 = out_array[1]; + return FragmentOutput(_e30, _e32, _e35, _e37); +} diff --git a/tests/out/wgsl/declarations-vert.wgsl b/tests/out/wgsl/declarations-vert.wgsl index 4b61704b96..4727541a9d 100644 --- a/tests/out/wgsl/declarations-vert.wgsl +++ b/tests/out/wgsl/declarations-vert.wgsl @@ -18,6 +18,7 @@ struct VertexOutput { @location(1) a: vec2, @location(2) out_array: vec4, @location(3) out_array_1: vec4, + @builtin(position) member: vec4, } var vert: VertexData; @@ -26,6 +27,7 @@ var in_array_2: array,2u>; var out_array: array,2u>; var array_2d: array,2u>; var array_toomanyd: array,2u>,2u>,2u>,2u>,2u>,2u>; +var gl_Position: vec4; fn main_1() { var positions: array,2u>; @@ -47,6 +49,7 @@ fn main_1() { let _e57 = array_toomanyd[0][0][0][0][0][0][0]; b = _e57; out_array[0] = vec4(2.0); + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); return; } @@ -65,5 +68,6 @@ fn main(@location(0) position: vec2, @location(1) a: vec2, @location(2 let _e32 = frag.a; let _e35 = out_array[0]; let _e37 = out_array[1]; - return VertexOutput(_e30, _e32, _e35, _e37); + let _e39 = gl_Position; + return VertexOutput(_e30, _e32, _e35, _e37, _e39); } diff --git a/tests/out/wgsl/global-constant-array-frag.wgsl b/tests/out/wgsl/global-constant-array-frag.wgsl new file mode 100644 index 0000000000..bda27f3f58 --- /dev/null +++ b/tests/out/wgsl/global-constant-array-frag.wgsl @@ -0,0 +1,15 @@ +const array_: array = array(1.0, 2.0); +var i: u32; + +fn main_1() { + var local: array = array(1.0, 2.0); + + let _e2 = i; +} + +@fragment +fn main() { + _ = array(1.0, 2.0); + main_1(); + return; +} diff --git a/tests/out/wgsl/inv-hyperbolic-trig-functions.wgsl b/tests/out/wgsl/inv-hyperbolic-trig-functions.wgsl index 2ac357020a..10f5d25946 100644 --- a/tests/out/wgsl/inv-hyperbolic-trig-functions.wgsl +++ b/tests/out/wgsl/inv-hyperbolic-trig-functions.wgsl @@ -14,7 +14,7 @@ fn main_1() { return; } -@vertex +@fragment fn main() { main_1(); } diff --git a/tests/out/wgsl/long-form-matrix-frag.wgsl b/tests/out/wgsl/long-form-matrix-frag.wgsl new file mode 100644 index 0000000000..4a173b63ce --- /dev/null +++ b/tests/out/wgsl/long-form-matrix-frag.wgsl @@ -0,0 +1,41 @@ +fn main_1() { + var splat: mat2x2; + var normal: mat2x2; + var from_matrix: mat2x4; + var a: mat2x2; + var b: mat2x2; + var c: mat3x3; + var d: mat3x3; + var e: mat4x4; + + let _e1 = f32(1); + splat = mat2x2(vec2(_e1, 0.0), vec2(0.0, _e1)); + let _e9 = vec2(f32(1)); + let _e12 = vec2(f32(2)); + normal = mat2x2(vec2(_e9.x, _e9.y), vec2(_e12.x, _e12.y)); + let _e26 = mat3x3(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0)); + from_matrix = mat2x4(vec4(_e26[0].x, _e26[0].y, _e26[0].z, 0.0), vec4(_e26[1].x, _e26[1].y, _e26[1].z, 0.0)); + a = mat2x2(vec2(f32(1), f32(2)), vec2(f32(3), f32(4))); + let _e58 = vec2(f32(2), f32(3)); + b = mat2x2(vec2(f32(1), _e58.x), vec2(_e58.y, f32(4))); + let _e73 = vec3(f32(1)); + let _e76 = vec3(f32(1)); + c = mat3x3(vec3(f32(1), f32(2), f32(3)), vec3(_e73.x, _e73.y, _e73.z), vec3(_e76.x, _e76.y, _e76.z)); + let _e93 = vec2(f32(2)); + let _e97 = vec3(f32(1)); + let _e100 = vec3(f32(1)); + d = mat3x3(vec3(_e93.x, _e93.y, f32(1)), vec3(_e97.x, _e97.y, _e97.z), vec3(_e100.x, _e100.y, _e100.z)); + let _e117 = vec2(f32(2)); + let _e120 = vec4(f32(1)); + let _e123 = vec2(f32(2)); + let _e126 = vec4(f32(1)); + let _e129 = vec4(f32(1)); + e = mat4x4(vec4(_e117.x, _e117.y, _e120.x, _e120.y), vec4(_e120.z, _e120.w, _e123.x, _e123.y), vec4(_e126.x, _e126.y, _e126.z, _e126.w), vec4(_e129.x, _e129.y, _e129.z, _e129.w)); + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/math-functions-frag.wgsl b/tests/out/wgsl/math-functions-frag.wgsl new file mode 100644 index 0000000000..b9049ef23d --- /dev/null +++ b/tests/out/wgsl/math-functions-frag.wgsl @@ -0,0 +1,226 @@ +fn main_1() { + var a: vec4; + var b: vec4; + var m: mat4x4; + var i: i32; + var ceilOut: vec4; + var roundOut: vec4; + var floorOut: vec4; + var fractOut: vec4; + var truncOut: vec4; + var sinOut: vec4; + var absOut: vec4; + var sqrtOut: vec4; + var inversesqrtOut: vec4; + var expOut: vec4; + var exp2Out: vec4; + var signOut: vec4; + var transposeOut: mat4x4; + var normalizeOut: vec4; + var sinhOut: vec4; + var cosOut: vec4; + var coshOut: vec4; + var tanOut: vec4; + var tanhOut: vec4; + var acosOut: vec4; + var asinOut: vec4; + var logOut: vec4; + var log2Out: vec4; + var lengthOut: f32; + var determinantOut: f32; + var bitCountOut: i32; + var bitfieldReverseOut: i32; + var atanOut: f32; + var atan2Out: f32; + var modOut: f32; + var powOut: vec4; + var dotOut: f32; + var maxOut: vec4; + var minOut: vec4; + var reflectOut: vec4; + var crossOut: vec3; + var outerProductOut: mat4x4; + var distanceOut: f32; + var stepOut: vec4; + var rad: vec4; + var deg: f32; + var smoothStepScalar: f32; + var smoothStepVector: vec4; + var smoothStepMixed: vec4; + + a = vec4(1.0); + b = vec4(2.0); + let _e6 = a; + let _e7 = b; + let _e8 = a; + let _e9 = b; + m = mat4x4(vec4(_e6.x, _e6.y, _e6.z, _e6.w), vec4(_e7.x, _e7.y, _e7.z, _e7.w), vec4(_e8.x, _e8.y, _e8.z, _e8.w), vec4(_e9.x, _e9.y, _e9.z, _e9.w)); + i = 5; + _ = a; + let _e35 = a; + ceilOut = ceil(_e35); + _ = a; + let _e39 = a; + roundOut = round(_e39); + _ = a; + let _e43 = a; + floorOut = floor(_e43); + _ = a; + let _e47 = a; + fractOut = fract(_e47); + _ = a; + let _e51 = a; + truncOut = trunc(_e51); + _ = a; + let _e55 = a; + sinOut = sin(_e55); + _ = a; + let _e59 = a; + absOut = abs(_e59); + _ = a; + let _e63 = a; + sqrtOut = sqrt(_e63); + _ = a; + let _e67 = a; + inversesqrtOut = inverseSqrt(_e67); + _ = a; + let _e71 = a; + expOut = exp(_e71); + _ = a; + let _e75 = a; + exp2Out = exp2(_e75); + _ = a; + let _e79 = a; + signOut = sign(_e79); + _ = m; + let _e83 = m; + transposeOut = transpose(_e83); + _ = a; + let _e87 = a; + normalizeOut = normalize(_e87); + _ = a; + let _e91 = a; + sinhOut = sinh(_e91); + _ = a; + let _e95 = a; + cosOut = cos(_e95); + _ = a; + let _e99 = a; + coshOut = cosh(_e99); + _ = a; + let _e103 = a; + tanOut = tan(_e103); + _ = a; + let _e107 = a; + tanhOut = tanh(_e107); + _ = a; + let _e111 = a; + acosOut = acos(_e111); + _ = a; + let _e115 = a; + asinOut = asin(_e115); + _ = a; + let _e119 = a; + logOut = log(_e119); + _ = a; + let _e123 = a; + log2Out = log2(_e123); + _ = a; + let _e127 = a; + lengthOut = length(_e127); + _ = m; + let _e131 = m; + determinantOut = determinant(_e131); + _ = i; + let _e135 = i; + bitCountOut = countOneBits(_e135); + _ = i; + let _e139 = i; + bitfieldReverseOut = reverseBits(_e139); + let _e142 = a; + _ = _e142.x; + let _e144 = a; + atanOut = atan(_e144.x); + let _e148 = a; + _ = _e148.x; + let _e150 = a; + _ = _e150.y; + let _e152 = a; + let _e154 = a; + atan2Out = atan2(_e152.x, _e154.y); + let _e158 = a; + _ = _e158.x; + let _e160 = b; + _ = _e160.x; + let _e162 = a; + let _e164 = b; + modOut = (_e162.x - (floor((_e162.x / _e164.x)) * _e164.x)); + _ = a; + _ = b; + let _e173 = a; + let _e174 = b; + powOut = pow(_e173, _e174); + _ = a; + _ = b; + let _e179 = a; + let _e180 = b; + dotOut = dot(_e179, _e180); + _ = a; + _ = b; + let _e185 = a; + let _e186 = b; + maxOut = max(_e185, _e186); + _ = a; + _ = b; + let _e191 = a; + let _e192 = b; + minOut = min(_e191, _e192); + _ = a; + _ = b; + let _e197 = a; + let _e198 = b; + reflectOut = reflect(_e197, _e198); + let _e201 = a; + _ = _e201.xyz; + let _e203 = b; + _ = _e203.xyz; + let _e205 = a; + let _e207 = b; + crossOut = cross(_e205.xyz, _e207.xyz); + _ = a; + _ = b; + let _e213 = a; + let _e214 = b; + outerProductOut = outerProduct(_e213, _e214); + _ = a; + _ = b; + let _e219 = a; + let _e220 = b; + distanceOut = distance(_e219, _e220); + _ = a; + _ = b; + let _e225 = a; + let _e226 = b; + stepOut = step(_e225, _e226); + _ = a; + let _e230 = a; + rad = radians(_e230); + let _e233 = a; + _ = _e233.x; + let _e235 = a; + deg = degrees(_e235.x); + smoothStepScalar = smoothstep(0.0, 1.0, 0.5); + _ = vec4(0.0); + _ = vec4(1.0); + _ = vec4(0.5); + smoothStepVector = smoothstep(vec4(0.0), vec4(1.0), vec4(0.5)); + _ = vec4(0.5); + smoothStepMixed = smoothstep(vec4(0.0), vec4(1.0), vec4(0.5)); + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/out/wgsl/math-functions.wgsl b/tests/out/wgsl/math-functions.wgsl index 71ae0fd749..e03648e1c3 100644 --- a/tests/out/wgsl/math-functions.wgsl +++ b/tests/out/wgsl/math-functions.wgsl @@ -1,4 +1,4 @@ -@vertex +@fragment fn main() { let v = vec4(0.0); let a = degrees(1.0); diff --git a/tests/out/wgsl/multiview.wgsl b/tests/out/wgsl/multiview.wgsl index 3ea9676b8c..51192d2f7a 100644 --- a/tests/out/wgsl/multiview.wgsl +++ b/tests/out/wgsl/multiview.wgsl @@ -1,4 +1,4 @@ -@vertex +@fragment fn main(@builtin(view_index) view_index: i32) { return; } diff --git a/tests/out/wgsl/vector-functions-frag.wgsl b/tests/out/wgsl/vector-functions-frag.wgsl new file mode 100644 index 0000000000..f7dfdd15cb --- /dev/null +++ b/tests/out/wgsl/vector-functions-frag.wgsl @@ -0,0 +1,222 @@ +fn ftest(a: vec4, b: vec4) { + var a_1: vec4; + var b_1: vec4; + var c: vec4; + var d: vec4; + var e: vec4; + var f: vec4; + var g: vec4; + var h: vec4; + + a_1 = a; + b_1 = b; + _ = a_1; + _ = b_1; + let _e6 = a_1; + let _e7 = b_1; + c = (_e6 < _e7); + _ = a_1; + _ = b_1; + let _e12 = a_1; + let _e13 = b_1; + d = (_e12 <= _e13); + _ = a_1; + _ = b_1; + let _e18 = a_1; + let _e19 = b_1; + e = (_e18 > _e19); + _ = a_1; + _ = b_1; + let _e24 = a_1; + let _e25 = b_1; + f = (_e24 >= _e25); + _ = a_1; + _ = b_1; + let _e30 = a_1; + let _e31 = b_1; + g = (_e30 == _e31); + _ = a_1; + _ = b_1; + let _e36 = a_1; + let _e37 = b_1; + h = (_e36 != _e37); + return; +} + +fn dtest(a_2: vec4, b_2: vec4) { + var a_3: vec4; + var b_3: vec4; + var c_1: vec4; + var d_1: vec4; + var e_1: vec4; + var f_1: vec4; + var g_1: vec4; + var h_1: vec4; + + a_3 = a_2; + b_3 = b_2; + _ = a_3; + _ = b_3; + let _e6 = a_3; + let _e7 = b_3; + c_1 = (_e6 < _e7); + _ = a_3; + _ = b_3; + let _e12 = a_3; + let _e13 = b_3; + d_1 = (_e12 <= _e13); + _ = a_3; + _ = b_3; + let _e18 = a_3; + let _e19 = b_3; + e_1 = (_e18 > _e19); + _ = a_3; + _ = b_3; + let _e24 = a_3; + let _e25 = b_3; + f_1 = (_e24 >= _e25); + _ = a_3; + _ = b_3; + let _e30 = a_3; + let _e31 = b_3; + g_1 = (_e30 == _e31); + _ = a_3; + _ = b_3; + let _e36 = a_3; + let _e37 = b_3; + h_1 = (_e36 != _e37); + return; +} + +fn itest(a_4: vec4, b_4: vec4) { + var a_5: vec4; + var b_5: vec4; + var c_2: vec4; + var d_2: vec4; + var e_2: vec4; + var f_2: vec4; + var g_2: vec4; + var h_2: vec4; + + a_5 = a_4; + b_5 = b_4; + _ = a_5; + _ = b_5; + let _e6 = a_5; + let _e7 = b_5; + c_2 = (_e6 < _e7); + _ = a_5; + _ = b_5; + let _e12 = a_5; + let _e13 = b_5; + d_2 = (_e12 <= _e13); + _ = a_5; + _ = b_5; + let _e18 = a_5; + let _e19 = b_5; + e_2 = (_e18 > _e19); + _ = a_5; + _ = b_5; + let _e24 = a_5; + let _e25 = b_5; + f_2 = (_e24 >= _e25); + _ = a_5; + _ = b_5; + let _e30 = a_5; + let _e31 = b_5; + g_2 = (_e30 == _e31); + _ = a_5; + _ = b_5; + let _e36 = a_5; + let _e37 = b_5; + h_2 = (_e36 != _e37); + return; +} + +fn utest(a_6: vec4, b_6: vec4) { + var a_7: vec4; + var b_7: vec4; + var c_3: vec4; + var d_3: vec4; + var e_3: vec4; + var f_3: vec4; + var g_3: vec4; + var h_3: vec4; + + a_7 = a_6; + b_7 = b_6; + _ = a_7; + _ = b_7; + let _e6 = a_7; + let _e7 = b_7; + c_3 = (_e6 < _e7); + _ = a_7; + _ = b_7; + let _e12 = a_7; + let _e13 = b_7; + d_3 = (_e12 <= _e13); + _ = a_7; + _ = b_7; + let _e18 = a_7; + let _e19 = b_7; + e_3 = (_e18 > _e19); + _ = a_7; + _ = b_7; + let _e24 = a_7; + let _e25 = b_7; + f_3 = (_e24 >= _e25); + _ = a_7; + _ = b_7; + let _e30 = a_7; + let _e31 = b_7; + g_3 = (_e30 == _e31); + _ = a_7; + _ = b_7; + let _e36 = a_7; + let _e37 = b_7; + h_3 = (_e36 != _e37); + return; +} + +fn btest(a_8: vec4, b_8: vec4) { + var a_9: vec4; + var b_9: vec4; + var c_4: vec4; + var d_4: vec4; + var e_4: bool; + var f_4: bool; + var g_4: vec4; + + a_9 = a_8; + b_9 = b_8; + _ = a_9; + _ = b_9; + let _e6 = a_9; + let _e7 = b_9; + c_4 = (_e6 == _e7); + _ = a_9; + _ = b_9; + let _e12 = a_9; + let _e13 = b_9; + d_4 = (_e12 != _e13); + _ = a_9; + let _e17 = a_9; + e_4 = any(_e17); + _ = a_9; + let _e21 = a_9; + f_4 = all(_e21); + _ = a_9; + let _e25 = a_9; + g_4 = !(_e25); + return; +} + +fn main_1() { + return; +} + +@fragment +fn main() { + main_1(); + return; +} diff --git a/tests/snapshots.rs b/tests/snapshots.rs index a0b9ed53ab..d1299a4a1d 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -117,7 +117,7 @@ fn check_targets(module: &naga::Module, name: &str, targets: Targets) { let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), capabilities) .validate(module) - .expect("Naga module validation failed"); + .expect(&format!("Naga module validation failed on test '{name}'")); #[cfg(feature = "serialize")] { @@ -582,6 +582,7 @@ fn convert_spv(name: &str, adjust_coordinate_space: bool, targets: Targets) { let _ = env_logger::try_init(); let root = env!("CARGO_MANIFEST_DIR"); + let module = naga::front::spv::parse_u8_slice( &fs::read(format!("{root}/{BASE_DIR_IN}/spv/{name}.spv")).expect("Couldn't find spv file"), &naga::front::spv::Options { diff --git a/tests/wgsl-errors.rs b/tests/wgsl-errors.rs index d44dd97f37..7c1f573b79 100644 --- a/tests/wgsl-errors.rs +++ b/tests/wgsl-errors.rs @@ -961,8 +961,11 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { check_validation! { "@vertex -fn main() { - discard; +fn main() -> @builtin(position) vec4 { + if true { + discard; + } + return vec4(); }": Err(naga::valid::ValidationError::EntryPoint { stage: naga::ShaderStage::Vertex, @@ -1124,13 +1127,13 @@ fn pointer_type_equivalence() { fn missing_bindings() { check_validation! { " - @vertex - fn vertex(_input: vec4) -> @location(0) vec4 { + @fragment + fn fragment(_input: vec4) -> @location(0) vec4 { return _input; } ": Err(naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Vertex, + stage: naga::ShaderStage::Fragment, source: naga::valid::EntryPointError::Argument( 0, naga::valid::VaryingError::MissingBinding, @@ -1141,13 +1144,13 @@ fn missing_bindings() { check_validation! { " - @vertex - fn vertex(@location(0) _input: vec4, more_input: f32) -> @location(0) vec4 { + @fragment + fn fragment(@location(0) _input: vec4, more_input: f32) -> @location(0) vec4 { return _input + more_input; } ": Err(naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Vertex, + stage: naga::ShaderStage::Fragment, source: naga::valid::EntryPointError::Argument( 1, naga::valid::VaryingError::MissingBinding, @@ -1158,13 +1161,13 @@ fn missing_bindings() { check_validation! { " - @vertex - fn vertex(@location(0) _input: vec4) -> vec4 { + @fragment + fn fragment(@location(0) _input: vec4) -> vec4 { return _input; } ": Err(naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Vertex, + stage: naga::ShaderStage::Fragment, source: naga::valid::EntryPointError::Result( naga::valid::VaryingError::MissingBinding, ), @@ -1174,18 +1177,18 @@ fn missing_bindings() { check_validation! { " - struct VertexIn { + struct FragmentIn { @location(0) pos: vec4, uv: vec2 } - @vertex - fn vertex(_input: VertexIn) -> @location(0) vec4 { + @fragment + fn fragment(_input: FragmentIn) -> @location(0) vec4 { return _input.pos; } ": Err(naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Vertex, + stage: naga::ShaderStage::Fragment, source: naga::valid::EntryPointError::Argument( 0, naga::valid::VaryingError::MemberMissingBinding(1), @@ -1195,6 +1198,39 @@ fn missing_bindings() { } } +#[test] +fn missing_bindings2() { + check_validation! { + " + @vertex + fn vertex() {} + ": + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Vertex, + source: naga::valid::EntryPointError::MissingVertexOutputPosition, + .. + }) + } + + check_validation! { + " + struct VertexOut { + @location(0) a: vec4, + } + + @vertex + fn vertex() -> VertexOut { + return VertexOut(vec4()); + } + ": + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Vertex, + source: naga::valid::EntryPointError::MissingVertexOutputPosition, + .. + }) + } +} + #[test] fn invalid_access() { check_validation! {