Skip to content

Instantly share code, notes, and snippets.

@seanbaxter
Last active August 12, 2020 21:32
Show Gist options
  • Save seanbaxter/43f0bb087692e42f4f884fb371c8a786 to your computer and use it in GitHub Desktop.
Save seanbaxter/43f0bb087692e42f4f884fb371c8a786 to your computer and use it in GitHub Desktop.
Loading vert + tesc shader in one module segfaults nv driver in first call to glSpecializeShader.
; SPIR-V
; Version: 1.5
; Generator: Khronos; 17
; Bound: 57
; Schema: 0
OpCapability Shader
OpCapability Tessellation
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %_ %gl_VertexID %gl_InstanceID
OpEntryPoint TessellationControl %main_0 "main" %gl_TessLevelInner %gl_TessLevelOuter %gl_out %gl_InvocationID
OpExecutionMode %main_0 OutputVertices 16
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpSource GLSL 450
OpSourceExtension "GL_GOOGLE_cpp_style_line_directive"
OpSourceExtension "GL_GOOGLE_include_directive"
OpName %main "main"
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_VertexID "gl_VertexID"
OpName %gl_InstanceID "gl_InstanceID"
OpName %main_0 "main"
OpName %gl_TessLevelInner "gl_TessLevelInner"
OpName %gl_TessLevelOuter "gl_TessLevelOuter"
OpName %gl_out "gl_out"
OpName %gl_InvocationID "gl_InvocationID"
OpModuleProcessed "Linked by SPIR-V Tools Linker"
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_VertexID BuiltIn VertexId
OpDecorate %gl_InstanceID BuiltIn InstanceId
OpDecorate %gl_TessLevelInner Patch
OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
OpDecorate %gl_TessLevelOuter Patch
OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
OpDecorate %gl_InvocationID BuiltIn InvocationId
%void = OpTypeVoid
%13 = 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
%float_1 = OpConstant %float 1
%float_0 = OpConstant %float 0
%24 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_ptr_Input_int = OpTypePointer Input %int
%gl_VertexID = OpVariable %_ptr_Input_int Input
%gl_InstanceID = OpVariable %_ptr_Input_int Input
%uint_2 = OpConstant %uint 2
%_arr_float_uint_2 = OpTypeArray %float %uint_2
%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
%int_0_0 = OpConstant %int 0
%float_4 = OpConstant %float 4
%_ptr_Output_float = OpTypePointer Output %float
%int_1 = OpConstant %int 1
%uint_4 = OpConstant %uint 4
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%uint_1_0 = OpConstant %uint 1
%uint_16 = OpConstant %uint 16
%_arr_gl_PerVertex_uint_16 = OpTypeArray %gl_PerVertex %uint_16
%_ptr_Output__arr_gl_PerVertex_uint_16 = OpTypePointer Output %_arr_gl_PerVertex_uint_16
%gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_uint_16 Output
%gl_InvocationID = OpVariable %_ptr_Input_int Input
%float_1_0 = OpConstant %float 1
%float_0_0 = OpConstant %float 0
%45 = OpConstantComposite %v4float %float_1_0 %float_0_0 %float_0_0 %float_1_0
%main = OpFunction %void None %13
%46 = OpLabel
%47 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %47 %24
OpReturn
OpFunctionEnd
%main_0 = OpFunction %void None %13
%48 = OpLabel
%49 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0_0
OpStore %49 %float_4
%50 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
OpStore %50 %float_4
%51 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0_0
OpStore %51 %float_4
%52 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
OpStore %52 %float_4
%53 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
OpStore %53 %float_4
%54 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
OpStore %54 %float_4
%55 = OpLoad %int %gl_InvocationID
%56 = OpAccessChain %_ptr_Output_v4float %gl_out %55 %int_0_0
OpStore %56 %45
OpReturn
OpFunctionEnd
#include <gl3w/GL/gl3w.h>
#include <SFML/Graphics.hpp>
void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity,
GLsizei length, const GLchar* message, const void* user_param) {
printf("GOT DEBUG CALLBACK: %s\n", message);
exit(1);
}
std::vector<char> load_file(const char* name) {
FILE* f = fopen(name, "r");
if(!f) {
printf("CANNOT LOAD %s\n", name);
return { };
}
fseek(f, 0, SEEK_END);
size_t len = ftell(f);
fseek(f, 0, SEEK_SET);
printf("%s: %zu bytes\n", name, len);
std::vector<char> data(len);
fread(data.data(), 1, len, f);
fclose(f);
return data;
}
int main() {
// Start the window.
sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.majorVersion = 4;
settings.minorVersion = 6;
settings.attributeFlags = sf::ContextSettings::Attribute::Core;
sf::RenderWindow window(sf::VideoMode(800, 600), "Render test",
sf::Style::Default, settings);
gl3wInit();
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(&debug_callback, nullptr);
printf("%d\n", gl3wIsSupported(4, 6));
// Load the binary.
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
GLuint ts = glCreateShader(GL_TESS_CONTROL_SHADER);
GLuint shaders[] { vs, ts };
std::vector<char> spv_data = load_file("program.spv");
glShaderBinary(2, shaders, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB,
spv_data.data(), spv_data.size());
if(int error = glGetError()) {
printf("glGetError = %d\n", error);
char text[1024];
glGetShaderInfoLog(vs, 1024, nullptr, text);
puts(text);
}
glSpecializeShader(vs, "main", 0, nullptr, nullptr);
printf("vs specialized\n");
glSpecializeShader(ts, "main", 0, nullptr, nullptr);
printf("ts specialized\n");
return 0;
}
$ glslc --target-env=opengl --target-spv=spv1.5 -o vert.spv vert.vert
$ glslc --target-env=opengl --target-spv=spv1.5 -o tesc.spv tesc.tesc
$ spirv-link vert.spv tesc.spv -o program.spv
$ clang++-9 segfault.cxx -lGL -lgl3w -lsfml-system -lsfml-window -lsfml-graphics -o segfault
$ ./segfault
Loaded spv: 1908 bytes
spv loaded
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff1dc7a54 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.450.57
#version 450 core
layout(vertices=16) out;
void main() {
gl_TessLevelInner[0] = 4;
gl_TessLevelInner[1] = 4;
gl_TessLevelOuter[0] = 4;
gl_TessLevelOuter[1] = 4;
gl_TessLevelOuter[2] = 4;
gl_TessLevelOuter[3] = 4;
gl_out[gl_InvocationID].gl_Position = vec4(1, 0, 0, 1);
}
#version 450 core
void main() {
gl_Position = vec4(1, 0, 0, 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment