void link_check_atomic_counter_resources(struct gl_context *ctx, struct gl_shader_program *prog) { unsigned num_buffers; active_atomic_buffer *const abs = find_active_atomic_counters(ctx, prog, &num_buffers); unsigned atomic_counters[MESA_SHADER_STAGES] = {}; unsigned atomic_buffers[MESA_SHADER_STAGES] = {}; unsigned total_atomic_counters = 0; unsigned total_atomic_buffers = 0; /* Sum the required resources. Note that this counts buffers and * counters referenced by several shader stages multiple times * against the combined limit -- That's the behavior the spec * requires. */ for (unsigned i = 0; i < ctx->Const.MaxAtomicBufferBindings; i++) { if (abs[i].size == 0) continue; for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) { const unsigned n = abs[i].stage_references[j]; if (n) { atomic_counters[j] += n; total_atomic_counters += n; atomic_buffers[j]++; total_atomic_buffers++; } } } /* Check that they are within the supported limits. */ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (atomic_counters[i] > ctx->Const.Program[i].MaxAtomicCounters) linker_error(prog, "Too many %s shader atomic counters", _mesa_shader_stage_to_string(i)); if (atomic_buffers[i] > ctx->Const.Program[i].MaxAtomicBuffers) linker_error(prog, "Too many %s shader atomic counter buffers", _mesa_shader_stage_to_string(i)); } if (total_atomic_counters > ctx->Const.MaxCombinedAtomicCounters) linker_error(prog, "Too many combined atomic counters"); if (total_atomic_buffers > ctx->Const.MaxCombinedAtomicBuffers) linker_error(prog, "Too many combined atomic buffers"); delete [] abs; }
bool st_load_ir_from_disk_cache(struct gl_context *ctx, struct gl_shader_program *prog, bool nir) { if (!ctx->Cache) return false; /* If we didn't load the GLSL metadata from cache then we could not have * loaded the tgsi either. */ if (prog->data->LinkStatus != LINKING_SKIPPED) return false; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (prog->_LinkedShaders[i] == NULL) continue; struct gl_program *glprog = prog->_LinkedShaders[i]->Program; st_deserialise_ir_program(ctx, prog, glprog, nir); /* We don't need the cached blob anymore so free it */ ralloc_free(glprog->driver_cache_blob); glprog->driver_cache_blob = NULL; glprog->driver_cache_blob_size = 0; if (ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "%s state tracker IR retrieved from cache\n", _mesa_shader_stage_to_string(i)); } } return true; }
backend_shader::backend_shader(const struct brw_compiler *compiler, void *log_data, void *mem_ctx, const nir_shader *shader, struct brw_stage_prog_data *stage_prog_data) : compiler(compiler), log_data(log_data), devinfo(compiler->devinfo), nir(shader), stage_prog_data(stage_prog_data), mem_ctx(mem_ctx), cfg(NULL), stage(shader->stage) { debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage); stage_name = _mesa_shader_stage_to_string(stage); stage_abbrev = _mesa_shader_stage_to_abbrev(stage); }
/** * Store tgsi and any other required state in on-disk shader cache. */ void st_store_ir_in_disk_cache(struct st_context *st, struct gl_program *prog, bool nir) { if (!st->ctx->Cache) return; /* Exit early when we are dealing with a ff shader with no source file to * generate a source from. */ static const char zero[sizeof(prog->sh.data->sha1)] = {0}; if (memcmp(prog->sh.data->sha1, zero, sizeof(prog->sh.data->sha1)) == 0) return; st_serialise_ir_program(st->ctx, prog, nir); if (st->ctx->_Shader->Flags & GLSL_CACHE_INFO) { fprintf(stderr, "putting %s state tracker IR in cache\n", _mesa_shader_stage_to_string(prog->info.stage)); } }
static void log_program_parameters(const struct gl_shader_program *shProg) { for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { if (shProg->_LinkedShaders[i] == NULL) continue; const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; printf("Program %d %s shader parameters:\n", shProg->Name, _mesa_shader_stage_to_string(i)); for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { printf("%s: %p %f %f %f %f\n", prog->Parameters->Parameters[j].Name, prog->Parameters->ParameterValues[j], prog->Parameters->ParameterValues[j][0].f, prog->Parameters->ParameterValues[j][1].f, prog->Parameters->ParameterValues[j][2].f, prog->Parameters->ParameterValues[j][3].f); } } fflush(stdout); }
nir_shader * brw_create_nir(struct brw_context *brw, const struct gl_shader_program *shader_prog, const struct gl_program *prog, gl_shader_stage stage, bool is_scalar) { struct gl_context *ctx = &brw->ctx; const nir_shader_compiler_options *options = ctx->Const.ShaderCompilerOptions[stage].NirOptions; struct gl_shader *shader = shader_prog ? shader_prog->_LinkedShaders[stage] : NULL; bool debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage); nir_shader *nir; /* First, lower the GLSL IR or Mesa IR to NIR */ if (shader_prog) { nir = glsl_to_nir(shader, options); } else { nir = prog_to_nir(prog, options); nir_convert_to_ssa(nir); /* turn registers into SSA */ } nir_validate_shader(nir); nir_lower_global_vars_to_local(nir); nir_validate_shader(nir); nir_lower_tex_projector(nir); nir_validate_shader(nir); nir_normalize_cubemap_coords(nir); nir_validate_shader(nir); nir_split_var_copies(nir); nir_validate_shader(nir); nir_optimize(nir, is_scalar); /* Lower a bunch of stuff */ nir_lower_var_copies(nir); nir_validate_shader(nir); /* Get rid of split copies */ nir_optimize(nir, is_scalar); if (is_scalar) { nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms, type_size_scalar); nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar); nir_assign_var_locations(&nir->outputs, &nir->num_outputs, type_size_scalar); nir_lower_io(nir, type_size_scalar); } else { nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms, type_size_vec4); nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_vec4); foreach_list_typed(nir_variable, var, node, &nir->outputs) var->data.driver_location = var->data.location; nir_lower_io(nir, type_size_vec4); } nir_validate_shader(nir); nir_remove_dead_variables(nir); nir_validate_shader(nir); if (shader_prog) { nir_lower_samplers(nir, shader_prog); nir_validate_shader(nir); } nir_lower_system_values(nir); nir_validate_shader(nir); nir_lower_atomics(nir); nir_validate_shader(nir); nir_optimize(nir, is_scalar); if (brw->gen >= 6) { /* Try and fuse multiply-adds */ nir_opt_peephole_ffma(nir); nir_validate_shader(nir); } nir_opt_algebraic_late(nir); nir_validate_shader(nir); nir_lower_locals_to_regs(nir); nir_validate_shader(nir); nir_lower_to_source_mods(nir); nir_validate_shader(nir); nir_copy_prop(nir); nir_validate_shader(nir); nir_opt_dce(nir); nir_validate_shader(nir); if (unlikely(debug_enabled)) { /* Re-index SSA defs so we print more sensible numbers. */ nir_foreach_overload(nir, overload) { if (overload->impl) nir_index_ssa_defs(overload->impl); } fprintf(stderr, "NIR (SSA form) for %s shader:\n", _mesa_shader_stage_to_string(stage)); nir_print_shader(nir, stderr); } nir_convert_from_ssa(nir, is_scalar); nir_validate_shader(nir); if (!is_scalar) { nir_lower_vec_to_movs(nir); nir_validate_shader(nir); } /* This is the last pass we run before we start emitting stuff. It * determines when we need to insert boolean resolves on Gen <= 5. We * run it last because it stashes data in instr->pass_flags and we don't * want that to be squashed by other NIR passes. */ if (brw->gen <= 5) brw_nir_analyze_boolean_resolves(nir); nir_sweep(nir); if (unlikely(debug_enabled)) { fprintf(stderr, "NIR (final form) for %s shader:\n", _mesa_shader_stage_to_string(stage)); nir_print_shader(nir, stderr); } return nir; }
/** * Creates a streamed BO containing the push constants for the VS or GS on * gen6+. * * Push constants are constant values (such as GLSL uniforms) that are * pre-loaded into a shader stage's register space at thread spawn time. * * Not all GLSL uniforms will be uploaded as push constants: The hardware has * a limitation of 32 or 64 EU registers (256 or 512 floats) per stage to be * uploaded as push constants, while GL 4.4 requires at least 1024 components * to be usable for the VS. Plus, currently we always use pull constants * instead of push constants when doing variable-index array access. * * See brw_curbe.c for the equivalent gen4/5 code. */ void gen6_upload_push_constants(struct brw_context *brw, const struct gl_program *prog, const struct brw_stage_prog_data *prog_data, struct brw_stage_state *stage_state, enum aub_state_struct_type type) { struct gl_context *ctx = &brw->ctx; /* Updates the ParamaterValues[i] pointers for all parameters of the * basic type of PROGRAM_STATE_VAR. */ /* XXX: Should this happen somewhere before to get our state flag set? */ _mesa_load_state_parameters(ctx, prog->Parameters); if (prog_data->nr_params == 0) { stage_state->push_const_size = 0; } else { gl_constant_value *param; int i; param = brw_state_batch(brw, type, prog_data->nr_params * sizeof(gl_constant_value), 32, &stage_state->push_const_offset); STATIC_ASSERT(sizeof(gl_constant_value) == sizeof(float)); /* _NEW_PROGRAM_CONSTANTS * * Also _NEW_TRANSFORM -- we may reference clip planes other than as a * side effect of dereferencing uniforms, so _NEW_PROGRAM_CONSTANTS * wouldn't be set for them. */ for (i = 0; i < prog_data->nr_params; i++) { param[i] = *prog_data->param[i]; } if (0) { fprintf(stderr, "%s constants:\n", _mesa_shader_stage_to_string(stage_state->stage)); for (i = 0; i < prog_data->nr_params; i++) { if ((i & 7) == 0) fprintf(stderr, "g%d: ", prog_data->dispatch_grf_start_reg + i / 8); fprintf(stderr, "%8f ", param[i].f); if ((i & 7) == 7) fprintf(stderr, "\n"); } if ((i & 7) != 0) fprintf(stderr, "\n"); fprintf(stderr, "\n"); } stage_state->push_const_size = ALIGN(prog_data->nr_params, 8) / 8; /* We can only push 32 registers of constants at a time. */ /* From the SNB PRM (vol2, part 1, section 3.2.1.4: 3DSTATE_CONSTANT_VS: * * "The sum of all four read length fields (each incremented to * represent the actual read length) must be less than or equal to * 32" * * From the IVB PRM (vol2, part 1, section 3.2.1.3: 3DSTATE_CONSTANT_VS: * * "The sum of all four read length fields must be less than or * equal to the size of 64" * * The other shader stages all match the VS's limits. */ assert(stage_state->push_const_size <= 32); } }