{
if (v->ir)
ir3_destroy(v->ir);
- if (v->bo)
- fd_bo_del(v->bo);
+ assert(!v->bo);
if (v->binning)
delete_variant(v->binning);
+ free(v->bin);
free(v);
}
assemble_variant(struct ir3_shader_variant *v)
{
struct ir3_compiler *compiler = v->shader->compiler;
- struct shader_info *info = &v->shader->nir->info;
uint32_t gpu_id = compiler->gpu_id;
- uint32_t sz, *bin;
- bin = ir3_shader_assemble(v, gpu_id);
- sz = v->info.sizedwords * 4;
-
- v->bo = fd_bo_new(compiler->dev, sz,
- DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
- DRM_FREEDRENO_GEM_TYPE_KMEM,
- "%s:%s", ir3_shader_stage(v), info->name);
-
- memcpy(fd_bo_map(v->bo), bin, sz);
+ v->bin = ir3_shader_assemble(v, gpu_id);
if (shader_debug_enabled(v->shader->type)) {
fprintf(stdout, "Native code for unnamed %s shader %s:\n",
ir3_shader_stage(v), v->shader->nir->info.name);
if (v->shader->type == MESA_SHADER_FRAGMENT)
fprintf(stdout, "SIMD0\n");
- ir3_shader_disasm(v, bin, stdout);
+ ir3_shader_disasm(v, v->bin, stdout);
}
- free(bin);
-
/* no need to keep the ir around beyond this point: */
ir3_destroy(v->ir);
v->ir = NULL;
}
assemble_variant(v);
- if (!v->bo) {
+ if (!v->bin) {
debug_error("assemble failed!");
goto fail;
}
free(shader);
}
-static bool
-lower_output_var(nir_shader *nir, int location)
-{
- nir_foreach_variable (var, &nir->outputs) {
- if (var->data.driver_location == location &&
- ((var->data.precision == GLSL_PRECISION_MEDIUM) ||
- (var->data.precision == GLSL_PRECISION_LOW))) {
- if (glsl_get_base_type(var->type) == GLSL_TYPE_FLOAT)
- var->type = glsl_float16_type(var->type);
-
- return glsl_get_base_type(var->type) == GLSL_TYPE_FLOAT16;
- }
- }
-
- return false;
-}
-
+/**
+ * Creates a bitmask of the used bits of the shader key by this particular
+ * shader. Used by the gallium driver to skip state-dependent recompiles when
+ * possible.
+ */
static void
-lower_mediump_outputs(nir_shader *nir)
+ir3_setup_used_key(struct ir3_shader *shader)
{
- nir_function_impl *impl = nir_shader_get_entrypoint(nir);
- assert(impl);
+ nir_shader *nir = shader->nir;
+ struct shader_info *info = &nir->info;
+ struct ir3_shader_key *key = &shader->key_mask;
- /* Get rid of old derefs before we change the types of the variables */
- nir_opt_dce(nir);
-
- nir_builder b;
- nir_builder_init(&b, impl);
-
- nir_foreach_block_safe (block, impl) {
- nir_foreach_instr_safe (instr, block) {
- if (instr->type != nir_instr_type_intrinsic)
- continue;
-
- nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
- if (intr->intrinsic != nir_intrinsic_store_output)
- continue;
+ /* This key flag is just used to make for a cheaper ir3_shader_key_equal
+ * check in the common case.
+ */
+ key->has_per_samp = true;
+
+ if (info->stage == MESA_SHADER_FRAGMENT) {
+ key->fsaturate_s = ~0;
+ key->fsaturate_t = ~0;
+ key->fsaturate_r = ~0;
+ key->fastc_srgb = ~0;
+ key->fsamples = ~0;
+
+ if (info->inputs_read & VARYING_BITS_COLOR) {
+ key->rasterflat = true;
+ key->color_two_side = true;
+ }
- if (!lower_output_var(nir, nir_intrinsic_base(intr)))
- continue;
+ if ((info->outputs_written & ~(FRAG_RESULT_DEPTH |
+ FRAG_RESULT_STENCIL |
+ FRAG_RESULT_SAMPLE_MASK)) != 0) {
+ key->fclamp_color = true;
+ }
- b.cursor = nir_before_instr(&intr->instr);
- nir_instr_rewrite_src(&intr->instr, &intr->src[0],
- nir_src_for_ssa(nir_f2f16(&b, intr->src[0].ssa)));
+ /* Only used for deciding on behavior of
+ * nir_intrinsic_load_barycentric_sample
+ */
+ key->msaa = info->fs.uses_sample_qualifier;
+ } else {
+ key->tessellation = ~0;
+ key->has_gs = true;
+
+ if (info->outputs_written & VARYING_BITS_COLOR)
+ key->vclamp_color = true;
+
+ if (info->stage == MESA_SHADER_VERTEX) {
+ key->vsaturate_s = ~0;
+ key->vsaturate_t = ~0;
+ key->vsaturate_r = ~0;
+ key->vastc_srgb = ~0;
+ key->vsamples = ~0;
}
}
}
struct ir3_shader *
-ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir)
+ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
+ struct ir3_stream_output_info *stream_output)
{
struct ir3_shader *shader = CALLOC_STRUCT(ir3_shader);
shader->compiler = compiler;
shader->id = p_atomic_inc_return(&shader->compiler->shader_count);
shader->type = nir->info.stage;
+ if (stream_output)
+ memcpy(&shader->stream_output, stream_output, sizeof(shader->stream_output));
+
+ if (nir->info.stage == MESA_SHADER_GEOMETRY)
+ NIR_PASS_V(nir, ir3_nir_lower_gs);
NIR_PASS_V(nir, nir_lower_io, nir_var_all, ir3_glsl_type_size,
(nir_lower_io_options)0);
if (compiler->gpu_id >= 600 &&
nir->info.stage == MESA_SHADER_FRAGMENT &&
!(ir3_shader_debug & IR3_DBG_NOFP16))
- lower_mediump_outputs(nir);
+ NIR_PASS_V(nir, nir_lower_mediump_outputs);
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
/* NOTE: lower load_barycentric_at_sample first, since it
nir_print_shader(shader->nir, stdout);
}
+ ir3_setup_used_key(shader);
+
return shader;
}
uint8_t regid;
unsigned i;
- struct ir3_instruction *instr;
foreach_input_n (instr, i, ir) {
reg = instr->regs[0];
regid = reg->num;
/* print pre-dispatch texture fetches: */
for (i = 0; i < so->num_sampler_prefetch; i++) {
const struct ir3_sampler_prefetch *fetch = &so->sampler_prefetch[i];
- fprintf(out, "@tex(%sr%d.%c)\tsrc=%u, samp=%u, tex=%u, wrmask=%x, cmd=%u\n",
+ fprintf(out, "@tex(%sr%d.%c)\tsrc=%u, samp=%u, tex=%u, wrmask=0x%x, cmd=%u\n",
fetch->half_precision ? "h" : "",
fetch->dst >> 2, "xyzw"[fetch->dst & 0x3],
fetch->src, fetch->samp_id, fetch->tex_id,