コード例 #1
0
ファイル: tgsi_ureg.c プロジェクト: blckshrk/Mesa
const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
{
   const struct tgsi_token *tokens;

   emit_header( ureg );
   emit_decls( ureg );
   copy_instructions( ureg );
   fixup_header_size( ureg );
   
   if (ureg->domain[0].tokens == error_tokens ||
       ureg->domain[1].tokens == error_tokens) {
      debug_printf("%s: error in generated shader\n", __FUNCTION__);
      assert(0);
      return NULL;
   }

   tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;

   if (0) {
      debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__, 
                   ureg->domain[DOMAIN_DECL].count);
      tgsi_dump( tokens, 0 );
   }

#if DEBUG
   if (tokens && !tgsi_sanity_check(tokens)) {
      debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");
      tgsi_dump(tokens, 0);
      assert(0);
   }
#endif

   
   return tokens;
}
コード例 #2
0
ファイル: draw_pipe_aaline.c プロジェクト: John-Gee/Mesa-3D
/**
 * 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;
}
コード例 #3
0
ファイル: u_simple_shaders.c プロジェクト: ndesh26/Mesa
/**
 * Make simple fragment color pass-through shader that replicates OUT[0]
 * to all bound colorbuffers.
 */
void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe,
                                      int input_semantic,
                                      int input_interpolate,
                                      boolean write_all_cbufs)
{
   static const char shader_templ[] =
         "FRAG\n"
         "%s"
         "DCL IN[0], %s[0], %s\n"
         "DCL OUT[0], COLOR[0]\n"

         "MOV OUT[0], IN[0]\n"
         "END\n";

   char text[sizeof(shader_templ)+100];
   struct tgsi_token tokens[1000];
   struct pipe_shader_state state;

   sprintf(text, shader_templ,
           write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "",
           tgsi_semantic_names[input_semantic],
           tgsi_interpolate_names[input_interpolate]);

   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
      assert(0);
      return NULL;
   }
   pipe_shader_state_from_tgsi(&state, tokens);
#if 0
   tgsi_dump(state.tokens, 0);
#endif

   return pipe->create_fs_state(pipe, &state);
}
void
i915_translate_fragment_program( struct i915_context *i915,
                                 struct i915_fragment_shader *fs)
{
   struct i915_fp_compile *p;
   const struct tgsi_token *tokens = fs->state.tokens;
   struct i915_token_list* i_tokens;

#if 0
   tgsi_dump(tokens, 0);
#endif

   /* hw doesn't seem to like empty frag programs, even when the depth write
    * fixup gets emitted below - may that one is fishy, too? */
   if (fs->info.num_instructions == 1) {
      i915_use_passthrough_shader(fs);

      return;
   }

   p = i915_init_compile(i915, fs);

   i_tokens = i915_optimize(tokens);
   i915_translate_instructions(p, i_tokens, fs);
   i915_fixup_depth_write(p);

   i915_fini_compile(i915, p);
   i915_optimize_free(i_tokens);

#if 0
   i915_disassemble_program(NULL, fs->program, fs->program_len);
#endif
}
コード例 #5
0
ファイル: lp_state_gs.c プロジェクト: ChristophHaag/mesa-mesa
static void *
llvmpipe_create_gs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
   struct lp_geometry_shader *state;

   state = CALLOC_STRUCT(lp_geometry_shader);
   if (!state)
      goto no_state;

   /* debug */
   if (LP_DEBUG & DEBUG_TGSI) {
      debug_printf("llvmpipe: Create geometry shader %p:\n", (void *)state);
      tgsi_dump(templ->tokens, 0);
   }

   /* copy stream output info */
   state->no_tokens = !templ->tokens;
   memcpy(&state->stream_output, &templ->stream_output, sizeof state->stream_output);

   if (templ->tokens) {
      state->dgs = draw_create_geometry_shader(llvmpipe->draw, templ);
      if (state->dgs == NULL) {
         goto no_dgs;
      }
   }

   return state;

no_dgs:
   FREE( state );
no_state:
   return NULL;
}
コード例 #6
0
/**
 * Translate the TGSI tokens.
 */
static bool
vs_setup_tgsi(struct toy_compiler *tc, const struct tgsi_token *tokens,
              struct toy_tgsi *tgsi)
{
   if (ilo_debug & ILO_DEBUG_VS) {
      ilo_printf("dumping vertex shader\n");
      ilo_printf("\n");

      tgsi_dump(tokens, 0);
      ilo_printf("\n");
   }

   toy_compiler_translate_tgsi(tc, tokens, true, tgsi);
   if (tc->fail) {
      ilo_err("failed to translate VS TGSI tokens: %s\n", tc->reason);
      return false;
   }

   if (ilo_debug & ILO_DEBUG_VS) {
      ilo_printf("TGSI translator:\n");
      toy_tgsi_dump(tgsi);
      ilo_printf("\n");
      toy_compiler_dump(tc);
      ilo_printf("\n");
   }

   return true;
}
コード例 #7
0
ファイル: ilo_shader_gs.c プロジェクト: Distrotech/Mesa
/**
 * Translate the TGSI tokens.
 */
static bool
gs_setup_tgsi(struct toy_compiler *tc, const struct tgsi_token *tokens,
              struct toy_tgsi *tgsi)
{
   if (ilo_debug & ILO_DEBUG_GS) {
      ilo_printf("dumping geometry shader\n");
      ilo_printf("\n");

      tgsi_dump(tokens, 0);
      ilo_printf("\n");
   }

   toy_compiler_translate_tgsi(tc, tokens, true, tgsi);
   if (tc->fail)
      return false;

   if (ilo_debug & ILO_DEBUG_GS) {
      ilo_printf("TGSI translator:\n");
      toy_tgsi_dump(tgsi);
      ilo_printf("\n");
      toy_compiler_dump(tc);
      ilo_printf("\n");
   }

   return true;
}
コード例 #8
0
ファイル: ir3_gallium.c プロジェクト: FireBurn/mesa
struct ir3_shader *
ir3_shader_create(struct ir3_compiler *compiler,
		const struct pipe_shader_state *cso, gl_shader_stage type,
		struct pipe_debug_callback *debug,
		struct pipe_screen *screen)
{
	nir_shader *nir;
	if (cso->type == PIPE_SHADER_IR_NIR) {
		/* we take ownership of the reference: */
		nir = cso->ir.nir;
	} else {
		debug_assert(cso->type == PIPE_SHADER_IR_TGSI);
		if (ir3_shader_debug & IR3_DBG_DISASM) {
			tgsi_dump(cso->tokens, 0);
		}
		nir = tgsi_to_nir(cso->tokens, screen);
	}

	struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir);

	copy_stream_out(&shader->stream_output, &cso->stream_output);

	if (fd_mesa_debug & FD_DBG_SHADERDB) {
		/* if shader-db run, create a standard variant immediately
		 * (as otherwise nothing will trigger the shader to be
		 * actually compiled)
		 */
		static struct ir3_shader_key key;
		memset(&key, 0, sizeof(key));
		ir3_shader_variant(shader, key, false, debug);
	}
	return shader;
}
コード例 #9
0
ファイル: fd2_program.c プロジェクト: Haifen/Mesa-3D
static struct fd2_shader_stateobj *
compile(struct fd_program_stateobj *prog, struct fd2_shader_stateobj *so)
{
	int ret;

	if (fd_mesa_debug & FD_DBG_DISASM) {
		DBG("dump tgsi: type=%d", so->type);
		tgsi_dump(so->tokens, 0);
	}

	ret = fd2_compile_shader(prog, so);
	if (ret)
		goto fail;

	/* NOTE: we don't assemble yet because for VS we don't know the
	 * type information for vertex fetch yet.. so those need to be
	 * patched up later before assembling.
	 */

	so->info.sizedwords = 0;

	return so;

fail:
	debug_error("compile failed!");
	delete_shader(so);
	return NULL;
}
コード例 #10
0
ファイル: shdr_dump.c プロジェクト: Distrotech/mesa-demos
static void shader_info(struct rbug_connection *con, rbug_context_t ctx)
{
   struct rbug_header *header;
   struct rbug_proto_shader_list_reply *list;
   struct rbug_proto_shader_info_reply *info;
   int i;

   debug_printf("Sending get shaders to %llu\n", (unsigned long long)ctx);
   rbug_send_shader_list(con, ctx, NULL);

   debug_printf("Waiting for shaders from %llu\n", (unsigned long long)ctx);
   header = rbug_get_message(con, NULL);
   assert(header->opcode == RBUG_OP_SHADER_LIST_REPLY);
   list = (struct rbug_proto_shader_list_reply *)header;

   debug_printf("Got shaders:\n");
   for (i = 0; i < list->shaders_len; i++) {
      rbug_send_shader_info(con, ctx, list->shaders[i], NULL);

      header = rbug_get_message(con, NULL);
      assert(header->opcode == RBUG_OP_SHADER_INFO_REPLY);
      info = (struct rbug_proto_shader_info_reply *)header;

      debug_printf("#####################################################\n");
      debug_printf("ctx: %llu shdr: %llu disabled %u\n",
                   (unsigned long long)ctx,
                   (unsigned long long)list->shaders[i],
                   info->disabled);

      /* just to be sure */
      assert(sizeof(struct tgsi_token) == 4);

      debug_printf("-----------------------------------------------------\n");
      tgsi_dump((struct tgsi_token *)info->original, 0);

      if (info->replaced_len > 0) {
         debug_printf("-----------------------------------------------------\n");
         tgsi_dump((struct tgsi_token *)info->replaced, 0);
      }

      rbug_free_header(header);
   }

   debug_printf("#####################################################\n");
   rbug_free_header(&list->header);
}
コード例 #11
0
void
lp_debug_fs_variant(const struct lp_fragment_shader_variant *variant)
{
   debug_printf("llvmpipe: Fragment shader #%u variant #%u:\n", 
                variant->shader->no, variant->no);
   tgsi_dump(variant->shader->base.tokens, 0);
   dump_fs_variant_key(&variant->key);
   debug_printf("variant->opaque = %u\n", variant->opaque);
   debug_printf("\n");
}
コード例 #12
0
/**
 * 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;
}
コード例 #13
0
ファイル: test.c プロジェクト: skrishnakar/etna_viv
int main(int argc, char **argv)
{
    if(argc < 2)
    {
        fprintf(stderr, "Must pass shader source name as argument\n");
        exit(1);
    }
    const char *text = load_text_file(argv[1]);
    if(!text)
    {
        fprintf(stderr, "Unable to open %s\n", argv[1]);
        exit(1);
    }
    struct tgsi_token tokens[1024];
    if(tgsi_text_translate(text, tokens, Elements(tokens)))
    {
        tgsi_dump(tokens, 0); 

        union {
            struct tgsi_header h;
            struct tgsi_token t;
        } hdr;

        hdr.t = tokens[0];
        printf("Header size: %i\n", hdr.h.HeaderSize);
        printf("Body size: %i\n", hdr.h.BodySize);
        int totalSize = hdr.h.HeaderSize + hdr.h.BodySize;

        for(int i=0; i<totalSize; ++i)
        {
            printf("%08x ", *((uint32_t*)&tokens[i]));
        }
        printf("\n");

        /* Parsing test */
        struct tgsi_parse_context ctx = {};
        unsigned status = TGSI_PARSE_OK;
        status = tgsi_parse_init(&ctx, tokens);
        assert(status == TGSI_PARSE_OK);

        while(!tgsi_parse_end_of_tokens(&ctx))
        {
            tgsi_parse_token(&ctx);
            /* declaration / immediate / instruction / property */
            printf("Parsed token! %i\n", ctx.FullToken.Token.Type);
        }

        tgsi_parse_free(&ctx);
    } else {
        fprintf(stderr, "Unable to parse %s\n", argv[1]);
    }

    return 0;
}
コード例 #14
0
ファイル: fd3_program.c プロジェクト: CSRedRat/mesa-1
static struct fd3_shader_stateobj *
create_shader(struct pipe_context *pctx, const struct pipe_shader_state *cso,
		enum shader_t type)
{
	struct fd3_shader_stateobj *so = CALLOC_STRUCT(fd3_shader_stateobj);
	int ret;

	if (!so)
		return NULL;

	so->type = type;

	if (fd_mesa_debug & FD_DBG_DISASM) {
		DBG("dump tgsi: type=%d", so->type);
		tgsi_dump(cso->tokens, 0);
	}

	if (type == SHADER_FRAGMENT) {
		/* we seem to get wrong colors (maybe swap/endianess or hw issue?)
		 * with full precision color reg.  And blob driver only seems to
		 * use half precision register for color output (that I can find
		 * so far), even with highp precision.  So for force half precision
		 * for frag shader:
		 */
		so->half_precision = true;
	}

	ret = fd3_compile_shader(so, cso->tokens);
	if (ret) {
		debug_error("compile failed!");
		goto fail;
	}

	assemble_shader(pctx, so);
	if (!so->bo) {
		debug_error("assemble failed!");
		goto fail;
	}

	if (type == SHADER_VERTEX)
		fixup_vp_regfootprint(so);

	if (fd_mesa_debug & FD_DBG_DISASM) {
		DBG("disassemble: type=%d", so->type);
		disasm_a3xx(fd_bo_map(so->bo), so->info.sizedwords, 0, so->type);
	}

	return so;

fail:
	delete_shader(so);
	return NULL;
}
コード例 #15
0
static INLINE struct tgsi_token *tokens_from_assembly(const char *txt, int num_tokens)
{
   struct tgsi_token *tokens;

   tokens = (struct tgsi_token *) MALLOC(num_tokens * sizeof(tokens[0]));

   tgsi_text_translate(txt, tokens, num_tokens);

#if DEBUG_SHADERS
   tgsi_dump(tokens, 0);
#endif

   return tokens;
}
コード例 #16
0
ファイル: st_debug.c プロジェクト: aljen/haiku-opengl
/**
 * Print current state.  May be called from inside gdb to see currently
 * bound vertex/fragment shaders and associated constants.
 */
void
st_print_current(void)
{
   GET_CURRENT_CONTEXT(ctx);
   struct st_context *st = ctx->st;

#if 0
   int i;

   printf("Vertex Transform Inputs:\n");
   for (i = 0; i < st->vp->state.num_inputs; i++) {
      printf("  Slot %d:  VERT_ATTRIB_%d\n", i, st->vp->index_to_input[i]);
   }
#endif

   tgsi_dump( st->vp->state.tokens, 0 );
   if (st->vp->Base.Base.Parameters)
      _mesa_print_parameter_list(st->vp->Base.Base.Parameters);

   tgsi_dump( st->fp->state.tokens, 0 );
   if (st->fp->Base.Base.Parameters)
      _mesa_print_parameter_list(st->fp->Base.Base.Parameters);
}
コード例 #17
0
ファイル: r300_vs.c プロジェクト: CPFDSoftware-Tony/gmv
void r300_translate_vertex_shader(struct r300_context* r300,
                                  struct r300_vertex_shader* vs)
{
    struct r300_vertex_program_compiler compiler;
    struct tgsi_to_rc ttr;

    /* Initialize. */
    r300_shader_read_vs_outputs(&vs->info, &vs->outputs);

    /* Setup the compiler */
    rc_init(&compiler.Base);

    compiler.Base.Debug = DBG_ON(r300, DBG_VP);
    compiler.code = &vs->code;
    compiler.UserData = vs;

    if (compiler.Base.Debug) {
        debug_printf("r300: Initial vertex program\n");
        tgsi_dump(vs->state.tokens, 0);
    }

    /* Translate TGSI to our internal representation */
    ttr.compiler = &compiler.Base;
    ttr.info = &vs->info;
    ttr.use_half_swizzles = FALSE;

    r300_tgsi_to_rc(&ttr, vs->state.tokens);

    compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs+1));
    compiler.SetHwInputOutput = &set_vertex_inputs_outputs;

    /* Insert the WPOS output. */
    r300_insert_wpos(&compiler, &vs->outputs);

    r300_shader_vap_output_fmt(vs);
    r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);

    /* Invoke the compiler */
    r3xx_compile_vertex_program(&compiler);
    if (compiler.Base.Error) {
        /* XXX We should fallback using Draw. */
        fprintf(stderr, "r300 VP: Compiler error\n");
        abort();
    }

    /* And, finally... */
    rc_destroy(&compiler.Base);
    vs->translated = TRUE;
}
コード例 #18
0
ファイル: r300_fs.c プロジェクト: MttDs/new-rexeno-tindpe
void r300_translate_fragment_shader(struct r300_context* r300,
                                    struct r300_fragment_shader* fs)
{
    struct r300_fragment_program_compiler compiler;
    struct tgsi_to_rc ttr;

    memset(&compiler, 0, sizeof(compiler));
    rc_init(&compiler.Base);
    compiler.Base.Debug = DBG_ON(r300, DBG_FP);

    compiler.code = &fs->code;
    compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
    compiler.AllocateHwInputs = &allocate_hardware_inputs;
    compiler.UserData = fs;

    /* TODO: Program compilation depends on texture compare modes,
     * which are sampler state. Therefore, programs need to be recompiled
     * depending on this state as in the classic Mesa driver.
     *
     * This is not yet handled correctly.
     */

    find_output_registers(&compiler, fs);

    if (compiler.Base.Debug) {
        debug_printf("r300: Initial fragment program\n");
        tgsi_dump(fs->state.tokens, 0);
    }

    /* Translate TGSI to our internal representation */
    ttr.compiler = &compiler.Base;
    ttr.info = &fs->info;

    r300_tgsi_to_rc(&ttr, fs->state.tokens);

    /* Invoke the compiler */
    r3xx_compile_fragment_program(&compiler);
    if (compiler.Base.Error) {
        /* XXX failover maybe? */
        DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
            compiler.Base.ErrorMsg);
    }

    /* And, finally... */
    rc_destroy(&compiler.Base);
    fs->translated = TRUE;
}
コード例 #19
0
ファイル: u_simple_shaders.c プロジェクト: ndesh26/Mesa
static void *
util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
                           enum tgsi_texture_type tgsi_tex,
                           const char *samp_type,
                           const char *output_semantic,
                           const char *output_mask,
                           const char *conversion_decl,
                           const char *conversion)
{
   static const char shader_templ[] =
         "FRAG\n"
         "DCL IN[0], GENERIC[0], LINEAR\n"
         "DCL SAMP[0]\n"
         "DCL SVIEW[0], %s, %s\n"
         "DCL OUT[0], %s\n"
         "DCL TEMP[0]\n"
         "%s"

         "F2U TEMP[0], IN[0]\n"
         "TXF TEMP[0], TEMP[0], SAMP[0], %s\n"
         "%s"
         "MOV OUT[0]%s, TEMP[0]\n"
         "END\n";

   const char *type = tgsi_texture_names[tgsi_tex];
   char text[sizeof(shader_templ)+100];
   struct tgsi_token tokens[1000];
   struct pipe_shader_state state;

   assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
          tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);

   util_snprintf(text, sizeof(text), shader_templ, type, samp_type,
                 output_semantic, conversion_decl, type, conversion, output_mask);

   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
      puts(text);
      assert(0);
      return NULL;
   }
   pipe_shader_state_from_tgsi(&state, tokens);
#if 0
   tgsi_dump(state.tokens, 0);
#endif

   return pipe->create_fs_state(pipe, &state);
}
コード例 #20
0
ファイル: st_program.c プロジェクト: ashmew2/kolibriosSVN
/**
 * For debugging, print/dump the current vertex program.
 */
