shaderc icon indicating copy to clipboard operation
shaderc copied to clipboard

Using GL_ARB_shader_viewport_layer_array in tess evaluation shader results in Geometry capability of spir-v

Open vladimir-nazarenko opened this issue 5 years ago • 3 comments

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?

vladimir-nazarenko avatar Jul 21 '20 13:07 vladimir-nazarenko

@dneto0 can you comment since this is in glslc?

zoddicus avatar Jul 21 '20 14:07 zoddicus

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.

dneto0 avatar Nov 12 '20 17:11 dneto0

I posted a patch to Glslang: https://github.com/KhronosGroup/glslang/pull/2462

dneto0 avatar Nov 12 '20 19:11 dneto0