Example #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;
}
/**
 * Create vertex shader state.
 * Called via pipe->create_vs_state()
 */
static void *
cell_create_vs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct cell_context *cell = cell_context(pipe);
   struct cell_vertex_shader_state *cvs;

   cvs = CALLOC_STRUCT(cell_vertex_shader_state);
   if (!cvs)
      return NULL;

   cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
   if (!cvs->shader.tokens) {
      FREE(cvs);
      return NULL;
   }

   tgsi_scan_shader(templ->tokens, &cvs->info);

   cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
   if (cvs->draw_data == NULL) {
      FREE( (void *) cvs->shader.tokens );
      FREE( cvs );
      return NULL;
   }

   return cvs;
}
Example #3
0
static void *
svga_create_gs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_geometry_shader *gs = CALLOC_STRUCT(svga_geometry_shader);

   if (!gs)
      return NULL;

   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEGS);

   gs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(gs->base.tokens, &gs->base.info);

   gs->draw_shader = draw_create_geometry_shader(svga->swtnl.draw, templ);

   gs->base.id = svga->debug.shader_id++;

   gs->generic_outputs = svga_get_generic_outputs_mask(&gs->base.info);

   /* check for any stream output declarations */
   if (templ->stream_output.num_outputs) {
      gs->base.stream_output = svga_create_stream_output(svga, &gs->base,
                                                         &templ->stream_output);
   }

   SVGA_STATS_TIME_POP(svga_sws(svga));
   return gs;
}
Example #4
0
static void *
svga_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_fragment_shader *fs;

   fs = CALLOC_STRUCT(svga_fragment_shader);
   if (!fs)
      return NULL;

   fs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(fs->base.tokens, &fs->base.info);

   fs->base.id = svga->debug.shader_id++;
   
   fs->generic_inputs = svga_get_generic_inputs_mask(&fs->base.info);

   svga_remap_generics(fs->generic_inputs, fs->generic_remap_table);

   fs->draw_shader = draw_create_fragment_shader(svga->swtnl.draw, templ);

   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
                   __FUNCTION__, fs->base.id,
                   fs->base.info.num_inputs, fs->base.info.num_outputs);
   }

   return fs;
}
Example #5
0
static void *
svga_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *svgascreen = svga_screen(pipe->screen);
   struct svga_fragment_shader *fs;

   fs = CALLOC_STRUCT(svga_fragment_shader);
   if (!fs)
      return NULL;

   fs->base.tokens = tgsi_dup_tokens(templ->tokens);

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(fs->base.tokens, &fs->base.info);

   fs->base.id = svga->debug.shader_id++;
   fs->base.use_sm30 = svgascreen->use_ps30;
   
   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
                   __FUNCTION__, fs->base.id,
                   fs->base.info.num_inputs, fs->base.info.num_outputs);
   }

   return fs;
}
Example #6
0
LLVMModuleRef r600_tgsi_llvm(
	struct radeon_llvm_context * ctx,
	const struct tgsi_token * tokens)
{
	struct tgsi_shader_info shader_info;
	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
	radeon_llvm_context_init(ctx);
	tgsi_scan_shader(tokens, &shader_info);

	bld_base->info = &shader_info;
	bld_base->userdata = ctx;
	bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = llvm_fetch_const;
	bld_base->emit_prologue = llvm_emit_prologue;
	bld_base->emit_epilogue = llvm_emit_epilogue;
	ctx->userdata = ctx;
	ctx->load_input = llvm_load_input;

	bld_base->op_actions[TGSI_OPCODE_DP2] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DP3] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DP4] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DPH] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_TEX].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXB].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXD].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXL].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXP].fetch_args = txp_fetch_args;
	bld_base->op_actions[TGSI_OPCODE_TXP].emit = llvm_emit_tex;

	lp_build_tgsi_llvm(bld_base, tokens);

	radeon_llvm_finalize_module(ctx);

	return ctx->gallivm.module;
}
LLVMModuleRef r600_tgsi_llvm(
	struct radeon_llvm_context * ctx,
	const struct tgsi_token * tokens)
{
	struct tgsi_shader_info shader_info;
	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
	radeon_llvm_context_init(ctx);
#if HAVE_LLVM >= 0x0304
	LLVMTypeRef Arguments[32];
	unsigned ArgumentsCount = 0;
	for (unsigned i = 0; i < ctx->inputs_count; i++)
		Arguments[ArgumentsCount++] = LLVMVectorType(bld_base->base.elem_type, 4);
	radeon_llvm_create_func(ctx, Arguments, ArgumentsCount);
	for (unsigned i = 0; i < ctx->inputs_count; i++) {
		LLVMValueRef P = LLVMGetParam(ctx->main_fn, i);
		LLVMAddAttribute(P, LLVMInRegAttribute);
	}
#else
	radeon_llvm_create_func(ctx, NULL, 0);
#endif
	tgsi_scan_shader(tokens, &shader_info);

	bld_base->info = &shader_info;
	bld_base->userdata = ctx;
	bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = llvm_fetch_const;
	bld_base->emit_prologue = llvm_emit_prologue;
	bld_base->emit_epilogue = llvm_emit_epilogue;
	ctx->userdata = ctx;
	ctx->load_input = llvm_load_input;
	ctx->load_system_value = llvm_load_system_value;

	bld_base->op_actions[TGSI_OPCODE_DP2] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DP3] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DP4] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DPH] = dot_action;
	bld_base->op_actions[TGSI_OPCODE_DDX].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_DDY].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TEX].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TEX2].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXB].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXB2].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXD].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXL].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXL2].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXF].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXQ].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_TXP].emit = llvm_emit_tex;
	bld_base->op_actions[TGSI_OPCODE_CMP].emit = emit_cndlt;

	lp_build_tgsi_llvm(bld_base, tokens);

	radeon_llvm_finalize_module(ctx);

	return ctx->gallivm.module;
}
Example #8
0
static void *
nv50_gp_state_create(struct pipe_context *pipe,
                     const struct pipe_shader_state *cso)
{
    struct nv50_program *p = CALLOC_STRUCT(nv50_program);

    p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
    p->type = PIPE_SHADER_GEOMETRY;
    tgsi_scan_shader(p->pipe.tokens, &p->info);
    return (void *)p;
}
Example #9
0
static int
nv30_fp(int chipset, struct tgsi_token tokens[],
        unsigned *size, unsigned **code) {
   struct nv30_fragprog fp;
   memset(&fp, 0, sizeof(fp));
   fp.pipe.tokens = tokens;
   tgsi_scan_shader(fp.pipe.tokens, &fp.info);
   _nvfx_fragprog_translate(chipset >= 0x40 ? 0x4097 : 0x3097, &fp);
   *size = fp.insn_len * 4;
   *code = fp.insn;
   return !fp.translated;
}
Example #10
0
struct draw_geometry_shader *
draw_create_geometry_shader(struct draw_context *draw,
                            const struct pipe_shader_state *state)
{
   struct draw_geometry_shader *gs;
   int i;

   gs = CALLOC_STRUCT(draw_geometry_shader);

   if (!gs)
      return NULL;

   gs->draw = draw;
   gs->state = *state;
   gs->state.tokens = tgsi_dup_tokens(state->tokens);
   if (!gs->state.tokens) {
      FREE(gs);
      return NULL;
   }

   tgsi_scan_shader(state->tokens, &gs->info);

   /* setup the defaults */
   gs->input_primitive = PIPE_PRIM_TRIANGLES;
   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
   gs->max_output_vertices = 32;

   for (i = 0; i < gs->info.num_properties; ++i) {
      if (gs->info.properties[i].name ==
          TGSI_PROPERTY_GS_INPUT_PRIM)
         gs->input_primitive = gs->info.properties[i].data[0];
      else if (gs->info.properties[i].name ==
               TGSI_PROPERTY_GS_OUTPUT_PRIM)
         gs->output_primitive = gs->info.properties[i].data[0];
      else if (gs->info.properties[i].name ==
               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
         gs->max_output_vertices = gs->info.properties[i].data[0];
   }

   gs->machine = draw->gs.tgsi.machine;

   if (gs)
   {
      uint i;
      for (i = 0; i < gs->info.num_outputs; i++) {
         if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
             gs->info.output_semantic_index[i] == 0)
            gs->position_output = i;
      }
   }

   return gs;
}
Example #11
0
static void *
nv30_vp_state_create(struct pipe_context *pipe,
                     const struct pipe_shader_state *cso)
{
   struct nv30_vertprog *vp = CALLOC_STRUCT(nv30_vertprog);
   if (!vp)
      return NULL;

   vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
   tgsi_scan_shader(vp->pipe.tokens, &vp->info);
   return vp;
}
Example #12
0
static void *
nv30_fp_state_create(struct pipe_context *pipe,
                     const struct pipe_shader_state *cso)
{
   struct nv30_fragprog *fp = CALLOC_STRUCT(nv30_fragprog);
   if (!fp)
      return NULL;

   fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
   tgsi_scan_shader(fp->pipe.tokens, &fp->info);
   return fp;
}
Example #13
0
static void *
nv40_fp_state_create(struct pipe_context *pipe,
		     const struct pipe_shader_state *cso)
{
	struct nv40_fragment_program *fp;

	fp = CALLOC(1, sizeof(struct nv40_fragment_program));
	fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);

	tgsi_scan_shader(fp->pipe.tokens, &fp->info);

	return (void *)fp;
}
Example #14
0
static int
nv30_vp(int chipset, struct tgsi_token tokens[],
        unsigned *size, unsigned **code) {
   struct nv30_vertprog vp;
   memset(&vp, 0, sizeof(vp));

   vp.pipe.tokens = tokens;
   tgsi_scan_shader(vp.pipe.tokens, &vp.info);
   _nvfx_vertprog_translate(chipset >= 0x40 ? 0x4097 : 0x3097, &vp);
   *size = vp.nr_insns * 16;
   *code = (unsigned *)vp.insns;
   return !vp.translated;
}
Example #15
0
struct draw_fragment_shader *
draw_create_fragment_shader(struct draw_context *draw,
                            const struct pipe_shader_state *shader)
{
   struct draw_fragment_shader *dfs;

   dfs = CALLOC_STRUCT(draw_fragment_shader);
   if (dfs) {
      dfs->base = *shader;
      tgsi_scan_shader(shader->tokens, &dfs->info);
   }

   return dfs;
}
Example #16
0
/* Create fragment shader state. */
static void* r300_create_fs_state(struct pipe_context* pipe,
                                  const struct pipe_shader_state* shader)
{
    struct r300_fragment_shader* fs = NULL;

    fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);

    /* Copy state directly into shader. */
    fs->state = *shader;
    fs->state.tokens = tgsi_dup_tokens(shader->tokens);

    tgsi_scan_shader(shader->tokens, &fs->info);

    return (void*)fs;
}
Example #17
0
/**
 * Create a new fragment shader variant.
 */
