diff --git a/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spv b/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spv new file mode 100644 index 0000000000..1498107419 Binary files /dev/null and b/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spv differ diff --git a/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spvasm b/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spvasm new file mode 100644 index 0000000000..2c31f90233 --- /dev/null +++ b/naga/tests/in/spv/builtin-accessed-outside-entrypoint.spvasm @@ -0,0 +1,90 @@ +;; Ensure builtin binding isn't removed by unused gl_PerVertex builtin culling when +;; the builtin is used in a function defined after (in the SPIRV) the entry point. +;; +;; Generated from the following glsl via `glslc` (without `-O` flag): +;; +;; ```glsl +;; #version 450 +;; +;; void builtin_usage() { +;; gl_Position = vec4( +;; (gl_VertexIndex == 0) ? -4.0 : 1.0, +;; (gl_VertexIndex == 2) ? 4.0 : -1.0, +;; 0.0, +;; 1.0 +;; ); +;; } +;; +;; void main() +;; { +;; builtin_usage(); +;; } +;; ``` +;; +; SPIR-V +; Version: 1.0 +; Generator: Google Shaderc over Glslang; 11 +; Bound: 37 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %main "main" %_ %gl_VertexIndex + OpSource GLSL 450 + OpSourceExtension "GL_GOOGLE_cpp_style_line_directive" + OpSourceExtension "GL_GOOGLE_include_directive" + OpName %main "main" + OpName %builtin_usage_ "builtin_usage(" + 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 %gl_VertexIndex "gl_VertexIndex" + 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 %gl_VertexIndex BuiltIn VertexIndex + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %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 +%_ptr_Input_int = OpTypePointer Input %int +%gl_VertexIndex = OpVariable %_ptr_Input_int Input + %bool = OpTypeBool + %float_n4 = OpConstant %float -4 + %float_1 = OpConstant %float 1 + %int_2 = OpConstant %int 2 + %float_4 = OpConstant %float 4 + %float_n1 = OpConstant %float -1 + %float_0 = OpConstant %float 0 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %main = OpFunction %void None %3 + %5 = OpLabel + %36 = OpFunctionCall %void %builtin_usage_ + OpReturn + OpFunctionEnd +%builtin_usage_ = OpFunction %void None %3 + %7 = OpLabel + %20 = OpLoad %int %gl_VertexIndex + %22 = OpIEqual %bool %20 %int_0 + %25 = OpSelect %float %22 %float_n4 %float_1 + %26 = OpLoad %int %gl_VertexIndex + %28 = OpIEqual %bool %26 %int_2 + %31 = OpSelect %float %28 %float_4 %float_n1 + %33 = OpCompositeConstruct %v4float %25 %31 %float_0 %float_1 + %35 = OpAccessChain %_ptr_Output_v4float %_ %int_0 + OpStore %35 %33 + OpReturn + OpFunctionEnd diff --git a/naga/tests/out/wgsl/builtin-accessed-outside-entrypoint.wgsl b/naga/tests/out/wgsl/builtin-accessed-outside-entrypoint.wgsl new file mode 100644 index 0000000000..8e1b885bf7 --- /dev/null +++ b/naga/tests/out/wgsl/builtin-accessed-outside-entrypoint.wgsl @@ -0,0 +1,31 @@ +struct gl_PerVertex { + @builtin(position) gl_Position: vec4, + gl_PointSize: f32, + gl_ClipDistance: array, + gl_CullDistance: array, +} + +var unnamed: gl_PerVertex = gl_PerVertex(vec4(0f, 0f, 0f, 1f), 1f, array(), array()); +var gl_VertexIndex_1: i32; + +fn builtin_usage() { + let _e9 = gl_VertexIndex_1; + let _e12 = gl_VertexIndex_1; + unnamed.gl_Position = vec4(select(1f, -4f, (_e9 == 0i)), select(-1f, 4f, (_e12 == 2i)), 0f, 1f); + return; +} + +fn main_1() { + builtin_usage(); + return; +} + +@vertex +fn main(@builtin(vertex_index) gl_VertexIndex: u32) -> @builtin(position) vec4 { + gl_VertexIndex_1 = i32(gl_VertexIndex); + main_1(); + let _e6 = unnamed.gl_Position.y; + unnamed.gl_Position.y = -(_e6); + let _e8 = unnamed.gl_Position; + return _e8; +} diff --git a/naga/tests/snapshots.rs b/naga/tests/snapshots.rs index 3df2af775a..8393d4a3ee 100644 --- a/naga/tests/snapshots.rs +++ b/naga/tests/snapshots.rs @@ -891,6 +891,7 @@ fn convert_spv_all() { true, Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL, ); + convert_spv("builtin-accessed-outside-entrypoint", true, Targets::WGSL); } #[cfg(feature = "glsl-in")]