* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
/**
#include "main/transformfeedback.h"
#include "main/uniforms.h"
#include "program/program.h"
+#include "program/prog_print.h"
#include "program/prog_parameter.h"
#include "ralloc.h"
#include <stdbool.h>
#include "../glsl/glsl_parser_extras.h"
+#include "../glsl/ir.h"
#include "../glsl/ir_uniform.h"
+#include "../glsl/program.h"
/** Define this to enable shader substitution (see below) */
#define SHADER_SUBST 0
const char *env = _mesa_getenv("MESA_GLSL");
if (env) {
- if (strstr(env, "dump"))
+ if (strstr(env, "dump_on_error"))
+ flags |= GLSL_DUMP_ON_ERROR;
+ else if (strstr(env, "dump"))
flags |= GLSL_DUMP;
if (strstr(env, "log"))
flags |= GLSL_LOG;
case GL_VERTEX_SHADER:
return ctx->Extensions.ARB_vertex_shader;
case GL_GEOMETRY_SHADER_ARB:
- return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+ return _mesa_has_geometry_shaders(ctx);
default:
return false;
}
/* Are geometry shaders available in this context?
*/
- const bool has_gs =
- _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4;
+ const bool has_gs = _mesa_has_geometry_shaders(ctx);
/* Are uniform buffer objects available in this context?
*/
if (!sh)
return;
+ /* Geometry shaders are not yet fully supported, so issue a warning message
+ * if we're compiling one.
+ */
+ if (sh->Type == GL_GEOMETRY_SHADER)
+ printf("WARNING: Geometry shader support is currently experimental.\n");
+
options = &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(sh->Type)];
/* set default pragma state for shader */
sh->Pragmas = options->DefaultPragmas;
- /* this call will set the sh->CompileStatus field to indicate if
- * compilation was successful.
- */
- _mesa_glsl_compile_shader(ctx, sh);
+ if (!sh->Source) {
+ /* If the user called glCompileShader without first calling
+ * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
+ */
+ sh->CompileStatus = GL_FALSE;
+ } else {
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ printf("GLSL source for %s shader %d:\n",
+ _mesa_glsl_shader_target_name(sh->Type), sh->Name);
+ printf("%s\n", sh->Source);
+ }
- if (sh->CompileStatus == GL_FALSE &&
- (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) {
- _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
- sh->Name, sh->InfoLog);
+ /* this call will set the shader->CompileStatus field to indicate if
+ * compilation was successful.
+ */
+ _mesa_glsl_compile_shader(ctx, sh, false, false);
+
+ if (ctx->Shader.Flags & GLSL_LOG) {
+ _mesa_write_shader_to_file(sh);
+ }
+
+ if (ctx->Shader.Flags & GLSL_DUMP) {
+ if (sh->CompileStatus) {
+ printf("GLSL IR for shader %d:\n", sh->Name);
+ _mesa_print_ir(sh->ir, NULL);
+ printf("\n\n");
+ } else {
+ printf("GLSL shader %d failed to compile.\n", sh->Name);
+ }
+ if (sh->InfoLog && sh->InfoLog[0] != 0) {
+ printf("GLSL shader %d info log:\n", sh->Name);
+ printf("%s\n", sh->InfoLog);
+ }
+ }
+
+ }
+
+ if (!sh->CompileStatus) {
+ if (ctx->Shader.Flags & GLSL_DUMP_ON_ERROR) {
+ fprintf(stderr, "GLSL source for %s shader %d:\n",
+ _mesa_glsl_shader_target_name(sh->Type), sh->Name);
+ fprintf(stderr, "%s\n", sh->Source);
+ }
+
+ if (ctx->Shader.Flags & GLSL_REPORT_ERRORS) {
+ _mesa_debug(ctx, "Error compiling shader %u:\n%s\n",
+ sh->Name, sh->InfoLog);
+ }
}
}
printf("Mesa: glUseProgram(%u)\n", shProg->Name);
for (i = 0; i < shProg->NumShaders; i++) {
- const char *s;
- switch (shProg->Shaders[i]->Type) {
- case GL_VERTEX_SHADER:
- s = "vertex";
- break;
- case GL_FRAGMENT_SHADER:
- s = "fragment";
- break;
- case GL_GEOMETRY_SHADER:
- s = "geometry";
- break;
- default:
- s = "";
- }
- printf(" %s shader %u, checksum %u\n", s,
+ printf(" %s shader %u, checksum %u\n",
+ _mesa_glsl_shader_target_name(shProg->Shaders[i]->Type),
shProg->Shaders[i]->Name,
shProg->Shaders[i]->SourceChecksum);
}
if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_geometry_shader4)
break;
- if (value < 1 ||
+ if (value < 0 ||
(unsigned) value > ctx->Const.MaxGeometryOutputVertices) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
+ "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d)",
value);
return;
}
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry input type = %s",
+ "glProgramParameteri(geometry input type = %s)",
_mesa_lookup_enum_by_nr(value));
return;
}
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glProgramParameteri(geometry output type = %s",
+ "glProgramParameteri(geometry output type = %s)",
_mesa_lookup_enum_by_nr(value));
return;
}
return program;
}
+
+
+/**
+ * Copy program-specific data generated by linking from the gl_shader_program
+ * object to a specific gl_program object.
+ */
+void
+_mesa_copy_linked_program_data(gl_shader_type type,
+ const struct gl_shader_program *src,
+ struct gl_program *dst)
+{
+ switch (type) {
+ case MESA_SHADER_VERTEX: {
+ struct gl_vertex_program *dst_vp = (struct gl_vertex_program *) dst;
+ dst_vp->UsesClipDistance = src->Vert.UsesClipDistance;
+ }
+ break;
+ case MESA_SHADER_GEOMETRY: {
+ struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
+ dst_gp->VerticesIn = src->Geom.VerticesIn;
+ dst_gp->VerticesOut = src->Geom.VerticesOut;
+ dst_gp->InputType = src->Geom.InputType;
+ dst_gp->OutputType = src->Geom.OutputType;
+ }
+ break;
+ default:
+ break;
+ }
+}