static struct sp_fragment_shader_variant *
create_fs_variant(struct softpipe_context *softpipe,
                  struct sp_fragment_shader *fs,
                  const struct sp_fragment_shader_variant_key *key)
{
   struct sp_fragment_shader_variant *var;
   struct pipe_shader_state *curfs = &fs->shader;

   /* codegen, create variant object */
   var = softpipe_create_fs_variant_exec(softpipe);

   if (var) {
      var->key = *key;

#if DO_PSTIPPLE_IN_HELPER_MODULE
      if (key->polygon_stipple) {
         /* get new shader that implements polygon stippling */
         var->tokens = 
            util_pstipple_create_fragment_shader(curfs->tokens,
                                                 &var->stipple_sampler_unit, 0,
                                                 TGSI_FILE_INPUT);
      }
      else
#endif
      {
         var->tokens = tgsi_dup_tokens(curfs->tokens);
         var->stipple_sampler_unit = 0;
      }

      tgsi_scan_shader(var->tokens, &var->info);

      /* See comments elsewhere about draw fragment shaders */
#if 0
      /* draw's fs state */
      var->draw_shader = draw_create_fragment_shader(softpipe->draw,
                                                     &fs->shader);
      if (!var->draw_shader) {
         var->delete(var);
         FREE((void *) var->tokens);
         return NULL;
      }
#endif

      /* insert variant into linked list */
      var->next = fs->variants;
      fs->variants = var;
   }
static void *brw_create_fs_state( struct pipe_context *pipe,
				  const struct pipe_shader_state *shader )
{
   struct brw_context *brw = brw_context(pipe);
   struct brw_fragment_shader *fs;
   int i;

   fs = CALLOC_STRUCT(brw_fragment_shader);
   if (fs == NULL)
      return NULL;

   /* Duplicate tokens, scan shader
    */
   fs->id = brw->program_id++;
   fs->has_flow_control = has_flow_control(&fs->info);

   fs->tokens = tgsi_dup_tokens(shader->tokens);
   if (fs->tokens == NULL)
      goto fail;

   tgsi_scan_shader(fs->tokens, &fs->info);
   scan_immediates(fs->tokens, &fs->info, &fs->immediates);

   fs->signature.nr_inputs = fs->info.num_inputs;
   for (i = 0; i < fs->info.num_inputs; i++) {
      fs->signature.input[i].interp = fs->info.input_interpolate[i];
      fs->signature.input[i].semantic = fs->info.input_semantic_name[i];
      fs->signature.input[i].semantic_index = fs->info.input_semantic_index[i];
   }

   for (i = 0; i < fs->info.num_inputs; i++)
      if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_POSITION)
	 fs->uses_depth = 1;

   if (fs->info.uses_kill)
      fs->iz_lookup |= IZ_PS_KILL_ALPHATEST_BIT;

   if (fs->info.writes_z)
      fs->iz_lookup |= IZ_PS_COMPUTES_DEPTH_BIT;

   return (void *)fs;

fail:
   FREE(fs);
   return NULL;
}
Example #19
0
static void *
i915_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct i915_context *i915 = i915_context(pipe);
   struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader);
   if (!ifs)
      return NULL;

   ifs->state.tokens = tgsi_dup_tokens(templ->tokens);

   tgsi_scan_shader(templ->tokens, &ifs->info);

   /* The shader's compiled to i915 instructions here */
   i915_translate_fragment_program(i915, ifs);

   return ifs;
}
Example #20
0
static unsigned
dd_num_active_viewports(struct dd_context *dctx)
{
   struct tgsi_shader_info info;
   const struct tgsi_token *tokens;

   if (dctx->shaders[PIPE_SHADER_GEOMETRY])
      tokens = dctx->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens;
   else if (dctx->shaders[PIPE_SHADER_TESS_EVAL])
      tokens = dctx->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens;
   else if (dctx->shaders[PIPE_SHADER_VERTEX])
      tokens = dctx->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens;
   else
      return 1;

   tgsi_scan_shader(tokens, &info);
   return info.writes_viewport_index ? PIPE_MAX_VIEWPORTS : 1;
}
Example #21
0
void *
llvmpipe_create_fs_state(struct pipe_context *pipe,
                         const struct pipe_shader_state *templ)
{
   struct lp_fragment_shader *shader;

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

   /* 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);

   return shader;
}
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;
}
Example #23
0
static void *
svga_create_vs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_vertex_shader *vs = CALLOC_STRUCT(svga_vertex_shader);

   if (!vs)
      return NULL;

   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEVS);         

   /* substitute a debug shader?
    */
   vs->base.tokens = tgsi_dup_tokens(substitute_vs(svga->debug.shader_id,
                                                   templ->tokens));

   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(vs->base.tokens, &vs->base.info);

   {
      /* Need to do construct a new template in case we substitued a
       * debug shader.
       */
      struct pipe_shader_state tmp2 = *templ;
      tmp2.tokens = vs->base.tokens;
      vs->draw_shader = draw_create_vertex_shader(svga->swtnl.draw, &tmp2);
   }

   vs->base.id = svga->debug.shader_id++;

   vs->generic_outputs = svga_get_generic_outputs_mask(&vs->base.info);

   /* check for any stream output declarations */
   if (templ->stream_output.num_outputs) {
      vs->base.stream_output = svga_create_stream_output(svga, &vs->base,
                                                         &templ->stream_output);
   }

   SVGA_STATS_TIME_POP(svga_sws(svga));
   return vs;
}
Example #24
0
static void* r300_create_vs_state(struct pipe_context* pipe,
                                  const struct pipe_shader_state* shader)
{
    struct r300_context* r300 = r300_context(pipe);

    if (r300_screen(pipe->screen)->caps->has_tcl) {
        struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
        /* Copy state directly into shader. */
        vs->state = *shader;
        vs->state.tokens = tgsi_dup_tokens(shader->tokens);

        tgsi_scan_shader(shader->tokens, &vs->info);

        /* Appease Draw. */
        vs->draw = draw_create_vertex_shader(r300->draw, shader);

        return (void*)vs;
    } else {
        return draw_create_vertex_shader(r300->draw, shader);
    }
}
Example #25
0
static void *
svga_create_vs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *svgascreen = svga_screen(pipe->screen);
   struct svga_vertex_shader *vs = CALLOC_STRUCT(svga_vertex_shader);
   if (!vs)
      return NULL;

   /* substitute a debug shader?
    */
   vs->base.tokens = tgsi_dup_tokens(substitute_vs(svga->debug.shader_id,
                                                   templ->tokens));


   /* Collect basic info that we'll need later:
    */
   tgsi_scan_shader(vs->base.tokens, &vs->base.info);

   {
      /* Need to do construct a new template in case we substitued a
       * debug shader.
       */
      struct pipe_shader_state tmp2 = *templ;
      tmp2.tokens = vs->base.tokens;
      vs->draw_shader = draw_create_vertex_shader(svga->swtnl.draw, &tmp2);
   }

   vs->base.id = svga->debug.shader_id++;
   vs->base.use_sm30 = svgascreen->use_vs30;

   if (SVGA_DEBUG & DEBUG_TGSI || 0) {
      debug_printf("%s id: %u, inputs: %u, outputs: %u\n",
                   __FUNCTION__, vs->base.id,
                   vs->base.info.num_inputs, vs->base.info.num_outputs);
   }

   return vs;
}
Example #26
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;
}
/**
 * Create fragment shader state.
 * Called via pipe->create_fs_state()
 */
