Using GL_ARB_shader_viewport_layer_array in tess evaluation shader results in Geometry capability of spir-v
I'm using the glslc to compile glsl shaders to spir-v and stumbled upon layered rendering without geometry shaders (which is crucial for targeting MoltenVK backend). There is an extension for that in Vulkan and corresponding extension in glsl.
I'm not really sure how the extension mechanic is implemented in glslc, but I've tried the following code:
#extension GL_ARB_shader_viewport_layer_array: require in tessellation shaders and it seems to do the job: I'm now able to write the gl_Layer in tess evaluation shaders. But using this extension results in tess evaluation shader having "Geometry" capability enabled, which in turn triggers Vulkan validation layers errors. Though the Vulkan extension states that
This extension allows variables decorated with the Layer and ViewportIndex built-ins to be exported from vertex or tessellation shaders, using the ShaderViewportIndexLayerEXT capability.
Hence I'd expect the generated spir-v binary to have ShaderViewportIndexLayerEXT capability. Is this intended behaviour of compiler? Can I somehow manipulate the capabilities of binaries through compiler options?
@dneto0 can you comment since this is in glslc?
I agree that the module should not add the Geometry capability. I have a tiny reproducer:
#version 450
#extension GL_ARB_shader_viewport_layer_array : require
layout(triangles) in;
void main() {
gl_Layer = 1;
}
Compiling: glslc t.tese -o t.spv
Produces:
; SPIR-V
; Version: 1.0
; Generator: Google Shaderc over Glslang; 10
; Bound: 10
; Schema: 0
OpCapability Geometry
OpCapability Tessellation
OpCapability ShaderViewportIndexLayerEXT
OpExtension "SPV_EXT_shader_viewport_index_layer"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint TessellationEvaluation %main "main" %gl_Layer
OpExecutionMode %main Triangles
OpExecutionMode %main SpacingEqual
OpExecutionMode %main VertexOrderCcw
OpSource GLSL 450
OpSourceExtension "GL_ARB_shader_viewport_layer_array"
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
OpName %gl_Layer "gl_Layer"
OpDecorate %gl_Layer BuiltIn Layer
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Output_int = OpTypePointer Output %int
%gl_Layer = OpVariable %_ptr_Output_int Output
%int_1 = OpConstant %int 1
%main = OpFunction %void None %3
%5 = OpLabel
OpStore %gl_Layer %int_1
OpReturn
OpFunctionEnd
I'll file this as an issue in Glslang, where the functionality resides.
I posted a patch to Glslang: https://github.com/KhronosGroup/glslang/pull/2462