Skip to content

Commit 5eedad6

Browse files
authored
Merge pull request glium#1814 from avl/nicer_compile_errors
Report which shader stage failed to compile
2 parents 58409b1 + 9f56180 commit 5eedad6

File tree

5 files changed

+70
-16
lines changed

5 files changed

+70
-16
lines changed

src/program/mod.rs

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,57 @@ lazy_static! {
6262
static ref COMPILER_GLOBAL_LOCK: Mutex<()> = Mutex::new(());
6363
}
6464

65+
/// Used in ProgramCreationError::CompilationError to explain which shader stage failed compilation
66+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
67+
pub enum ShaderType {
68+
/// Vertex shader, maps to gl::VERTEX_SHADER
69+
Vertex,
70+
/// Geometry shader, maps to gl::GEOMETRY_SHADER
71+
Geometry,
72+
/// Fragment shader, maps to gl::FRAGMENT_SHADER
73+
Fragment,
74+
/// Tesselation control shader, maps to gl::TESS_CONTROL_SHADER
75+
TesselationControl,
76+
/// Tesselation evaluation shader, maps to gl::TESS_EVALUATION_SHADER
77+
TesselationEvaluation,
78+
/// Compute shader, maps to gl::COMPUTE_SHADER
79+
Compute,
80+
}
81+
82+
impl ShaderType {
83+
/// Creates an instance of gl::types::GLenum corresponding to the given ShaderType
84+
pub fn to_opengl_type(self) -> gl::types::GLenum {
85+
match self {
86+
ShaderType::Vertex => gl::VERTEX_SHADER,
87+
ShaderType::Geometry => gl::GEOMETRY_SHADER,
88+
ShaderType::Fragment => gl::FRAGMENT_SHADER,
89+
ShaderType::TesselationControl => gl::TESS_CONTROL_SHADER,
90+
ShaderType::TesselationEvaluation => gl::TESS_EVALUATION_SHADER,
91+
ShaderType::Compute => gl::COMPUTE_SHADER,
92+
}
93+
}
94+
/// Creates an instance of ShaderType corresponding to the given gl::types::GLenum.
95+
/// This routine will panic if the given shadertype is not supported by glium.
96+
pub fn from_opengl_type(gl_type: gl::types::GLenum) -> Self {
97+
match gl_type {
98+
gl::VERTEX_SHADER => ShaderType::Vertex,
99+
gl::GEOMETRY_SHADER => ShaderType::Geometry,
100+
gl::FRAGMENT_SHADER => ShaderType::Fragment,
101+
gl::TESS_CONTROL_SHADER => ShaderType::TesselationControl,
102+
gl::TESS_EVALUATION_SHADER => ShaderType::TesselationEvaluation,
103+
gl::COMPUTE_SHADER => ShaderType::Compute,
104+
_ => {
105+
panic!("Unsupported shader type")
106+
}
107+
}
108+
}
109+
}
110+
65111
/// Error that can be triggered when creating a `Program`.
66112
#[derive(Clone, Debug)]
67113
pub enum ProgramCreationError {
68114
/// Error while compiling one of the shaders.
69-
CompilationError(String),
115+
CompilationError(String, ShaderType),
70116

71117
/// Error while linking the program.
72118
LinkingError(String),
@@ -95,7 +141,7 @@ impl fmt::Display for ProgramCreationError {
95141
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
96142
use self::ProgramCreationError::*;
97143
match *self {
98-
CompilationError(ref s) =>
144+
CompilationError(ref s, _) =>
99145
write!(fmt, "{}: {}", self.description(), s),
100146
LinkingError(ref s) =>
101147
write!(fmt, "{}: {}", self.description(), s),
@@ -109,8 +155,16 @@ impl Error for ProgramCreationError {
109155
fn description(&self) -> &str {
110156
use self::ProgramCreationError::*;
111157
match *self {
112-
CompilationError(_) =>
113-
"Compilation error in one of the shaders",
158+
CompilationError(_,typ) => {
159+
match typ {
160+
ShaderType::Vertex => "Compilation error in vertex shader",
161+
ShaderType::Geometry => "Compilation error in geometry shader",
162+
ShaderType::Fragment => "Compilation error in fragment shader",
163+
ShaderType::TesselationControl => "Compilation error in tesselation control shader",
164+
ShaderType::TesselationEvaluation => "Compilation error in tesselation evaluation shader",
165+
ShaderType::Compute => "Compilation error in compute shader"
166+
}
167+
},
114168
LinkingError(_) =>
115169
"Error while linking shaders together",
116170
ShaderTypeNotSupported =>

src/program/program.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use ProgramExt;
1818
use Handle;
1919
use RawUniformValue;
2020

21-
use program::{COMPILER_GLOBAL_LOCK, ProgramCreationInput, ProgramCreationError, Binary};
21+
use program::{COMPILER_GLOBAL_LOCK, ProgramCreationInput, ProgramCreationError, ShaderType, Binary};
2222
use program::GetBinaryError;
2323

2424
use program::reflection::{Uniform, UniformBlock, OutputPrimitives};
@@ -55,22 +55,22 @@ impl Program {
5555
let mut has_tessellation_evaluation_shader = false;
5656

5757
let mut shaders = vec![
58-
(vertex_shader, gl::VERTEX_SHADER),
59-
(fragment_shader, gl::FRAGMENT_SHADER)
58+
(vertex_shader, ShaderType::Vertex),
59+
(fragment_shader, ShaderType::Fragment)
6060
];
6161

6262
if let Some(gs) = geometry_shader {
63-
shaders.push((gs, gl::GEOMETRY_SHADER));
63+
shaders.push((gs, ShaderType::Geometry));
6464
has_geometry_shader = true;
6565
}
6666

6767
if let Some(ts) = tessellation_control_shader {
68-
shaders.push((ts, gl::TESS_CONTROL_SHADER));
68+
shaders.push((ts, ShaderType::TesselationControl));
6969
has_tessellation_control_shader = true;
7070
}
7171

7272
if let Some(ts) = tessellation_evaluation_shader {
73-
shaders.push((ts, gl::TESS_EVALUATION_SHADER));
73+
shaders.push((ts, ShaderType::TesselationEvaluation));
7474
has_tessellation_evaluation_shader = true;
7575
}
7676

@@ -91,7 +91,7 @@ impl Program {
9191
let shaders_store = {
9292
let mut shaders_store = Vec::new();
9393
for (src, ty) in shaders.into_iter() {
94-
shaders_store.push(build_shader(facade, ty, src)?);
94+
shaders_store.push(build_shader(facade, ty.to_opengl_type(), src)?);
9595
}
9696
shaders_store
9797
};

src/program/shader.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::rc::Rc;
1313
use GlObject;
1414
use Handle;
1515

16-
use program::ProgramCreationError;
16+
use program::{ProgramCreationError, ShaderType};
1717

1818
/// A single, compiled but unlinked, shader.
1919
pub struct Shader {
@@ -172,10 +172,10 @@ pub fn build_shader<F: ?Sized>(facade: &F, shader_type: gl::types::GLenum, sourc
172172
error_log.set_len(error_log_size as usize);
173173

174174
match String::from_utf8(error_log) {
175-
Ok(msg) => Err(ProgramCreationError::CompilationError(msg)),
175+
Ok(msg) => Err(ProgramCreationError::CompilationError(msg, ShaderType::from_opengl_type(shader_type))),
176176
Err(_) => Err(
177177
ProgramCreationError::CompilationError("Could not convert the log \
178-
message to UTF-8".to_owned())
178+
message to UTF-8".to_owned(), ShaderType::from_opengl_type(shader_type))
179179
),
180180
}
181181
}

tests/framebuffer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn multioutput() {
209209
",
210210
None)
211211
{
212-
Err(glium::CompilationError(_)) => return,
212+
Err(glium::CompilationError(..)) => return,
213213
Ok(p) => p,
214214
e => e.unwrap()
215215
};

tests/shaders.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn program_compilation_error() {
7070
None);
7171

7272
match program {
73-
Err(glium::CompilationError(_)) => (),
73+
Err(glium::CompilationError(..)) => (),
7474
_ => panic!()
7575
};
7676

0 commit comments

Comments
 (0)