[Mesa-dev] [PATCH 16/24] mesa: Implement glSpecializeShaderARB
Eduardo Lima
elima at igalia.com
Tue Nov 28 09:12:57 UTC 2017
On 11/27/2017 11:06 AM, Alejandro Piñeiro wrote:
> On 27/11/17 03:22, Timothy Arceri wrote:
>> I suspect this patch doesn't compile. I think pEntryPoint is meant to
>> be passed as an argument to this function.
pEntryPoint is passed as an argument. What makes you think it is not?
> It is the second parameter of the method. But it is true that it doesn't
> appear on this patch. Seems that the diff skipped some lines there.
It doesn't appear in the hunk below because git is showing just 3 lines
of context above and below each hunk. pEntryPoint arg simply falls outside.
> In any case, note that the method was added on patch "mesa: add
> GL_ARB_gl_spirv boilerplate", with pEntryPoint as second parameter, and
> no other patch is changing that.
>
>> 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);
>>> }
>>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list