-static void
-delete_variant(struct fd3_shader_variant *v)
-{
- ir3_shader_destroy(v->ir);
- fd_bo_del(v->bo);
- free(v);
-}
-
-static void
-assemble_variant(struct fd3_shader_variant *so)
-{
- struct fd_context *ctx = fd_context(so->so->pctx);
- uint32_t sz, *bin;
-
- bin = ir3_shader_assemble(so->ir, &so->info);
- sz = so->info.sizedwords * 4;
-
- so->bo = fd_bo_new(ctx->dev, sz,
- DRM_FREEDRENO_GEM_CACHE_WCOMBINE |
- DRM_FREEDRENO_GEM_TYPE_KMEM);
-
- memcpy(fd_bo_map(so->bo), bin, sz);
-
- free(bin);
-
- so->instrlen = so->info.sizedwords / 8;
- so->constlen = so->info.max_const + 1;
-}
-
-/* for vertex shader, the inputs are loaded into registers before the shader
- * is executed, so max_regs from the shader instructions might not properly
- * reflect the # of registers actually used:
- */
-static void
-fixup_vp_regfootprint(struct fd3_shader_variant *so)
-{
- unsigned i;
- for (i = 0; i < so->inputs_count; i++) {
- if (so->inputs[i].compmask) {
- uint32_t regid = (so->inputs[i].regid + 3) >> 2;
- so->info.max_reg = MAX2(so->info.max_reg, regid);
- }
- }
- for (i = 0; i < so->outputs_count; i++) {
- uint32_t regid = (so->outputs[i].regid + 3) >> 2;
- so->info.max_reg = MAX2(so->info.max_reg, regid);
- }
-}
-
-static struct fd3_shader_variant *
-create_variant(struct fd3_shader_stateobj *so, struct fd3_shader_key key)
-{
- struct fd3_shader_variant *v = CALLOC_STRUCT(fd3_shader_variant);
- const struct tgsi_token *tokens = so->tokens;
- int ret;
-
- if (!v)
- return NULL;
-
- v->so = so;
- v->key = key;
- v->type = so->type;
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- DBG("dump tgsi: type=%d, k={bp=%u,cts=%u,hp=%u}", so->type,
- key.binning_pass, key.color_two_side, key.half_precision);
- tgsi_dump(tokens, 0);
- }
-
- if (!(fd_mesa_debug & FD_DBG_NOOPT)) {
- ret = fd3_compile_shader(v, tokens, key);
- if (ret) {
- debug_error("new compiler failed, trying fallback!");
-
- v->inputs_count = 0;
- v->outputs_count = 0;
- v->total_in = 0;
- v->has_samp = false;
- v->immediates_count = 0;
- }
- } else {
- ret = -1; /* force fallback to old compiler */
- }
-
- if (ret)
- ret = fd3_compile_shader_old(v, tokens, key);
-
- if (ret) {
- debug_error("compile failed!");
- goto fail;
- }
-
- assemble_variant(v);
- if (!v->bo) {
- debug_error("assemble failed!");
- goto fail;
- }
-
- if (so->type == SHADER_VERTEX)
- fixup_vp_regfootprint(v);
-
- if (fd_mesa_debug & FD_DBG_DISASM) {
- DBG("disassemble: type=%d, k={bp=%u,cts=%u,hp=%u}", v->type,
- key.binning_pass, key.color_two_side, key.half_precision);
- disasm_a3xx(fd_bo_map(v->bo), v->info.sizedwords, 0, v->type);
- }
-
- return v;
-
-fail:
- delete_variant(v);
- return NULL;
-}
-
-struct fd3_shader_variant *
-fd3_shader_variant(struct fd3_shader_stateobj *so, struct fd3_shader_key key)
-{
- struct fd3_shader_variant *v;
-
- /* some shader key values only apply to vertex or frag shader,
- * so normalize the key to avoid constructing multiple identical
- * variants:
- */
- if (so->type == SHADER_FRAGMENT) {
- key.binning_pass = false;
- }
- if (so->type == SHADER_VERTEX) {
- key.color_two_side = false;
- key.half_precision = false;
- }
-
- for (v = so->variants; v; v = v->next)
- if (!memcmp(&key, &v->key, sizeof(key)))
- return v;
-
- /* compile new variant if it doesn't exist already: */
- v = create_variant(so, key);
- v->next = so->variants;
- so->variants = v;
-
- return v;
-}
-
-
-static void
-delete_shader(struct fd3_shader_stateobj *so)
-{
- struct fd3_shader_variant *v, *t;
- for (v = so->variants; v; ) {
- t = v;
- v = v->next;
- delete_variant(t);
- }
- free((void *)so->tokens);
- free(so);
-}
-
-static struct fd3_shader_stateobj *
-create_shader(struct pipe_context *pctx, const struct pipe_shader_state *cso,