|
34 | 34 | #include <fstream> |
35 | 35 | #include <string> |
36 | 36 | #include <map> |
| 37 | +#include <cstdlib> |
37 | 38 |
|
38 | 39 | #include <stdint.h> |
39 | 40 |
|
@@ -124,27 +125,53 @@ struct ShaderProgram : public WithOpenGLBindings |
124 | 125 |
|
125 | 126 | char error_buffer[2048]; |
126 | 127 |
|
| 128 | + std::string defines; |
| 129 | + bool is_mesa_checked; |
| 130 | + |
127 | 131 | ShaderProgram() : |
128 | 132 | program(0), |
| 133 | + is_mesa_checked(false), |
129 | 134 | vertex_shader(0), |
130 | 135 | fragment_shader(0) |
131 | 136 | { |
132 | 137 | } |
133 | 138 |
|
| 139 | + void checkMesaBug() |
| 140 | + { |
| 141 | + if (is_mesa_checked) |
| 142 | + return; |
| 143 | + is_mesa_checked = true; |
| 144 | + std::string ren((const char*)glGetString(GL_RENDERER)); |
| 145 | + std::string ver((const char*)glGetString(GL_VERSION)); |
| 146 | + if (ren.find("Mesa DRI Intel") == 0) |
| 147 | + { |
| 148 | + size_t mesa_pos = ver.rfind("Mesa "); |
| 149 | + if (mesa_pos != std::string::npos) |
| 150 | + { |
| 151 | + double mesa_ver = atof(ver.substr(mesa_pos + 5).c_str()); |
| 152 | + if (mesa_ver < 10.3) |
| 153 | + { |
| 154 | + defines += "#define MESA_BUGGY_BOOL_CMP\n"; |
| 155 | + LOG_WARNING << "Working around buggy boolean instructions in your Mesa driver. Mesa DRI 10.3+ is recommended."; |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + } |
| 160 | + |
134 | 161 | void setVertexShader(const std::string& src) |
135 | 162 | { |
136 | | - const char* src_ = src.c_str(); |
137 | | - int length_ = src.length(); |
| 163 | + checkMesaBug(); |
| 164 | + const GLchar *sources[] = {"#version 140\n", defines.c_str(), src.c_str()}; |
138 | 165 | vertex_shader = gl()->glCreateShader(GL_VERTEX_SHADER); |
139 | | - gl()->glShaderSource(vertex_shader, 1, &src_, &length_); |
| 166 | + gl()->glShaderSource(vertex_shader, 3, sources, NULL); |
140 | 167 | } |
141 | 168 |
|
142 | 169 | void setFragmentShader(const std::string& src) |
143 | 170 | { |
144 | | - const char* src_ = src.c_str(); |
145 | | - int length_ = src.length(); |
| 171 | + checkMesaBug(); |
| 172 | + const GLchar *sources[] = {"#version 140\n", defines.c_str(), src.c_str()}; |
146 | 173 | fragment_shader = gl()->glCreateShader(GL_FRAGMENT_SHADER); |
147 | | - gl()->glShaderSource(fragment_shader, 1, &src_, &length_); |
| 174 | + gl()->glShaderSource(fragment_shader, 3, sources, NULL); |
148 | 175 | } |
149 | 176 |
|
150 | 177 | void bindFragDataLocation(const std::string &name, int output) |
|
0 commit comments