const struct tgsi_token * tgsi_emulate(const struct tgsi_token *tokens, unsigned flags) { struct tgsi_emulation_context ctx; struct tgsi_token *newtoks; int newlen; if (!(flags & (TGSI_EMU_CLAMP_COLOR_OUTPUTS | TGSI_EMU_PASSTHROUGH_EDGEFLAG | TGSI_EMU_FORCE_PERSAMPLE_INTERP))) return NULL; memset(&ctx, 0, sizeof(ctx)); ctx.flags = flags; tgsi_scan_shader(tokens, &ctx.info); if (flags & TGSI_EMU_FORCE_PERSAMPLE_INTERP) ctx.base.transform_declaration = transform_decl; if (flags & (TGSI_EMU_CLAMP_COLOR_OUTPUTS | TGSI_EMU_PASSTHROUGH_EDGEFLAG)) ctx.base.transform_instruction = transform_instr; newlen = tgsi_num_tokens(tokens) + 20; newtoks = tgsi_alloc_tokens(newlen); if (!newtoks) return NULL; tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); return newtoks; }
/** * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ static boolean generate_aaline_fs(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->stage.draw->pipe; const struct pipe_shader_state *orig_fs = &aaline->fs->state; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS; aaline_fs = *orig_fs; /* copy to init */ aaline_fs.tokens = tgsi_alloc_tokens(newLen); if (aaline_fs.tokens == NULL) return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; transform.maxInput = -1; transform.maxGeneric = -1; transform.colorTemp = -1; transform.texTemp = -1; transform.base.prolog = aa_transform_prolog; transform.base.epilog = aa_transform_epilog; transform.base.transform_instruction = aa_transform_inst; transform.base.transform_declaration = aa_transform_decl; tgsi_transform_shader(orig_fs->tokens, (struct tgsi_token *) aaline_fs.tokens, newLen, &transform.base); #if 0 /* DEBUG */ debug_printf("draw_aaline, orig shader:\n"); tgsi_dump(orig_fs->tokens, 0); debug_printf("draw_aaline, new shader:\n"); tgsi_dump(aaline_fs.tokens, 0); #endif aaline->fs->sampler_unit = transform.freeSampler; aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs); if (aaline->fs->aaline_fs == NULL) goto fail; aaline->fs->generic_attrib = transform.maxGeneric + 1; FREE((void *)aaline_fs.tokens); return TRUE; fail: FREE((void *)aaline_fs.tokens); return FALSE; }
/** * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ static boolean generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; #define MAX 1000 aaline_fs = *orig_fs; /* copy to init */ aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); if (aaline_fs.tokens == NULL) return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; transform.maxInput = -1; transform.maxGeneric = -1; transform.colorTemp = -1; transform.texTemp = -1; transform.firstInstruction = TRUE; transform.base.transform_instruction = aa_transform_inst; transform.base.transform_declaration = aa_transform_decl; tgsi_transform_shader(orig_fs->tokens, (struct tgsi_token *) aaline_fs.tokens, MAX, &transform.base); #if 0 /* DEBUG */ tgsi_dump(orig_fs->tokens, 0); tgsi_dump(aaline_fs.tokens, 0); #endif aaline->fs->sampler_unit = transform.freeSampler; aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); if (aaline->fs->aaline_fs == NULL) return FALSE; aaline->fs->generic_attrib = transform.maxGeneric + 1; return TRUE; }
/* * A post-process step in the draw call to fix texture targets and * insert code for fog. */ const struct tgsi_token * st_fixup_atifs(const struct tgsi_token *tokens, const struct st_fp_variant_key *key) { struct tgsi_atifs_transform ctx; struct tgsi_token *newtoks; int newlen; memset(&ctx, 0, sizeof(ctx)); ctx.base.transform_declaration = transform_decl; ctx.base.transform_instruction = transform_instr; ctx.key = key; tgsi_scan_shader(tokens, &ctx.info); newlen = tgsi_num_tokens(tokens) + 30; newtoks = tgsi_alloc_tokens(newlen); if (!newtoks) return NULL; tgsi_transform_shader(tokens, newtoks, newlen, &ctx.base); return newtoks; }
void r300_draw_init_vertex_shader(struct r300_context *r300, struct r300_vertex_shader *vs) { struct draw_context *draw = r300->draw; struct pipe_shader_state new_vs; struct tgsi_shader_info info; struct vs_transform_context transform; const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */; unsigned i; tgsi_scan_shader(vs->state.tokens, &info); new_vs.tokens = tgsi_alloc_tokens(newLen); if (new_vs.tokens == NULL) return; memset(&transform, 0, sizeof(transform)); for (i = 0; i < Elements(transform.out_remap); i++) { transform.out_remap[i] = i; } transform.last_generic = -1; transform.base.transform_instruction = transform_inst; transform.base.transform_declaration = transform_decl; for (i = 0; i < info.num_outputs; i++) { unsigned index = info.output_semantic_index[i]; switch (info.output_semantic_name[i]) { case TGSI_SEMANTIC_COLOR: assert(index < 2); transform.color_used[index] = TRUE; break; case TGSI_SEMANTIC_BCOLOR: assert(index < 2); transform.bcolor_used[index] = TRUE; break; } } tgsi_transform_shader(vs->state.tokens, (struct tgsi_token*)new_vs.tokens, newLen, &transform.base); #if 0 printf("----------------------------------------------\norig shader:\n"); tgsi_dump(vs->state.tokens, 0); printf("----------------------------------------------\nnew shader:\n"); tgsi_dump(new_vs.tokens, 0); printf("----------------------------------------------\n"); #endif /* Free old tokens. */ FREE((void*)vs->state.tokens); vs->draw_vs = draw_create_vertex_shader(draw, &new_vs); /* Instead of duplicating and freeing the tokens, copy the pointer directly. */ vs->state.tokens = new_vs.tokens; /* Init the VS output table for the rasterizer. */ r300_init_vs_outputs(r300, vs); /* Make the last generic be WPOS. */ vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1]; vs->outputs.generic[transform.last_generic + 1] = ATTR_UNUSED; }