Пример #1
0
static INLINE void *
remote_context_create_vs_state(struct pipe_context *_pipe,
                              const struct pipe_shader_state *state)
{

    int tokens = tgsi_num_tokens(state->tokens);

    struct remreq_create_vs_state* header = 
	allocate_message_memory(
	    sizeof(struct remreq_create_vs_state) 
	  + (tokens * sizeof(struct tgsi_token)));
	  
    uint32_t handle = get_fresh_vs_handle(_pipe->screen);
    
    DBG("Create new VS state: handle %u\n", handle);
    
    header->base.opcode = REMREQ_CREATE_VS_STATE;
    header->pipe = PIPE_HANDLE(_pipe);
    header->vs_handle = handle;

    char* copy_dest = ((char*)header) + sizeof(struct remreq_create_vs_state);
    memcpy(copy_dest, (char*)(state->tokens), sizeof(struct tgsi_token) * tokens);
    
    enqueue_message(header);
    
    struct opaque_remote_vs* retval = CALLOC_STRUCT(opaque_remote_vs);
    
    PANIC_IF_NULL(retval);
    
    retval->handle = handle;
    
    return retval;

}
Пример #2
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;
}
Пример #3
0
/**
 * Make a new copy of a token array.
 */
struct tgsi_token *
tgsi_dup_tokens(const struct tgsi_token *tokens)
{
   unsigned n = tgsi_num_tokens(tokens);
   unsigned bytes = n * sizeof(struct tgsi_token);
   struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);
   if (new_tokens)
      memcpy(new_tokens, tokens, bytes);
   return new_tokens;
}
Пример #4
0
void
tgsi_dump_tokens(const struct tgsi_token *tokens)
{
   const unsigned *dwords = (const unsigned *)tokens;
   int nr = tgsi_num_tokens(tokens);
   int i;
   
   assert(sizeof(*tokens) == sizeof(unsigned));

   debug_printf("const unsigned tokens[%d] = {\n", nr);
   for (i = 0; i < nr; i++)
      debug_printf("0x%08x,\n", dwords[i]);
   debug_printf("};\n");
}
Пример #5
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;
}
Пример #6
0
enum pipe_error cso_set_fragment_shader(struct cso_context *ctx,
                                        const struct pipe_shader_state *templ)
{
   const struct tgsi_token *tokens = templ->tokens;
   unsigned num_tokens = tgsi_num_tokens(tokens);
   size_t tokens_size = num_tokens*sizeof(struct tgsi_token);
   unsigned hash_key = cso_construct_key((void*)tokens, tokens_size);
   struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
                                                       hash_key, 
                                                       CSO_FRAGMENT_SHADER,
                                                       (void*)tokens,
                                                       sizeof(*templ)); /* XXX correct? tokens_size? */
   void *handle = NULL;

   if (cso_hash_iter_is_null(iter)) {
      struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size);
      struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso));

      if (!cso)
         return PIPE_ERROR_OUT_OF_MEMORY;

      memcpy(cso_tokens, tokens, tokens_size);
      cso->state.tokens = cso_tokens;
      cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state);
      cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state;
      cso->context = ctx->pipe;

      iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso);
      if (cso_hash_iter_is_null(iter)) {
         FREE(cso);
         return PIPE_ERROR_OUT_OF_MEMORY;
      }

      handle = cso->data;
   }
   else {
      handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data;
   }

   return cso_set_fragment_shader_handle( ctx, handle );
}
Пример #7
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;
}
Пример #8
0
int virgl_encode_shader_state(struct virgl_context *ctx,
                              uint32_t handle,
                              uint32_t type,
                              const struct pipe_stream_output_info *so_info,
                              const struct tgsi_token *tokens)
{
   char *str, *sptr;
   uint32_t shader_len, len;
   bool bret;
   int num_tokens = tgsi_num_tokens(tokens);
   int str_total_size = 65536;
   int retry_size = 1;
   uint32_t left_bytes, base_hdr_size, strm_hdr_size, thispass;
   bool first_pass;
   str = CALLOC(1, str_total_size);
   if (!str)
      return -1;

   do {
      int old_size;

      bret = tgsi_dump_str(tokens, TGSI_DUMP_FLOAT_AS_HEX, str, str_total_size);
      if (bret == false) {
         fprintf(stderr, "Failed to translate shader in available space - trying again\n");
         old_size = str_total_size;
         str_total_size = 65536 * ++retry_size;
         str = REALLOC(str, old_size, str_total_size);
         if (!str)
            return -1;
      }
   } while (bret == false && retry_size < 10);

   if (bret == false)
      return -1;

   shader_len = strlen(str) + 1;

   left_bytes = shader_len;

   base_hdr_size = 5;
   strm_hdr_size = so_info->num_outputs ? so_info->num_outputs * 2 + 4 : 0;
   first_pass = true;
   sptr = str;
   while (left_bytes) {
      uint32_t length, offlen;
      int hdr_len = base_hdr_size + (first_pass ? strm_hdr_size : 0);
      if (ctx->cbuf->cdw + hdr_len + 1 > VIRGL_MAX_CMDBUF_DWORDS)
         ctx->base.flush(&ctx->base, NULL, 0);

      thispass = (VIRGL_MAX_CMDBUF_DWORDS - ctx->cbuf->cdw - hdr_len - 1) * 4;

      length = MIN2(thispass, left_bytes);
      len = ((length + 3) / 4) + hdr_len;

      if (first_pass)
         offlen = VIRGL_OBJ_SHADER_OFFSET_VAL(shader_len);
      else
         offlen = VIRGL_OBJ_SHADER_OFFSET_VAL((uintptr_t)sptr - (uintptr_t)str) | VIRGL_OBJ_SHADER_OFFSET_CONT;

      virgl_emit_shader_header(ctx, handle, len, type, offlen, num_tokens);

      virgl_emit_shader_streamout(ctx, first_pass ? so_info : NULL);

      virgl_encoder_write_block(ctx->cbuf, (uint8_t *)sptr, length);

      sptr += length;
      first_pass = false;
      left_bytes -= length;
   }

   FREE(str);
   return 0;
}
Пример #9
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;
}