Skip to content

Commit

Permalink
Clean up shader compilation error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
kovidgoyal committed Jun 13, 2023
1 parent b40a4f5 commit 86b4637
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 14 deletions.
10 changes: 8 additions & 2 deletions kitty/gl.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,15 @@ compile_shaders(GLenum shader_type, GLsizei count, const GLchar * const * source
GLsizei len;
static char glbuf[4096];
glGetShaderInfoLog(shader_id, sizeof(glbuf), &len, glbuf);
log_error("Failed to compile GLSL shader!\n%s", glbuf);
glDeleteShader(shader_id);
PyErr_SetString(PyExc_ValueError, "Failed to compile shader");
const char *shader_type_name = "unknown_type";
switch(shader_type) {
case GL_VERTEX_SHADER:
shader_type_name = "vertex"; break;
case GL_FRAGMENT_SHADER:
shader_type_name = "fragment"; break;
}
PyErr_Format(PyExc_ValueError, "Failed to compile GLSL %s shader:\n%s", shader_type_name, glbuf);
return 0;
}
return shader_id;
Expand Down
20 changes: 8 additions & 12 deletions kitty/shaders.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,43 +1080,39 @@ attach_shaders(PyObject *sources, GLuint program_id, GLenum shader_type) {
c_sources[i] = PyUnicode_AsUTF8(temp);
}
GLuint shader_id = compile_shaders(shader_type, PyTuple_GET_SIZE(sources), c_sources);
if (shader_id == 0) return false;
glAttachShader(program_id, shader_id);
glDeleteShader(shader_id);
return true;
}

static PyObject*
compile_program(PyObject UNUSED *self, PyObject *args) {
PyObject *vertex_shaders, *fragment_shaders;
int which, allow_recompile = 0;
GLuint vertex_shader_id = 0, fragment_shader_id = 0;
if (!PyArg_ParseTuple(args, "iO!O!|p", &which, &PyTuple_Type, &vertex_shaders, &PyTuple_Type, &fragment_shaders, &allow_recompile)) return NULL;
if (which < 0 || which >= NUM_PROGRAMS) { PyErr_Format(PyExc_ValueError, "Unknown program: %d", which); return NULL; }
Program *program = program_ptr(which);
if (program->id != 0) {
if (allow_recompile) { glDeleteProgram(program->id); program->id = 0; }
else { PyErr_SetString(PyExc_ValueError, "program already compiled"); return NULL; }
}
#define fail_compile() { glDeleteProgram(program->id); return NULL; }
program->id = glCreateProgram();
if (!attach_shaders(vertex_shaders, program->id, GL_VERTEX_SHADER)) return NULL;
if (!attach_shaders(fragment_shaders, program->id, GL_FRAGMENT_SHADER)) return NULL;
glAttachShader(program->id, fragment_shader_id);
if (!attach_shaders(vertex_shaders, program->id, GL_VERTEX_SHADER)) fail_compile();
if (!attach_shaders(fragment_shaders, program->id, GL_FRAGMENT_SHADER)) fail_compile();
glLinkProgram(program->id);
GLint ret = GL_FALSE;
glGetProgramiv(program->id, GL_LINK_STATUS, &ret);
if (ret != GL_TRUE) {
GLsizei len;
static char glbuf[4096];
glGetProgramInfoLog(program->id, sizeof(glbuf), &len, glbuf);
log_error("Failed to compile GLSL shader!\n%s", glbuf);
PyErr_SetString(PyExc_ValueError, "Failed to compile shader");
goto end;
PyErr_Format(PyExc_ValueError, "Failed to link GLSL shaders:\n%s", glbuf);
fail_compile();
}
#undef fail_compile
init_uniforms(which);

end:
if (vertex_shader_id != 0) glDeleteShader(vertex_shader_id);
if (fragment_shader_id != 0) glDeleteShader(fragment_shader_id);
if (PyErr_Occurred()) { glDeleteProgram(program->id); program->id = 0; return NULL;}
return Py_BuildValue("I", program->id);
}

Expand Down

0 comments on commit 86b4637

Please sign in to comment.