validate vertex stage returns the position built-in

This commit is contained in:
teoxoy 2023-04-12 16:48:57 +02:00 committed by Jim Blandy
parent f59668ccfa
commit b9c5cb5a78
54 changed files with 535 additions and 239 deletions

View File

@ -63,6 +63,8 @@ pub enum VaryingError {
pub enum EntryPointError { pub enum EntryPointError {
#[error("Multiple conflicting entry points")] #[error("Multiple conflicting entry points")]
Conflict, Conflict,
#[error("Vertex shaders must return a `@builtin(position)` output value")]
MissingVertexOutputPosition,
#[error("Early depth test is not applicable")] #[error("Early depth test is not applicable")]
UnexpectedEarlyDepthTest, UnexpectedEarlyDepthTest,
#[error("Workgroup size is not applicable")] #[error("Workgroup size is not applicable")]
@ -353,7 +355,6 @@ impl VaryingContext<'_> {
.map_err(|e| e.with_span_context(span_context)), .map_err(|e| e.with_span_context(span_context)),
None => { None => {
match self.types[ty].inner { match self.types[ty].inner {
//TODO: check the member types
crate::TypeInner::Struct { ref members, .. } => { crate::TypeInner::Struct { ref members, .. } => {
for (index, member) in members.iter().enumerate() { for (index, member) in members.iter().enumerate() {
let span_context = self.types.get_span_context(ty); let span_context = self.types.get_span_context(ty);
@ -369,7 +370,6 @@ impl VaryingContext<'_> {
#[cfg(not(feature = "validate"))] #[cfg(not(feature = "validate"))]
let _ = index; let _ = index;
} }
// TODO: shouldn't this be validate?
Some(ref binding) => self Some(ref binding) => self
.validate_impl(member.ty, binding) .validate_impl(member.ty, binding)
.map_err(|e| e.with_span_context(span_context))?, .map_err(|e| e.with_span_context(span_context))?,
@ -603,6 +603,16 @@ impl super::Validator {
}; };
ctx.validate(fr.ty, fr.binding.as_ref()) ctx.validate(fr.ty, fr.binding.as_ref())
.map_err_inner(|e| EntryPointError::Result(e).with_span())?; .map_err_inner(|e| EntryPointError::Result(e).with_span())?;
#[cfg(feature = "validate")]
if ep.stage == crate::ShaderStage::Vertex
&& !result_built_ins.contains(&crate::BuiltIn::Position { invariant: false })
{
return Err(EntryPointError::MissingVertexOutputPosition.with_span());
}
} else if ep.stage == crate::ShaderStage::Vertex {
#[cfg(feature = "validate")]
return Err(EntryPointError::MissingVertexOutputPosition.with_span());
} }
for bg in self.bind_group_masks.iter_mut() { for bg in self.bind_group_masks.iter_mut() {

View File

@ -7,7 +7,7 @@ fn test_fma() -> vec2<f32> {
} }
@vertex @fragment
fn main() { fn main() {
let a = test_fma(); let a = test_fma();
} }

View File

@ -1,4 +1,4 @@
@vertex @fragment
fn main() { fn main() {
let f = 1.0; let f = 1.0;
let v = vec4<f32>(0.0); let v = vec4<f32>(0.0);

View File

@ -1,2 +1,2 @@
@vertex @fragment
fn main(@builtin(view_index) view_index: i32) {} fn main(@builtin(view_index) view_index: i32) {}

View File

@ -1,2 +1,2 @@
@vertex @fragment
fn main(@builtin(view_index) view_index: i32) {} fn main(@builtin(view_index) view_index: i32) {}

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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

291
tests/in/spv/shadow.spvasm Normal file
View File

@ -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

View File

@ -7,7 +7,6 @@ precision highp int;
void main() { void main() {
int view_index = gl_ViewIndex; int view_index = gl_ViewIndex;
gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w);
return; return;
} }

View File

@ -4,8 +4,6 @@
precision highp float; precision highp float;
precision highp int; precision highp int;
layout(num_views = 2) in;
void main() { void main() {
int view_index = int(gl_ViewID_OVR); int view_index = int(gl_ViewID_OVR);

View File

@ -1,3 +1,3 @@
vertex=(main:vs_5_1 ) vertex=()
fragment=() fragment=(main:ps_5_1 )
compute=() compute=()

View File

@ -1,3 +1,3 @@
vertex=(main:vs_5_1 ) vertex=()
fragment=() fragment=(main:ps_5_1 )
compute=() compute=()

View File

@ -6,7 +6,7 @@ using metal::uint;
constant metal::int2 const_type_1_ = {0, 0}; constant metal::int2 const_type_1_ = {0, 0};
vertex void main_( fragment void main_(
) { ) {
metal::float4 v = metal::float4(0.0); metal::float4 v = metal::float4(0.0);
float a = ((1.0) * 57.295779513082322865); float a = ((1.0) * 57.295779513082322865);

View File

@ -5,7 +5,8 @@
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %18 "main" OpEntryPoint Fragment %18 "main"
OpExecutionMode %18 OriginUpperLeft
%2 = OpTypeVoid %2 = OpTypeVoid
%4 = OpTypeFloat 32 %4 = OpTypeFloat 32
%3 = OpConstant %4 1.0 %3 = OpConstant %4 1.0

View File

@ -7,8 +7,10 @@ OpCapability MultiView
OpExtension "SPV_KHR_multiview" OpExtension "SPV_KHR_multiview"
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %8 "main" %5 OpEntryPoint Fragment %8 "main" %5
OpExecutionMode %8 OriginUpperLeft
OpDecorate %5 BuiltIn ViewIndex OpDecorate %5 BuiltIn ViewIndex
OpDecorate %5 Flat
%2 = OpTypeVoid %2 = OpTypeVoid
%3 = OpTypeInt 32 1 %3 = OpTypeInt 32 1
%6 = OpTypePointer Input %3 %6 = OpTypePointer Input %3

View File

@ -5,7 +5,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -6,7 +6,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -2,7 +2,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -8,7 +8,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -62,7 +62,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -6,7 +6,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -8,7 +8,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -17,7 +17,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -1,187 +0,0 @@
var<private> o_color: vec4<f32>;
fn testBinOpVecFloat(a: vec4<f32>, b: f32) {
var a1: vec4<f32>;
var b1: f32;
var v: vec4<f32>;
a1 = a;
b1 = b;
let e5: vec4<f32> = a1;
v = (e5 * 2.0);
let e8: vec4<f32> = a1;
v = (e8 / vec4<f32>(2.0));
let e12: vec4<f32> = a1;
v = (e12 + vec4<f32>(2.0));
let e16: vec4<f32> = a1;
v = (e16 - vec4<f32>(2.0));
return;
}
fn testBinOpFloatVec(a2: vec4<f32>, b2: f32) {
var a3: vec4<f32>;
var b3: f32;
var v1: vec4<f32>;
a3 = a2;
b3 = b2;
let e5: vec4<f32> = a3;
let e6: f32 = b3;
v1 = (e5 * e6);
let e8: vec4<f32> = a3;
let e9: f32 = b3;
v1 = (e8 / vec4<f32>(e9));
let e12: vec4<f32> = a3;
let e13: f32 = b3;
v1 = (e12 + vec4<f32>(e13));
let e16: vec4<f32> = a3;
let e17: f32 = b3;
v1 = (e16 - vec4<f32>(e17));
return;
}
fn testBinOpIVecInt(a4: vec4<i32>, b4: i32) {
var a5: vec4<i32>;
var b5: i32;
var v2: vec4<i32>;
a5 = a4;
b5 = b4;
let e5: vec4<i32> = a5;
let e6: i32 = b5;
v2 = (e5 * e6);
let e8: vec4<i32> = a5;
let e9: i32 = b5;
v2 = (e8 / vec4<i32>(e9));
let e12: vec4<i32> = a5;
let e13: i32 = b5;
v2 = (e12 + vec4<i32>(e13));
let e16: vec4<i32> = a5;
let e17: i32 = b5;
v2 = (e16 - vec4<i32>(e17));
let e20: vec4<i32> = a5;
let e21: i32 = b5;
v2 = (e20 & vec4<i32>(e21));
let e24: vec4<i32> = a5;
let e25: i32 = b5;
v2 = (e24 | vec4<i32>(e25));
let e28: vec4<i32> = a5;
let e29: i32 = b5;
v2 = (e28 ^ vec4<i32>(e29));
let e32: vec4<i32> = a5;
let e33: i32 = b5;
v2 = (e32 >> vec4<u32>(u32(e33)));
let e37: vec4<i32> = a5;
let e38: i32 = b5;
v2 = (e37 << vec4<u32>(u32(e38)));
return;
}
fn testBinOpIntIVec(a6: i32, b6: vec4<i32>) {
var a7: i32;
var b7: vec4<i32>;
var v3: vec4<i32>;
a7 = a6;
b7 = b6;
let e5: i32 = a7;
let e6: vec4<i32> = b7;
v3 = (e5 * e6);
let e8: i32 = a7;
let e9: vec4<i32> = b7;
v3 = (vec4<i32>(e8) + e9);
let e12: i32 = a7;
let e13: vec4<i32> = b7;
v3 = (vec4<i32>(e12) - e13);
let e16: i32 = a7;
let e17: vec4<i32> = b7;
v3 = (vec4<i32>(e16) & e17);
let e20: i32 = a7;
let e21: vec4<i32> = b7;
v3 = (vec4<i32>(e20) | e21);
let e24: i32 = a7;
let e25: vec4<i32> = b7;
v3 = (vec4<i32>(e24) ^ e25);
return;
}
fn testBinOpUVecUint(a8: vec4<u32>, b8: u32) {
var a9: vec4<u32>;
var b9: u32;
var v4: vec4<u32>;
a9 = a8;
b9 = b8;
let e5: vec4<u32> = a9;
let e6: u32 = b9;
v4 = (e5 * e6);
let e8: vec4<u32> = a9;
let e9: u32 = b9;
v4 = (e8 / vec4<u32>(e9));
let e12: vec4<u32> = a9;
let e13: u32 = b9;
v4 = (e12 + vec4<u32>(e13));
let e16: vec4<u32> = a9;
let e17: u32 = b9;
v4 = (e16 - vec4<u32>(e17));
let e20: vec4<u32> = a9;
let e21: u32 = b9;
v4 = (e20 & vec4<u32>(e21));
let e24: vec4<u32> = a9;
let e25: u32 = b9;
v4 = (e24 | vec4<u32>(e25));
let e28: vec4<u32> = a9;
let e29: u32 = b9;
v4 = (e28 ^ vec4<u32>(e29));
let e32: vec4<u32> = a9;
let e33: u32 = b9;
v4 = (e32 >> vec4<u32>(e33));
let e36: vec4<u32> = a9;
let e37: u32 = b9;
v4 = (e36 << vec4<u32>(e37));
return;
}
fn testBinOpUintUVec(a10: u32, b10: vec4<u32>) {
var a11: u32;
var b11: vec4<u32>;
var v5: vec4<u32>;
a11 = a10;
b11 = b10;
let e5: u32 = a11;
let e6: vec4<u32> = b11;
v5 = (e5 * e6);
let e8: u32 = a11;
let e9: vec4<u32> = b11;
v5 = (vec4<u32>(e8) + e9);
let e12: u32 = a11;
let e13: vec4<u32> = b11;
v5 = (vec4<u32>(e12) - e13);
let e16: u32 = a11;
let e17: vec4<u32> = b11;
v5 = (vec4<u32>(e16) & e17);
let e20: u32 = a11;
let e21: vec4<u32> = b11;
v5 = (vec4<u32>(e20) | e21);
let e24: u32 = a11;
let e25: vec4<u32> = b11;
v5 = (vec4<u32>(e24) ^ e25);
return;
}
fn main1() {
let e1: vec4<f32> = o_color;
let e4: vec4<f32> = vec4<f32>(1.0);
o_color.x = e4.x;
o_color.y = e4.y;
o_color.z = e4.z;
o_color.w = e4.w;
return;
}
@fragment
fn main() {
main1();
return;
}

View File

@ -37,7 +37,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -13,7 +13,7 @@ struct TestStruct {
b: f32, b: f32,
} }
struct VertexOutput { struct FragmentOutput {
@location(0) position: vec2<f32>, @location(0) position: vec2<f32>,
@location(1) a: vec2<f32>, @location(1) a: vec2<f32>,
@location(2) out_array: vec4<f32>, @location(2) out_array: vec4<f32>,
@ -50,8 +50,8 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main(@location(0) position: vec2<f32>, @location(1) a: vec2<f32>, @location(2) in_array: vec4<f32>, @location(3) in_array_1: vec4<f32>) -> VertexOutput { fn main(@location(0) position: vec2<f32>, @location(1) a: vec2<f32>, @location(2) in_array: vec4<f32>, @location(3) in_array_1: vec4<f32>) -> FragmentOutput {
vert.position = position; vert.position = position;
vert.a = a; vert.a = a;
in_array_2[0] = in_array; in_array_2[0] = in_array;
@ -65,5 +65,5 @@ fn main(@location(0) position: vec2<f32>, @location(1) a: vec2<f32>, @location(2
let _e32 = frag.a; let _e32 = frag.a;
let _e35 = out_array[0]; let _e35 = out_array[0];
let _e37 = out_array[1]; let _e37 = out_array[1];
return VertexOutput(_e30, _e32, _e35, _e37); return FragmentOutput(_e30, _e32, _e35, _e37);
} }

View File

@ -7,7 +7,7 @@ fn main_1() {
let _e2 = i; let _e2 = i;
} }
@vertex @fragment
fn main() { fn main() {
_ = array<f32,2u>(1.0, 2.0); _ = array<f32,2u>(1.0, 2.0);
main_1(); main_1();

View File

@ -14,7 +14,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
} }

View File

@ -34,7 +34,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -219,7 +219,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -1,4 +1,4 @@
@vertex @fragment
fn main() { fn main() {
let v = vec4<f32>(0.0); let v = vec4<f32>(0.0);
let a = degrees(1.0); let a = degrees(1.0);

View File

@ -1,4 +1,4 @@
@vertex @fragment
fn main(@builtin(view_index) view_index: i32) { fn main(@builtin(view_index) view_index: i32) {
return; return;
} }

View File

@ -215,7 +215,7 @@ fn main_1() {
return; return;
} }
@vertex @fragment
fn main() { fn main() {
main_1(); main_1();
return; return;

View File

@ -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) let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), capabilities)
.validate(module) .validate(module)
.expect("Naga module validation failed"); .expect(&format!("Naga module validation failed on test '{name}'"));
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
{ {
@ -595,6 +595,7 @@ fn convert_spv(name: &str, adjust_coordinate_space: bool, targets: Targets) {
let _ = env_logger::try_init(); let _ = env_logger::try_init();
let root = env!("CARGO_MANIFEST_DIR"); let root = env!("CARGO_MANIFEST_DIR");
let module = naga::front::spv::parse_u8_slice( let module = naga::front::spv::parse_u8_slice(
&fs::read(format!("{root}/{BASE_DIR_IN}/spv/{name}.spv")).expect("Couldn't find spv file"), &fs::read(format!("{root}/{BASE_DIR_IN}/spv/{name}.spv")).expect("Couldn't find spv file"),
&naga::front::spv::Options { &naga::front::spv::Options {

View File

@ -961,8 +961,11 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
check_validation! { check_validation! {
"@vertex "@vertex
fn main() { fn main() -> @builtin(position) vec4<f32> {
discard; if true {
discard;
}
return vec4<f32>();
}": }":
Err(naga::valid::ValidationError::EntryPoint { Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex, stage: naga::ShaderStage::Vertex,
@ -1124,13 +1127,13 @@ fn pointer_type_equivalence() {
fn missing_bindings() { fn missing_bindings() {
check_validation! { check_validation! {
" "
@vertex @fragment
fn vertex(_input: vec4<f32>) -> @location(0) vec4<f32> { fn fragment(_input: vec4<f32>) -> @location(0) vec4<f32> {
return _input; return _input;
} }
": ":
Err(naga::valid::ValidationError::EntryPoint { Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex, stage: naga::ShaderStage::Fragment,
source: naga::valid::EntryPointError::Argument( source: naga::valid::EntryPointError::Argument(
0, 0,
naga::valid::VaryingError::MissingBinding, naga::valid::VaryingError::MissingBinding,
@ -1141,13 +1144,13 @@ fn missing_bindings() {
check_validation! { check_validation! {
" "
@vertex @fragment
fn vertex(@location(0) _input: vec4<f32>, more_input: f32) -> @location(0) vec4<f32> { fn fragment(@location(0) _input: vec4<f32>, more_input: f32) -> @location(0) vec4<f32> {
return _input + more_input; return _input + more_input;
} }
": ":
Err(naga::valid::ValidationError::EntryPoint { Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex, stage: naga::ShaderStage::Fragment,
source: naga::valid::EntryPointError::Argument( source: naga::valid::EntryPointError::Argument(
1, 1,
naga::valid::VaryingError::MissingBinding, naga::valid::VaryingError::MissingBinding,
@ -1158,13 +1161,13 @@ fn missing_bindings() {
check_validation! { check_validation! {
" "
@vertex @fragment
fn vertex(@location(0) _input: vec4<f32>) -> vec4<f32> { fn fragment(@location(0) _input: vec4<f32>) -> vec4<f32> {
return _input; return _input;
} }
": ":
Err(naga::valid::ValidationError::EntryPoint { Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex, stage: naga::ShaderStage::Fragment,
source: naga::valid::EntryPointError::Result( source: naga::valid::EntryPointError::Result(
naga::valid::VaryingError::MissingBinding, naga::valid::VaryingError::MissingBinding,
), ),
@ -1174,18 +1177,18 @@ fn missing_bindings() {
check_validation! { check_validation! {
" "
struct VertexIn { struct FragmentIn {
@location(0) pos: vec4<f32>, @location(0) pos: vec4<f32>,
uv: vec2<f32> uv: vec2<f32>
} }
@vertex @fragment
fn vertex(_input: VertexIn) -> @location(0) vec4<f32> { fn fragment(_input: FragmentIn) -> @location(0) vec4<f32> {
return _input.pos; return _input.pos;
} }
": ":
Err(naga::valid::ValidationError::EntryPoint { Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex, stage: naga::ShaderStage::Fragment,
source: naga::valid::EntryPointError::Argument( source: naga::valid::EntryPointError::Argument(
0, 0,
naga::valid::VaryingError::MemberMissingBinding(1), 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<f32>,
}
@vertex
fn vertex() -> VertexOut {
return VertexOut(vec4<f32>());
}
":
Err(naga::valid::ValidationError::EntryPoint {
stage: naga::ShaderStage::Vertex,
source: naga::valid::EntryPointError::MissingVertexOutputPosition,
..
})
}
}
#[test] #[test]
fn invalid_access() { fn invalid_access() {
check_validation! { check_validation! {