#include "main/shaderobj.h"
#include "main/transformfeedback.h"
#include "main/uniforms.h"
-#include "glsl/glsl_parser_extras.h"
-#include "glsl/ir_uniform.h"
+#include "compiler/glsl/glsl_parser_extras.h"
+#include "compiler/glsl/ir_uniform.h"
#include "program/program.h"
#include "program/prog_parameter.h"
#include "util/ralloc.h"
* Callback for deleting a pipeline object. Called by _mesa_HashDeleteAll().
*/
static void
-delete_pipelineobj_cb(GLuint id, void *data, void *userData)
+delete_pipelineobj_cb(UNUSED GLuint id, void *data, void *userData)
{
struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data;
struct gl_context *ctx = (struct gl_context *) userData;
if ((stages & GL_COMPUTE_SHADER_BIT) != 0)
_mesa_use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, pipe);
+
+ pipe->Validated = false;
}
/**
_mesa_bind_pipeline(struct gl_context *ctx,
struct gl_pipeline_object *pipe)
{
+ int i;
/* First bind the Pipeline to pipeline binding point */
_mesa_reference_pipeline_object(ctx, &ctx->Pipeline.Current, pipe);
FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
- if (ctx->Driver.UseProgram)
- ctx->Driver.UseProgram(ctx, NULL);
+ for (i = 0; i < MESA_SHADER_STAGES; i++)
+ _mesa_shader_program_init_subroutine_defaults(ctx, ctx->_Shader->CurrentProgram[i]);
}
}
/* Are geometry shaders available in this context?
*/
const bool has_gs = _mesa_has_geometry_shaders(ctx);
- const bool has_tess = _mesa_has_tessellation(ctx);;
+ const bool has_tess = _mesa_has_tessellation(ctx);
if (!pipe) {
_mesa_error(ctx, GL_INVALID_OPERATION,
*params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
return;
case GL_INFO_LOG_LENGTH:
- *params = pipe->InfoLog ? strlen(pipe->InfoLog) + 1 : 0;
+ *params = (pipe->InfoLog && pipe->InfoLog[0] != '\0') ?
+ strlen(pipe->InfoLog) + 1 : 0;
return;
case GL_VALIDATE_STATUS:
*params = pipe->Validated;
extern GLboolean
_mesa_validate_program_pipeline(struct gl_context* ctx,
- struct gl_pipeline_object *pipe,
- GLboolean IsBound)
+ struct gl_pipeline_object *pipe)
{
unsigned i;
bool program_empty = true;
*/
for (i = 0; i < MESA_SHADER_STAGES; i++) {
if (!program_stages_all_active(pipe, pipe->CurrentProgram[i])) {
- goto err;
+ return GL_FALSE;
}
}
ralloc_strdup(pipe,
"Program is active for multiple shader stages with an "
"intervening stage provided by another program");
- goto err;
+ return GL_FALSE;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] ||
pipe->CurrentProgram[MESA_SHADER_TESS_EVAL])) {
pipe->InfoLog = ralloc_strdup(pipe, "Program lacks a vertex shader");
- goto err;
+ return GL_FALSE;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
"Program %d was relinked without "
"PROGRAM_SEPARABLE state",
pipe->CurrentProgram[i]->Name);
- goto err;
+ return GL_FALSE;
}
}
}
if (program_empty) {
- goto err;
+ return GL_FALSE;
}
/* Section 2.11.11 (Shader Execution), subheading "Validation," of the
* maximum number of texture image units allowed."
*/
if (!_mesa_sampler_uniforms_pipeline_are_valid(pipe))
- goto err;
+ return GL_FALSE;
/* Validate inputs against outputs, this cannot be done during linking
* since programs have been linked separately from each other.
*
- * From OpenGL 4.5 Core spec:
+ * Section 11.1.3.11 (Validation) of the OpenGL 4.5 Core Profile spec says:
+ *
* "Separable program objects may have validation failures that cannot be
* detected without the complete program pipeline. Mismatched interfaces,
* improper usage of program objects together, and the same
* program objects."
*
* OpenGL ES 3.1 specification has the same text.
+ *
+ * Section 11.1.3.11 (Validation) of the OpenGL ES spec also says:
+ *
+ * An INVALID_OPERATION error is generated by any command that transfers
+ * vertices to the GL or launches compute work if the current set of
+ * active program objects cannot be executed, for reasons including:
+ *
+ * * The current program pipeline object contains a shader interface
+ * that doesn't have an exact match (see section 7.4.1)
+ *
+ * Based on this, only perform the most-strict checking on ES or when the
+ * application has created a debug context.
*/
- if (!_mesa_validate_pipeline_io(pipe))
- goto err;
+ if ((_mesa_is_gles(ctx) || (ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) &&
+ !_mesa_validate_pipeline_io(pipe)) {
+ if (_mesa_is_gles(ctx))
+ return GL_FALSE;
- pipe->Validated = GL_TRUE;
- return GL_TRUE;
+ static GLuint msg_id = 0;
-err:
- if (IsBound)
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glValidateProgramPipeline failed to validate the pipeline");
+ _mesa_gl_debug(ctx, &msg_id,
+ MESA_DEBUG_SOURCE_API,
+ MESA_DEBUG_TYPE_PORTABILITY,
+ MESA_DEBUG_SEVERITY_MEDIUM,
+ "glValidateProgramPipeline: pipeline %u does not meet "
+ "strict OpenGL ES 3.1 requirements and may not be "
+ "portable across desktop hardware\n",
+ pipe->Name);
+ }
- return GL_FALSE;
+ pipe->Validated = GL_TRUE;
+ return GL_TRUE;
}
/**
return;
}
- /* ValidateProgramPipeline should not throw errors when pipeline validation
- * fails and should instead only update the validation status. We pass
- * false for IsBound to avoid an error being thrown.
- */
- _mesa_validate_program_pipeline(ctx, pipe, false);
+ _mesa_validate_program_pipeline(ctx, pipe);
}
void GLAPIENTRY
return;
}
- if (pipe->InfoLog)
- _mesa_copy_string(infoLog, bufSize, length, pipe->InfoLog);
- else
- *length = 0;
+ _mesa_copy_string(infoLog, bufSize, length, pipe->InfoLog);
}