static void *
cell_create_fs_state(struct pipe_context *pipe,
                     const struct pipe_shader_state *templ)
{
   struct cell_context *cell = cell_context(pipe);
   struct cell_fragment_shader_state *cfs;

   cfs = CALLOC_STRUCT(cell_fragment_shader_state);
   if (!cfs)
      return NULL;

   cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
   if (!cfs->shader.tokens) {
      FREE(cfs);
      return NULL;
   }

   tgsi_scan_shader(templ->tokens, &cfs->info);

   cell_gen_fragment_program(cell, cfs->shader.tokens, &cfs->code);

   return cfs;
}
Example #28
0
struct draw_geometry_shader *
draw_create_geometry_shader(struct draw_context *draw,
                            const struct pipe_shader_state *state)
{
#ifdef HAVE_LLVM
   boolean use_llvm = draw_get_option_use_llvm();
   struct llvm_geometry_shader *llvm_gs;
#endif
   struct draw_geometry_shader *gs;
   unsigned i;

#ifdef HAVE_LLVM
   if (use_llvm) {
      llvm_gs = CALLOC_STRUCT(llvm_geometry_shader);

      if (llvm_gs == NULL)
         return NULL;

      gs = &llvm_gs->base;

      make_empty_list(&llvm_gs->variants);
   } else
#endif
   {
      gs = CALLOC_STRUCT(draw_geometry_shader);
   }

   if (!gs)
      return NULL;

   gs->draw = draw;
   gs->state = *state;
   gs->state.tokens = tgsi_dup_tokens(state->tokens);
   if (!gs->state.tokens) {
      FREE(gs);
      return NULL;
   }

   tgsi_scan_shader(state->tokens, &gs->info);

   /* setup the defaults */
   gs->input_primitive = PIPE_PRIM_TRIANGLES;
   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
   gs->max_output_vertices = 32;
   gs->max_out_prims = 0;

#ifdef HAVE_LLVM
   if (use_llvm) {
      /* TODO: change the input array to handle the following
         vector length, instead of the currently hardcoded
         TGSI_NUM_CHANNELS
      gs->vector_length = lp_native_vector_width / 32;*/
      gs->vector_length = TGSI_NUM_CHANNELS;
   } else
#endif
   {
      gs->vector_length = 1;
   }

   for (i = 0; i < gs->info.num_properties; ++i) {
      if (gs->info.properties[i].name ==
          TGSI_PROPERTY_GS_INPUT_PRIM)
         gs->input_primitive = gs->info.properties[i].data[0];
      else if (gs->info.properties[i].name ==
               TGSI_PROPERTY_GS_OUTPUT_PRIM)
         gs->output_primitive = gs->info.properties[i].data[0];
      else if (gs->info.properties[i].name ==
               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
         gs->max_output_vertices = gs->info.properties[i].data[0];
   }
   /* Primitive boundary is bigger than max_output_vertices by one, because
    * the specification says that the geometry shader should exit if the 
    * number of emitted vertices is bigger or equal to max_output_vertices and
    * we can't do that because we're running in the SoA mode, which means that
    * our storing routines will keep getting called on channels that have
    * overflown.
    * So we need some scratch area where we can keep writing the overflown 
    * vertices without overwriting anything important or crashing.
    */
   gs->primitive_boundary = gs->max_output_vertices + 1;

   for (i = 0; i < gs->info.num_outputs; i++) {
      if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
          gs->info.output_semantic_index[i] == 0)
         gs->position_output = i;
      if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
         gs->viewport_index_output = i;
      if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
         debug_assert(gs->info.output_semantic_index[i] <
                      PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
         gs->clipdistance_output[gs->info.output_semantic_index[i]] = i;
      }
      if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_CULLDIST) {
         debug_assert(gs->info.output_semantic_index[i] <
                      PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
         gs->culldistance_output[gs->info.output_semantic_index[i]] = i;
      }
   }

   gs->machine = draw->gs.tgsi.machine;

#ifdef HAVE_LLVM
   if (use_llvm) {
      int vector_size = gs->vector_length * sizeof(float);
      gs->gs_input = align_malloc(sizeof(struct draw_gs_inputs), 16);
      memset(gs->gs_input, 0, sizeof(struct draw_gs_inputs));
      gs->llvm_prim_lengths = 0;

      gs->llvm_emitted_primitives = align_malloc(vector_size, vector_size);
      gs->llvm_emitted_vertices = align_malloc(vector_size, vector_size);
      gs->llvm_prim_ids = align_malloc(vector_size, vector_size);

      gs->fetch_outputs = llvm_fetch_gs_outputs;
      gs->fetch_inputs = llvm_fetch_gs_input;
      gs->prepare = llvm_gs_prepare;
      gs->run = llvm_gs_run;

      gs->jit_context = &draw->llvm->gs_jit_context;


      llvm_gs->variant_key_size =
         draw_gs_llvm_variant_key_size(
            MAX2(gs->info.file_max[TGSI_FILE_SAMPLER]+1,
                 gs->info.file_max[TGSI_FILE_SAMPLER_VIEW]+1));
   } else
#endif
   {
      gs->fetch_outputs = tgsi_fetch_gs_outputs;
      gs->fetch_inputs = tgsi_fetch_gs_input;
      gs->prepare = tgsi_gs_prepare;
      gs->run = tgsi_gs_run;
   }

   return gs;
}
Example #29
0
static void *si_create_compute_state(
	struct pipe_context *ctx,
	const struct pipe_compute_state *cso)
{
	struct si_context *sctx = (struct si_context *)ctx;
	struct si_screen *sscreen = (struct si_screen *)ctx->screen;
	struct si_compute *program = CALLOC_STRUCT(si_compute);
	struct si_shader *shader = &program->shader;


	program->ir_type = cso->ir_type;
	program->local_size = cso->req_local_mem;
	program->private_size = cso->req_private_mem;
	program->input_size = cso->req_input_mem;
	program->use_code_object_v2 = HAVE_LLVM >= 0x0400 &&
					cso->ir_type == PIPE_SHADER_IR_NATIVE;


	if (cso->ir_type == PIPE_SHADER_IR_TGSI) {
		struct si_shader_selector sel;
		bool scratch_enabled;

		memset(&sel, 0, sizeof(sel));

		sel.tokens = tgsi_dup_tokens(cso->prog);
		if (!sel.tokens) {
			FREE(program);
			return NULL;
		}

		tgsi_scan_shader(cso->prog, &sel.info);
		sel.type = PIPE_SHADER_COMPUTE;
		sel.local_size = cso->req_local_mem;

		p_atomic_inc(&sscreen->b.num_shaders_created);

		program->shader.selector = &sel;

		if (si_shader_create(sscreen, sctx->tm, &program->shader,
		                     &sctx->b.debug)) {
			FREE(sel.tokens);
			FREE(program);
			return NULL;
		}

		scratch_enabled = shader->config.scratch_bytes_per_wave > 0;

		shader->config.rsrc1 =
			   S_00B848_VGPRS((shader->config.num_vgprs - 1) / 4) |
			   S_00B848_SGPRS((shader->config.num_sgprs - 1) / 8) |
			   S_00B848_DX10_CLAMP(1) |
			   S_00B848_FLOAT_MODE(shader->config.float_mode);

		shader->config.rsrc2 = S_00B84C_USER_SGPR(SI_CS_NUM_USER_SGPR) |
			   S_00B84C_SCRATCH_EN(scratch_enabled) |
			   S_00B84C_TGID_X_EN(1) | S_00B84C_TGID_Y_EN(1) |
			   S_00B84C_TGID_Z_EN(1) | S_00B84C_TIDIG_COMP_CNT(2) |
			   S_00B84C_LDS_SIZE(shader->config.lds_size);

		FREE(sel.tokens);
	} else {
		const struct pipe_llvm_program_header *header;
		const char *code;
		header = cso->prog;
		code = cso->prog + sizeof(struct pipe_llvm_program_header);

		radeon_elf_read(code, header->num_bytes, &program->shader.binary);
		if (program->use_code_object_v2) {
			const amd_kernel_code_t *code_object =
				si_compute_get_code_object(program, 0);
			code_object_to_config(code_object, &program->shader.config);
		} else {
			si_shader_binary_read_config(&program->shader.binary,
				     &program->shader.config, 0);
		}
		si_shader_dump(sctx->screen, &program->shader, &sctx->b.debug,
			       PIPE_SHADER_COMPUTE, stderr);
		si_shader_binary_upload(sctx->screen, &program->shader);
	}

	return program;
}
/**
 * Detect any direct relationship between the output color
 */
