key->program_string_id = bcp->id;
}
-static void
-fail_on_compile_error(int status, const char *msg)
-{
- int source, line, column;
- char error[256];
-
- if (status)
- return;
-
- if (sscanf(msg, "%d:%d(%d): error: %255[^\n]", &source, &line, &column, error) == 4)
- fail_if(!status, "%d:%s\n", line, error);
- else
- fail_if(!status, "%s\n", msg);
-}
-
struct anv_compiler {
struct anv_device *device;
struct intel_screen *screen;
compiler->device = device;
- compiler->brw->optionCache.info = NULL;
- compiler->brw->bufmgr = NULL;
compiler->brw->gen = devinfo->gen;
compiler->brw->is_g4x = devinfo->is_g4x;
compiler->brw->is_baytrail = devinfo->is_baytrail;
ctx = &compiler->brw->ctx;
_mesa_init_shader_object_functions(&ctx->Driver);
- _mesa_init_constants(&ctx->Const, API_OPENGL_CORE);
-
- brw_initialize_context_constants(compiler->brw);
-
- intelInitExtensions(ctx);
-
- /* Set dd::NewShader */
- brwInitFragProgFuncs(&ctx->Driver);
-
+ /* brw_select_clip_planes() needs this for bogus reasons. */
ctx->_Shader = &compiler->pipeline;
- compiler->brw->precompile = false;
-
return compiler;
fail:
uint32_t gen_magic;
};
-static const char *
-src_as_glsl(const char *data)
-{
- const struct spirv_header *as_spirv = (const struct spirv_header *)data;
-
- /* Check alignment */
- if ((intptr_t)data & 0x3) {
- return data;
- }
-
- if (as_spirv->magic == SPIR_V_MAGIC_NUMBER) {
- /* LunarG back-door */
- if (as_spirv->version == 0)
- return data + 12;
- else
- return NULL;
- } else {
- return data;
- }
-}
-
static void
-anv_compile_shader_glsl(struct anv_compiler *compiler,
- struct gl_shader_program *program,
- struct anv_pipeline *pipeline, uint32_t stage)
-{
- struct brw_context *brw = compiler->brw;
- struct gl_shader *shader;
- int name = 0;
-
- shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
- fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name);
-
- shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->module->data));
- _mesa_glsl_compile_shader(&brw->ctx, shader, false, false);
- fail_on_compile_error(shader->CompileStatus, shader->InfoLog);
-
- program->Shaders[program->NumShaders] = shader;
- program->NumShaders++;
-}
-
-static void
-setup_nir_io(struct gl_program *prog,
+setup_nir_io(struct gl_shader *mesa_shader,
nir_shader *shader)
{
+ struct gl_program *prog = mesa_shader->Program;
foreach_list_typed(nir_variable, var, node, &shader->inputs) {
prog->InputsRead |= BITFIELD64_BIT(var->data.location);
+ if (shader->stage == MESA_SHADER_FRAGMENT) {
+ struct gl_fragment_program *fprog = (struct gl_fragment_program *)prog;
+
+ fprog->InterpQualifier[var->data.location] =
+ (glsl_interp_qualifier)var->data.interpolation;
+ if (var->data.centroid)
+ fprog->IsCentroid |= BITFIELD64_BIT(var->data.location);
+ if (var->data.sample)
+ fprog->IsSample |= BITFIELD64_BIT(var->data.location);
+ }
}
foreach_list_typed(nir_variable, var, node, &shader->outputs) {
prog->OutputsWritten |= BITFIELD64_BIT(var->data.location);
}
+
+ mesa_shader->num_uniform_components = shader->num_uniforms;
}
static void
struct anv_shader *shader = pipeline->shaders[stage];
struct gl_shader *mesa_shader;
int name = 0;
+ uint32_t *spirv;
mesa_shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
fail_if(mesa_shader == NULL,
"failed to create %s shader\n", stage_info[stage].name);
+#define CREATE_PROGRAM(stage) \
+ _mesa_init_##stage##_program(&brw->ctx, &ralloc(mesa_shader, struct brw_##stage##_program)->program, 0, 0)
+
+ bool is_scalar;
+ struct gl_program *prog;
switch (stage) {
case VK_SHADER_STAGE_VERTEX:
- mesa_shader->Program = &rzalloc(mesa_shader, struct brw_vertex_program)->program.Base;
+ prog = CREATE_PROGRAM(vertex);
+ is_scalar = compiler->screen->compiler->scalar_vs;
break;
case VK_SHADER_STAGE_GEOMETRY:
- mesa_shader->Program = &rzalloc(mesa_shader, struct brw_geometry_program)->program.Base;
+ prog = CREATE_PROGRAM(geometry);
+ is_scalar = false;
break;
case VK_SHADER_STAGE_FRAGMENT:
- mesa_shader->Program = &rzalloc(mesa_shader, struct brw_fragment_program)->program.Base;
+ prog = CREATE_PROGRAM(fragment);
+ is_scalar = true;
break;
case VK_SHADER_STAGE_COMPUTE:
- mesa_shader->Program = &rzalloc(mesa_shader, struct brw_compute_program)->program.Base;
+ prog = CREATE_PROGRAM(compute);
+ is_scalar = true;
break;
+ default:
+ unreachable("Unsupported shader stage");
}
+ _mesa_reference_program(&brw->ctx, &mesa_shader->Program, prog);
mesa_shader->Program->Parameters =
rzalloc(mesa_shader, struct gl_program_parameter_list);
mesa_shader->Type = stage_info[stage].token;
mesa_shader->Stage = stage_info[stage].stage;
- assert(shader->module->size % 4 == 0);
-
struct gl_shader_compiler_options *glsl_options =
&compiler->screen->compiler->glsl_compiler_options[stage_info[stage].stage];
+ spirv = (uint32_t *) shader->module->data;
+ assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
+ assert(shader->module->size % 4 == 0);
+
mesa_shader->Program->nir =
- spirv_to_nir((uint32_t *)shader->module->data, shader->module->size / 4,
+ spirv_to_nir(spirv, shader->module->size / 4,
stage_info[stage].stage, glsl_options->NirOptions);
nir_validate_shader(mesa_shader->Program->nir);
brw_process_nir(mesa_shader->Program->nir,
compiler->screen->devinfo,
- NULL, mesa_shader->Stage, false);
+ NULL, mesa_shader->Stage, is_scalar);
- setup_nir_io(mesa_shader->Program, mesa_shader->Program->nir);
+ setup_nir_io(mesa_shader, mesa_shader->Program->nir);
fail_if(mesa_shader->Program->nir == NULL,
"failed to translate SPIR-V to NIR\n");
- program->Shaders[program->NumShaders] = mesa_shader;
+ _mesa_reference_shader(&brw->ctx, &program->Shaders[program->NumShaders],
+ mesa_shader);
program->NumShaders++;
}
fail_if(program == NULL || program->Shaders == NULL,
"failed to create program\n");
- bool all_spirv = true;
for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
- if (pipeline->shaders[i] == NULL)
- continue;
-
- /* You need at least this much for "void main() { }" anyway */
- assert(pipeline->shaders[i]->module->size >= 12);
-
- if (src_as_glsl(pipeline->shaders[i]->module->data)) {
- all_spirv = false;
- break;
- }
-
- assert(pipeline->shaders[i]->module->size % 4 == 0);
+ if (pipeline->shaders[i])
+ anv_compile_shader_spirv(compiler, program, pipeline, i);
}
- if (all_spirv) {
- for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
- if (pipeline->shaders[i])
- anv_compile_shader_spirv(compiler, program, pipeline, i);
- }
-
- for (unsigned i = 0; i < program->NumShaders; i++) {
- struct gl_shader *shader = program->Shaders[i];
- program->_LinkedShaders[shader->Stage] = shader;
- }
- } else {
- for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
- if (pipeline->shaders[i])
- anv_compile_shader_glsl(compiler, program, pipeline, i);
- }
-
- _mesa_glsl_link_shader(&brw->ctx, program);
- fail_on_compile_error(program->LinkStatus,
- program->InfoLog);
+ for (unsigned i = 0; i < program->NumShaders; i++) {
+ struct gl_shader *shader = program->Shaders[i];
+ program->_LinkedShaders[shader->Stage] = shader;
}
bool success;
&pipeline->cs_prog_data.base);
}
- /* XXX: Deleting the shader is broken with our current SPIR-V hacks. We
- * need to fix this ASAP.
- */
- if (!all_spirv)
- brw->ctx.Driver.DeleteShaderProgram(&brw->ctx, program);
+ brw->ctx.Driver.DeleteShaderProgram(&brw->ctx, program);
struct anv_device *device = compiler->device;
while (device->scratch_block_pool.bo.size < pipeline->total_scratch)