void
st_print_current_vertex_program(void)
{
   GET_CURRENT_CONTEXT(ctx);

   if (ctx->VertexProgram._Current) {
      struct st_vertex_program *stvp =
         (struct st_vertex_program *) ctx->VertexProgram._Current;
      struct st_vp_variant *stv;

      debug_printf("Vertex program %u\n", stvp->Base.Base.Id);

      for (stv = stvp->variants; stv; stv = stv->next) {
         debug_printf("variant %p\n", stv);
         tgsi_dump(stv->tgsi.tokens, 0);
      }
   }
}
コード例 #21
0
static void *
llvmpipe_create_fs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
   struct lp_fragment_shader *shader;
   int nr_samplers;

   shader = CALLOC_STRUCT(lp_fragment_shader);
   if (!shader)
      return NULL;

   shader->no = fs_no++;
   make_empty_list(&shader->variants);

   /* get/save the summary info for this shader */
   tgsi_scan_shader(templ->tokens, &shader->info);

   /* we need to keep a local copy of the tokens */
   shader->base.tokens = tgsi_dup_tokens(templ->tokens);

   nr_samplers = shader->info.file_max[TGSI_FILE_SAMPLER] + 1;

   shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key,
				     sampler[nr_samplers]);

   if (LP_DEBUG & DEBUG_TGSI) {
      unsigned attrib;
      debug_printf("llvmpipe: Create fragment shader #%u %p:\n", shader->no, (void *) shader);
      tgsi_dump(templ->tokens, 0);
      debug_printf("usage masks:\n");
      for (attrib = 0; attrib < shader->info.num_inputs; ++attrib) {
         unsigned usage_mask = shader->info.input_usage_mask[attrib];
         debug_printf("  IN[%u].%s%s%s%s\n",
                      attrib,
                      usage_mask & TGSI_WRITEMASK_X ? "x" : "",
                      usage_mask & TGSI_WRITEMASK_Y ? "y" : "",
                      usage_mask & TGSI_WRITEMASK_Z ? "z" : "",
                      usage_mask & TGSI_WRITEMASK_W ? "w" : "");
      }
      debug_printf("\n");
   }

   return shader;
}
コード例 #22
0
ファイル: lp_state_vs.c プロジェクト: John-Gee/Mesa-3D
static void *
llvmpipe_create_vs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
   struct draw_vertex_shader *vs;

   vs = draw_create_vertex_shader(llvmpipe->draw, templ);
   if (vs == NULL) {
      return NULL;
   }

   if (LP_DEBUG & DEBUG_TGSI) {
      debug_printf("llvmpipe: Create vertex shader %p:\n", (void *) vs);
      tgsi_dump(templ->tokens, 0);
   }

   return vs;
}
コード例 #23
0
ファイル: ir3_gallium.c プロジェクト: FireBurn/mesa
/* a bit annoying that compute-shader and normal shader state objects
 * aren't a bit more aligned.
 */
struct ir3_shader *
ir3_shader_create_compute(struct ir3_compiler *compiler,
		const struct pipe_compute_state *cso,
		struct pipe_debug_callback *debug,
		struct pipe_screen *screen)
{
	nir_shader *nir;
	if (cso->ir_type == PIPE_SHADER_IR_NIR) {
		/* we take ownership of the reference: */
		nir = (nir_shader *)cso->prog;
	} else {
		debug_assert(cso->ir_type == PIPE_SHADER_IR_TGSI);
		if (ir3_shader_debug & IR3_DBG_DISASM) {
			tgsi_dump(cso->prog, 0);
		}
		nir = tgsi_to_nir(cso->prog, screen);
	}

	struct ir3_shader *shader = ir3_shader_from_nir(compiler, nir);

	return shader;
}
コード例 #24
0
ファイル: u_simple_shaders.c プロジェクト: ndesh26/Mesa
/**
 * Make a fragment shader that sets the output depth and stencil to depth
 * and stencil values fetched from two multisample textures / samplers.
 * The sizes of both textures should match (it should be one depth-stencil
 * texture).
 * \param tex_target  one of PIPE_TEXTURE_x
 */
void *
util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe,
                                    enum tgsi_texture_type tgsi_tex)
{
   static const char shader_templ[] =
         "FRAG\n"
         "DCL IN[0], GENERIC[0], LINEAR\n"
         "DCL SAMP[0..1]\n"
         "DCL SVIEW[0..1], %s, FLOAT\n"
         "DCL OUT[0], POSITION\n"
         "DCL OUT[1], STENCIL\n"
         "DCL TEMP[0]\n"

         "F2U TEMP[0], IN[0]\n"
         "TXF OUT[0].z, TEMP[0], SAMP[0], %s\n"
         "TXF OUT[1].y, TEMP[0], SAMP[1], %s\n"
         "END\n";

   const char *type = tgsi_texture_names[tgsi_tex];
   char text[sizeof(shader_templ)+100];
   struct tgsi_token tokens[1000];
   struct pipe_shader_state state;

   assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
          tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);

   sprintf(text, shader_templ, type, type, type);

   if (!tgsi_text_translate(text, tokens, ARRAY_SIZE(tokens))) {
      assert(0);
      return NULL;
   }
   pipe_shader_state_from_tgsi(&state, tokens);
#if 0
   tgsi_dump(state.tokens, 0);
#endif

   return pipe->create_fs_state(pipe, &state);
}
コード例 #25
0
ファイル: lp_state_gs.c プロジェクト: ashmew2/kolibriosSVN
static void *
llvmpipe_create_gs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    struct lp_geometry_shader *state;

    state = CALLOC_STRUCT(lp_geometry_shader);
    if (state == NULL )
        goto fail;

    /* debug */
    if (0)
        tgsi_dump(templ->tokens, 0);

    /* copy stream output info */
    state->shader = *templ;
    if (templ->tokens) {
        /* copy shader tokens, the ones passed in will go away. */
        state->shader.tokens = tgsi_dup_tokens(templ->tokens);
        if (state->shader.tokens == NULL)
            goto fail;

        state->draw_data = draw_create_geometry_shader(llvmpipe->draw, templ);
        if (state->draw_data == NULL)
            goto fail;
    }

    return state;

fail:
    if (state) {
        FREE( (void *)state->shader.tokens );
        FREE( state->draw_data );
        FREE( state );
    }
    return NULL;
}
コード例 #26
0
static void *
util_make_fs_blit_msaa_gen(struct pipe_context *pipe,
                           unsigned tgsi_tex,
                           const char *output_semantic,
                           const char *output_mask)
{
   static const char shader_templ[] =
         "FRAG\n"
         "DCL IN[0], GENERIC[0], LINEAR\n"
         "DCL SAMP[0]\n"
         "DCL OUT[0], %s\n"
         "DCL TEMP[0]\n"

         "F2U TEMP[0], IN[0]\n"
         "TXF OUT[0]%s, TEMP[0], SAMP[0], %s\n"
         "END\n";

   const char *type = tgsi_texture_names[tgsi_tex];
   char text[sizeof(shader_templ)+100];
   struct tgsi_token tokens[1000];
   struct pipe_shader_state state = {tokens};

   assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA ||
          tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA);

   sprintf(text, shader_templ, output_semantic, output_mask, type);

   if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
      puts(text);
      assert(0);
      return NULL;
   }
#if 0
   tgsi_dump(state.tokens, 0);
#endif

   return pipe->create_fs_state(pipe, &state);
}
コード例 #27
0
ファイル: lp_state_vs.c プロジェクト: venkatarajasekhar/Qt
static void *
llvmpipe_create_vs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
   struct lp_vertex_shader *state;

   state = CALLOC_STRUCT(lp_vertex_shader);
   if (state == NULL ) 
      goto fail;

   /* copy shader tokens, the ones passed in will go away.
    */
   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
   if (state->shader.tokens == NULL)
      goto fail;

   state->draw_data = draw_create_vertex_shader(llvmpipe->draw, templ);
   if (state->draw_data == NULL) 
      goto fail;

   if (LP_DEBUG & DEBUG_TGSI) {
      debug_printf("llvmpipe: Create vertex shader %p:\n", (void *) state);
      tgsi_dump(templ->tokens, 0);
   }

   return state;

fail:
   if (state) {
      FREE( (void *)state->shader.tokens );
      FREE( state->draw_data );
      FREE( state );
   }
   return NULL;
}
コード例 #28
0
void
lp_build_tgsi_aos(struct gallivm_state *gallivm,
                  const struct tgsi_token *tokens,
                  struct lp_type type,
                  const unsigned char swizzles[4],
                  LLVMValueRef consts_ptr,
                  const LLVMValueRef *inputs,
                  LLVMValueRef *outputs,
                  struct lp_build_sampler_aos *sampler,
                  const struct tgsi_shader_info *info)
{
   struct lp_build_tgsi_aos_context bld;
   struct tgsi_parse_context parse;
   uint num_immediates = 0;
   unsigned chan;
   int pc = 0;

   /* Setup build context */
   memset(&bld, 0, sizeof bld);
   lp_build_context_init(&bld.bld_base.base, gallivm, type);
   lp_build_context_init(&bld.bld_base.uint_bld, gallivm, lp_uint_type(type));
   lp_build_context_init(&bld.bld_base.int_bld, gallivm, lp_int_type(type));
   lp_build_context_init(&bld.int_bld, gallivm, lp_int_type(type));

   for (chan = 0; chan < 4; ++chan) {
      bld.swizzles[chan] = swizzles[chan];
      bld.inv_swizzles[swizzles[chan]] = chan;
   }

   bld.inputs = inputs;
   bld.outputs = outputs;
   bld.consts_ptr = consts_ptr;
   bld.sampler = sampler;
   bld.indirect_files = info->indirect_files;
   bld.bld_base.emit_swizzle = swizzle_aos;
   bld.bld_base.info = info;

   bld.bld_base.emit_fetch_funcs[TGSI_FILE_CONSTANT] = emit_fetch_constant;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
   bld.bld_base.emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;

   /* Set opcode actions */
   lp_set_default_actions_cpu(&bld.bld_base);

   if (!lp_bld_tgsi_list_init(&bld.bld_base)) {
      return;
   }

   tgsi_parse_init(&parse, tokens);

   while (!tgsi_parse_end_of_tokens(&parse)) {
      tgsi_parse_token(&parse);

      switch(parse.FullToken.Token.Type) {
      case TGSI_TOKEN_TYPE_DECLARATION:
         /* Inputs already interpolated */
         lp_emit_declaration_aos(&bld, &parse.FullToken.FullDeclaration);
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         /* save expanded instruction */
         lp_bld_tgsi_add_instruction(&bld.bld_base,
                                     &parse.FullToken.FullInstruction);
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         /* simply copy the immediate values into the next immediates[] slot */
         {
            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
            float imm[4];
            assert(size <= 4);
            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
            for (chan = 0; chan < 4; ++chan) {
               imm[chan] = 0.0f;
            }
            for (chan = 0; chan < size; ++chan) {
               unsigned swizzle = bld.swizzles[chan];
               imm[swizzle] = parse.FullToken.FullImmediate.u[chan].Float;
            }
            bld.immediates[num_immediates] =
                     lp_build_const_aos(gallivm, type,
                                        imm[0], imm[1], imm[2], imm[3],
                                        NULL);
            num_immediates++;
         }
         break;

      case TGSI_TOKEN_TYPE_PROPERTY:
         break;

      default:
         assert(0);
      }
   }

   while (pc != -1) {
      struct tgsi_full_instruction *instr = bld.bld_base.instructions + pc;
      const struct tgsi_opcode_info *opcode_info =
         tgsi_get_opcode_info(instr->Instruction.Opcode);
      if (!lp_emit_instruction_aos(&bld, instr, opcode_info, &pc))
         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
                       opcode_info->mnemonic);
   }

   if (0) {
      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
      LLVMValueRef function = LLVMGetBasicBlockParent(block);
      debug_printf("11111111111111111111111111111 \n");
      tgsi_dump(tokens, 0);
      lp_debug_dump_value(function);
      debug_printf("2222222222222222222222222222 \n");
   }
   tgsi_parse_free(&parse);
   FREE(bld.bld_base.instructions);

   if (0) {
      LLVMModuleRef module = LLVMGetGlobalParent(
         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
      LLVMDumpModule(module);
   }

}
コード例 #29
0
static INLINE void
dump_info(const struct tgsi_token *tokens,
          struct lp_tgsi_info *info)
{
   unsigned index;
   unsigned chan;

   tgsi_dump(tokens, 0);

   for (index = 0; index < info->num_texs; ++index) {
      const struct lp_tgsi_texture_info *tex_info = &info->tex[index];
      debug_printf("TEX[%u] =", index);
      for (chan = 0; chan < 4; ++chan) {
         const struct lp_tgsi_channel_info *chan_info =
               &tex_info->coord[chan];
         if (chan_info->file != TGSI_FILE_NULL) {
            debug_printf(" %s[%u].%c",
                         tgsi_file_name(chan_info->file),
                         chan_info->u.index,
                         "xyzw01"[chan_info->swizzle]);
         } else {
            debug_printf(" _");
         }
      }
      debug_printf(", RES[%u], SAMP[%u], %s\n",
                   tex_info->texture_unit,
                   tex_info->sampler_unit,
                   tgsi_texture_names[tex_info->target]);
   }

   for (index = 0; index < PIPE_MAX_SHADER_OUTPUTS; ++index) {
      for (chan = 0; chan < 4; ++chan) {
         const struct lp_tgsi_channel_info *chan_info =
               &info->output[index][chan];
         if (chan_info->file != TGSI_FILE_NULL) {
            debug_printf("OUT[%u].%c = ", index, "xyzw"[chan]);
            if (chan_info->file == TGSI_FILE_IMMEDIATE) {
               debug_printf("%f", chan_info->u.value);
            } else {
               const char *file_name;
               switch (chan_info->file) {
               case TGSI_FILE_CONSTANT:
                  file_name = "CONST";
                  break;
               case TGSI_FILE_INPUT:
                  file_name = "IN";
                  break;
               default:
                  file_name = "???";
                  break;
               }
               debug_printf("%s[%u].%c",
                            file_name,
                            chan_info->u.index,
                            "xyzw01"[chan_info->swizzle]);
            }
            debug_printf("\n");
         }
      }
   }
}
コード例 #30
0
ファイル: st_program.c プロジェクト: ashmew2/kolibriosSVN
/**
 * Translate a geometry program to create a new variant.
 */
static struct st_gp_variant *
st_translate_geometry_program(struct st_context *st,
                              struct st_geometry_program *stgp,
                              const struct st_gp_variant_key *key)
{
   GLuint inputMapping[VARYING_SLOT_MAX];
   GLuint outputMapping[VARYING_SLOT_MAX];
   struct pipe_context *pipe = st->pipe;
   GLuint attr;

   uint gs_num_inputs = 0;

   ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
   ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];

   ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
   ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
   uint gs_num_outputs = 0;

   GLint i;
   struct ureg_program *ureg;
   struct pipe_shader_state state = {0};
   struct st_gp_variant *gpv;

   gpv = CALLOC_STRUCT(st_gp_variant);
   if (!gpv)
      return NULL;

   ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY);
   if (ureg == NULL) {
      free(gpv);
      return NULL;
   }

   memset(inputMapping, 0, sizeof(inputMapping));
   memset(outputMapping, 0, sizeof(outputMapping));

   /*
    * Convert Mesa program inputs to TGSI input register semantics.
    */
   for (attr = 0; attr < VARYING_SLOT_MAX; attr++) {
      if ((stgp->Base.Base.InputsRead & BITFIELD64_BIT(attr)) != 0) {
         const GLuint slot = gs_num_inputs++;

         inputMapping[attr] = slot;

         switch (attr) {
         case VARYING_SLOT_PRIMITIVE_ID:
            input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_POS:
            input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_COL0:
            input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_COL1:
            input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
            input_semantic_index[slot] = 1;
            break;
         case VARYING_SLOT_FOGC:
            input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_VERTEX:
            input_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_DIST0:
            input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_DIST1:
            input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
            input_semantic_index[slot] = 1;
            break;
         case VARYING_SLOT_PSIZ:
            input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
            input_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_TEX0:
         case VARYING_SLOT_TEX1:
         case VARYING_SLOT_TEX2:
         case VARYING_SLOT_TEX3:
         case VARYING_SLOT_TEX4:
         case VARYING_SLOT_TEX5:
         case VARYING_SLOT_TEX6:
         case VARYING_SLOT_TEX7:
            if (st->needs_texcoord_semantic) {
               input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
               input_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
               break;
            }
            /* fall through */
         case VARYING_SLOT_VAR0:
         default:
            assert(attr >= VARYING_SLOT_VAR0 && attr < VARYING_SLOT_MAX);
            input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
            input_semantic_index[slot] =
               st_get_generic_varying_index(st, attr);
         break;
         }
      }
   }

   /* initialize output semantics to defaults */
   for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
      gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
      gs_output_semantic_index[i] = 0;
   }

   /*
    * Determine number of outputs, the (default) output register
    * mapping and the semantic information for each output.
    */
   for (attr = 0; attr < VARYING_SLOT_MAX; attr++) {
      if (stgp->Base.Base.OutputsWritten & BITFIELD64_BIT(attr)) {
         GLuint slot = gs_num_outputs++;

         outputMapping[attr] = slot;

         switch (attr) {
         case VARYING_SLOT_POS:
            assert(slot == 0);
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_COL0:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_COL1:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
            gs_output_semantic_index[slot] = 1;
            break;
         case VARYING_SLOT_BFC0:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_BFC1:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
            gs_output_semantic_index[slot] = 1;
            break;
         case VARYING_SLOT_FOGC:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_PSIZ:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_VERTEX:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_DIST0:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_CLIP_DIST1:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
            gs_output_semantic_index[slot] = 1;
            break;
         case VARYING_SLOT_LAYER:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_LAYER;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_PRIMITIVE_ID:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_VIEWPORT:
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_VIEWPORT_INDEX;
            gs_output_semantic_index[slot] = 0;
            break;
         case VARYING_SLOT_TEX0:
         case VARYING_SLOT_TEX1:
         case VARYING_SLOT_TEX2:
         case VARYING_SLOT_TEX3:
         case VARYING_SLOT_TEX4:
         case VARYING_SLOT_TEX5:
         case VARYING_SLOT_TEX6:
         case VARYING_SLOT_TEX7:
            if (st->needs_texcoord_semantic) {
               gs_output_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
               gs_output_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
               break;
            }
            /* fall through */
         case VARYING_SLOT_VAR0:
         default:
            assert(slot < ARRAY_SIZE(gs_output_semantic_name));
            assert(attr >= VARYING_SLOT_VAR0);
            gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
            gs_output_semantic_index[slot] =
               st_get_generic_varying_index(st, attr);
         break;
         }
      }
   }

   ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, stgp->Base.InputType);
   ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, stgp->Base.OutputType);
   ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,
                 stgp->Base.VerticesOut);
   ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, stgp->Base.Invocations);

   st_translate_program(st->ctx,
                        TGSI_PROCESSOR_GEOMETRY,
                        ureg,
                        stgp->glsl_to_tgsi,
                        &stgp->Base.Base,
                        /* inputs */
                        gs_num_inputs,
                        inputMapping,
                        input_semantic_name,
                        input_semantic_index,
                        NULL,
                        NULL,
                        /* outputs */
                        gs_num_outputs,
                        outputMapping,
                        gs_output_semantic_name,
                        gs_output_semantic_index,
                        FALSE,
                        FALSE);

   state.tokens = ureg_get_tokens(ureg, NULL);
   ureg_destroy(ureg);

   st_translate_stream_output_info(stgp->glsl_to_tgsi,
                                   outputMapping,
                                   &state.stream_output);

   if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
      _mesa_print_program(&stgp->Base.Base);
      debug_printf("\n");
   }

   if (ST_DEBUG & DEBUG_TGSI) {
      tgsi_dump(state.tokens, 0);
      debug_printf("\n");
   }

   /* fill in new variant */
   gpv->driver_shader = pipe->create_gs_state(pipe, &state);
   gpv->key = *key;

   ureg_free_tokens(state.tokens);
   return gpv;
}