void
lp_build_tgsi_info(const struct tgsi_token *tokens,
                   struct lp_tgsi_info *info)
{
   struct tgsi_parse_context parse;
   struct analysis_context ctx;
   unsigned index;
   unsigned chan;

   memset(info, 0, sizeof *info);

   tgsi_scan_shader(tokens, &info->base);

   memset(&ctx, 0, sizeof ctx);
   ctx.info = info;

   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:
         break;

      case TGSI_TOKEN_TYPE_INSTRUCTION:
         {
            struct tgsi_full_instruction *inst =
                  &parse.FullToken.FullInstruction;

            if (inst->Instruction.Opcode == TGSI_OPCODE_END ||
                inst->Instruction.Opcode == TGSI_OPCODE_BGNSUB) {
               /* We reached the end of main function body. */
               goto finished;
            }

            analyse_instruction(&ctx, inst);
         }
         break;

      case TGSI_TOKEN_TYPE_IMMEDIATE:
         {
            const unsigned size =
                  parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
            assert(size <= 4);
            if (ctx.num_imms < Elements(ctx.imm)) {
               for (chan = 0; chan < size; ++chan) {
                  float value = parse.FullToken.FullImmediate.u[chan].Float;
                  ctx.imm[ctx.num_imms][chan] = value;

                  if (value < 0.0f || value > 1.0f) {
                     info->unclamped_immediates = TRUE;
                  }
               }
               ++ctx.num_imms;
            }
         }
         break;

      case TGSI_TOKEN_TYPE_PROPERTY:
         break;

      default:
         assert(0);
      }
   }
finished:

   tgsi_parse_free(&parse);


   /*
    * Link the output color values.
    */

   for (index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) {
      const struct lp_tgsi_channel_info null_output[4];
      info->cbuf[index] = null_output;
   }

   for (index = 0; index < info->base.num_outputs; ++index) {
      unsigned semantic_name = info->base.output_semantic_name[index];
      unsigned semantic_index = info->base.output_semantic_index[index];
      if (semantic_name == TGSI_SEMANTIC_COLOR &&
          semantic_index < PIPE_MAX_COLOR_BUFS) {
         info->cbuf[semantic_index] = info->output[index];
      }
   }

   if (gallivm_debug & GALLIVM_DEBUG_TGSI) {
      dump_info(tokens, info);
   }
}