[Mesa-dev] [PATCH 16/24] mesa: Implement glSpecializeShaderARB
Timothy Arceri
tarceri at itsqueeze.com
Mon Nov 27 02:22:30 UTC 2017
I suspect this patch doesn't compile. I think pEntryPoint is meant to be
passed as an argument to this function.
On 16/11/17 00:22, Eduardo Lima Mitev wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> v2: use gl_spirv_validation instead of spirv_to_nir.
> This method just validates the shader. The conversion to NIR will
> happen later, during linking. (Alejandro Piñeiro)
>
> v3: Use gl_shader_spirv_data struct to store the SPIR-V data.
> (Eduardo Lima)
> ---
> src/mesa/main/glspirv.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 107 insertions(+)
>
> diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
> index 390fa9e6984..fe954b05c7b 100644
> --- a/src/mesa/main/glspirv.c
> +++ b/src/mesa/main/glspirv.c
> @@ -24,6 +24,10 @@
> #include "glspirv.h"
>
> #include "errors.h"
> +#include "shaderobj.h"
> +
> +#include "compiler/nir/nir.h"
> +#include "compiler/spirv/nir_spirv.h"
>
> #include "util/u_atomic.h"
>
> @@ -120,4 +124,107 @@ _mesa_SpecializeShaderARB(GLuint shader,
> const GLuint *pConstantIndex,
> const GLuint *pConstantValue)
> {
> + 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) {
> + _mesa_error(ctx, GL_INVALID_OPERATION, "glSpecializeShaderARB");
> + return;
> + }
> +
> + sh = _mesa_lookup_shader_err(ctx, shader, "glSpecializeShaderARB");
> + if (!sh)
> + return;
> +
> + if (!sh->SpirVBinary) {
> + _mesa_error(ctx, GL_INVALID_OPERATION,
> + "glSpecializeShaderARB(not SPIR-V)");
> + return;
> + }
> +
> + if (sh->CompileStatus) {
> + _mesa_error(ctx, GL_INVALID_OPERATION,
> + "glSpecializeShaderARB(already specialized)");
> + return;
> + }
> +
> + struct gl_shader_spirv_data *spirv_data = sh->spirv_data;
> + assert(spirv_data);
> +
> + /* From the GL_ARB_gl_spirv spec:
> + *
> + * "The OpenGL API expects the SPIR-V module to have already been
> + * validated, and can return an error if it discovers anything invalid
> + * in the module. An invalid SPIR-V module is allowed to result in
> + * undefined behavior."
> + *
> + * However, the following errors still need to be detected (from the same
> + * spec):
> + *
> + * "INVALID_VALUE is generated if <pEntryPoint> does not name a valid
> + * entry point for <shader>.
> + *
> + * INVALID_VALUE is generated if any element of <pConstantIndex>
> + * refers to a specialization constant that does not exist in the
> + * shader module contained in <shader>."
> + *
> + * We cannot flag those errors a-priori because detecting them requires
> + * parsing the module. However, flagging them during specialization is okay,
> + * since it makes no difference in terms of application-visible state.
> + */
> + spec_entries = calloc(sizeof(*spec_entries), numSpecializationConstants);
> +
> + for (unsigned i = 0; i < numSpecializationConstants; ++i) {
> + spec_entries[i].id = pConstantIndex[i];
> + spec_entries[i].data32 = pConstantValue[i];
> + 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);
> +
> + /* See previous spec comment */
> + if (!has_entry_point) {
> + _mesa_error(ctx, GL_INVALID_VALUE,
> + "glSpecializeShaderARB(\"%s\" is not a valid entry point"
> + " 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;
> + }
> + }
> +
> + spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint);
> +
> + /* Note that we didn't make a real compilation of the module (spirv_to_nir),
> + * but just checked some error conditions. Real "compilation" will be done
> + * later, upon linking.
> + */
> + sh->CompileStatus = compile_success;
> +
> + spirv_data->NumSpecializationConstants = numSpecializationConstants;
> + spirv_data->SpecializationConstantsIndex =
> + rzalloc_array_size(spirv_data, sizeof(GLuint),
> + numSpecializationConstants);
> + spirv_data->SpecializationConstantsValue =
> + rzalloc_array_size(spirv_data, sizeof(GLuint),
> + numSpecializationConstants);
> + for (unsigned i = 0; i < numSpecializationConstants; ++i) {
> + spirv_data->SpecializationConstantsIndex[i] = pConstantIndex[i];
> + spirv_data->SpecializationConstantsValue[i] = pConstantValue[i];
> + }
> +
> + end:
> + free(spec_entries);
> }
>
More information about the mesa-dev
mailing list