예제 #1
0
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;
}
예제 #2
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)
{
   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
/*
 * 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;
}
예제 #4
0
/**
*	Convert the TGSI assembly to a runnable shader.
*
* We need not care about geometry shaders. All we have is screen quads.
*/
void *
pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
                 const char *name)
{
   struct pipe_shader_state state;
   struct tgsi_token *tokens = NULL;
   void *ret_state = NULL;
 
   /*
    * Allocate temporary token storage. State creation will duplicate
    * tokens so we must free them on exit.
    */ 
   tokens = tgsi_alloc_tokens(PP_MAX_TOKENS);

   if (!tokens) {
      pp_debug("Failed to allocate temporary token storage.\n");
      return NULL;
   }

   if (tgsi_text_translate(text, tokens, PP_MAX_TOKENS) == FALSE) {
      _debug_printf("pp: Failed to translate a shader for %s\n", name);
      return NULL;
   }

   state.tokens = tokens;
   memset(&state.stream_output, 0, sizeof(state.stream_output));

   if (isvs) {
      ret_state = pipe->create_vs_state(pipe, &state);
      FREE(tokens);
   } else {
      ret_state = pipe->create_fs_state(pipe, &state);
      FREE(tokens);
   }

   return ret_state;
}
예제 #5
0
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;
}