* would need to trigger the specific errors.
*
*/
-bool
-gl_spirv_validation(const uint32_t *words, size_t word_count,
- struct nir_spirv_specialization *spec, unsigned num_spec,
- gl_shader_stage stage, const char *entry_point_name)
+enum spirv_verify_result
+spirv_verify_gl_specialization_constants(
+ const uint32_t *words, size_t word_count,
+ struct nir_spirv_specialization *spec, unsigned num_spec,
+ gl_shader_stage stage, const char *entry_point_name)
{
/* vtn_warn/vtn_log uses debug.func. Setting a null to prevent crash. Not
* need to print the warnings now, would be done later, on the real
/* See also _vtn_fail() */
if (vtn_setjmp(b->fail_jump)) {
ralloc_free(b);
- return false;
+ return SPIRV_VERIFY_PARSER_ERROR;
}
/* Skip the SPIR-V header, handled at vtn_create_builder */
if (b->entry_point == NULL) {
ralloc_free(b);
- return false;
+ return SPIRV_VERIFY_ENTRY_POINT_NOT_FOUND;
}
b->specializations = spec;
ralloc_free(b);
- return true;
+ for (unsigned i = 0; i < num_spec; i++) {
+ if (!spec[i].defined_on_module)
+ return SPIRV_VERIFY_UNKNOWN_SPEC_INDEX;
+ }
+
+ return SPIRV_VERIFY_OK;
}
bool skip_os_break_in_debug_build;
};
-bool gl_spirv_validation(const uint32_t *words, size_t word_count,
- struct nir_spirv_specialization *spec, unsigned num_spec,
- gl_shader_stage stage, const char *entry_point_name);
+enum spirv_verify_result {
+ SPIRV_VERIFY_OK = 0,
+ SPIRV_VERIFY_PARSER_ERROR = 1,
+ SPIRV_VERIFY_ENTRY_POINT_NOT_FOUND = 2,
+ SPIRV_VERIFY_UNKNOWN_SPEC_INDEX = 3,
+};
+
+enum spirv_verify_result spirv_verify_gl_specialization_constants(
+ const uint32_t *words, size_t word_count,
+ struct nir_spirv_specialization *spec, unsigned num_spec,
+ gl_shader_stage stage, const char *entry_point_name);
nir_shader *spirv_to_nir(const uint32_t *words, size_t word_count,
struct nir_spirv_specialization *specializations,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_shader *sh;
- bool has_entry_point;
struct nir_spirv_specialization *spec_entries = NULL;
if (!ctx->Extensions.ARB_gl_spirv) {
spec_entries[i].defined_on_module = false;
}
- has_entry_point =
- gl_spirv_validation((uint32_t *)&spirv_data->SpirVModule->Binary[0],
- spirv_data->SpirVModule->Length / 4,
- spec_entries, numSpecializationConstants,
- sh->Stage, pEntryPoint);
+ enum spirv_verify_result r = spirv_verify_gl_specialization_constants(
+ (uint32_t *)&spirv_data->SpirVModule->Binary[0],
+ spirv_data->SpirVModule->Length / 4,
+ spec_entries, numSpecializationConstants,
+ sh->Stage, pEntryPoint);
- /* See previous spec comment */
- if (!has_entry_point) {
+ switch (r) {
+ case SPIRV_VERIFY_OK:
+ break;
+ case SPIRV_VERIFY_PARSER_ERROR:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glSpecializeShaderARB(\"%s\" is not a valid entry point"
+ "glSpecializeShaderARB(failed to parse entry point \"%s\""
" for shader)", pEntryPoint);
goto end;
- }
-
- for (unsigned i = 0; i < numSpecializationConstants; ++i) {
- if (spec_entries[i].defined_on_module == false) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glSpecializeShaderARB(constant \"%i\" does not exist "
- "in shader)", spec_entries[i].id);
- goto end;
+ case SPIRV_VERIFY_ENTRY_POINT_NOT_FOUND:
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glSpecializeShaderARB(could not find entry point \"%s\""
+ " for shader)", pEntryPoint);
+ goto end;
+ case SPIRV_VERIFY_UNKNOWN_SPEC_INDEX:
+ for (unsigned i = 0; i < numSpecializationConstants; ++i) {
+ if (spec_entries[i].defined_on_module == false) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glSpecializeShaderARB(constant \"%i\" does not exist "
+ "in shader)", spec_entries[i].id);
+ break;
+ }
}
+ goto end;
}
spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint);