Ejemplo n.º 1
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct tgsi_shader_info *fsInfo = &llvmpipe->fs->info.base;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   int vs_index;
   uint i;

   draw_prepare_shader_outputs(llvmpipe->draw);

   /*
    * Those can't actually be 0 (because pos is always at 0).
    * But use ints anyway to avoid confusion (in vs outputs, they
    * can very well be at pos 0).
    */
   llvmpipe->color_slot[0] = -1;
   llvmpipe->color_slot[1] = -1;
   llvmpipe->bcolor_slot[0] = -1;
   llvmpipe->bcolor_slot[1] = -1;
   llvmpipe->viewport_index_slot = -1;
   llvmpipe->layer_slot = -1;
   llvmpipe->face_slot = -1;
   llvmpipe->psize_slot = -1;

   /*
    * Match FS inputs against VS outputs, emitting the necessary
    * attributes.  Could cache these structs and look them up with a
    * combination of fragment shader, vertex shader ids.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_POSITION, 0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);

   for (i = 0; i < fsInfo->num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         fsInfo->input_semantic_name[i],
                                         fsInfo->input_semantic_index[i]);

      if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
          fsInfo->input_semantic_index[i] < 2) {
         int idx = fsInfo->input_semantic_index[i];
         llvmpipe->color_slot[idx] = (int)vinfo->num_attribs;
      }

      if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_FACE) {
         llvmpipe->face_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      /*
       * For vp index and layer, if the fs requires them but the vs doesn't
       * provide them, draw (vbuf) will give us the required 0 (slot -1).
       * (This means in this case we'll also use those slots in setup, which
       * isn't necessary but they'll contain the correct (0) value.)
       */
      } else if (fsInfo->input_semantic_name[i] ==
                 TGSI_SEMANTIC_VIEWPORT_INDEX) {
         llvmpipe->viewport_index_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
         llvmpipe->layer_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      } else {
         /*
          * Note that we'd actually want to skip position (as we won't use
          * the attribute in the fs) but can't. The reason is that we don't
          * actually have a input/output map for setup (even though it looks
          * like we do...). Could adjust for this though even without a map
          * (in llvmpipe_create_fs_state()).
          */
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need bcolor as well.
    */
   for (i = 0; i < 2; i++) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_BCOLOR, i);

      if (vs_index >= 0) {
         llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index >= 0) {
      llvmpipe->psize_slot = (int)vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
   }

   /* Figure out if we need viewport index (if it wasn't already in fs input) */
   if (llvmpipe->viewport_index_slot < 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->viewport_index_slot =(int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   /* Figure out if we need layer (if it wasn't already in fs input) */
   if (llvmpipe->layer_slot < 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_LAYER,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->layer_slot = (int)vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
      }
   }

   draw_compute_vertex_size(vinfo);
   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
Ejemplo n.º 2
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
    const struct lp_fragment_shader *lpfs = llvmpipe->fs;
    struct vertex_info *vinfo = &llvmpipe->vertex_info;
    int vs_index;
    uint i;

    draw_prepare_shader_outputs(llvmpipe->draw);

    llvmpipe->color_slot[0] = -1;
    llvmpipe->color_slot[1] = -1;
    llvmpipe->bcolor_slot[0] = -1;
    llvmpipe->bcolor_slot[1] = -1;

    /*
     * Match FS inputs against VS outputs, emitting the necessary
     * attributes.  Could cache these structs and look them up with a
     * combination of fragment shader, vertex shader ids.
     */

    vinfo->num_attribs = 0;

    vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_POSITION,
                                       0);

    draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);

    for (i = 0; i < lpfs->info.base.num_inputs; i++) {
        /*
         * Search for each input in current vs output:
         */

        vs_index = draw_find_shader_output(llvmpipe->draw,
                                           lpfs->info.base.input_semantic_name[i],
                                           lpfs->info.base.input_semantic_index[i]);

        if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
                lpfs->info.base.input_semantic_index[i] < 2) {
            int idx = lpfs->info.base.input_semantic_index[i];
            llvmpipe->color_slot[idx] = (int)vinfo->num_attribs;
        }

        if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_FACE) {
            llvmpipe->face_slot = vinfo->num_attribs;
            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
        } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_PRIMID) {
            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
        } else {
            /*
             * Emit the requested fs attribute for all but position.
             */
            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
        }
    }
    /* Figure out if we need bcolor as well.
     */
    for (i = 0; i < 2; i++) {
        vs_index = draw_find_shader_output(llvmpipe->draw,
                                           TGSI_SEMANTIC_BCOLOR, i);

        if (vs_index >= 0) {
            llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs;
            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
        }
    }


    /* Figure out if we need pointsize as well.
     */
    vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_PSIZE, 0);

    if (vs_index >= 0) {
        llvmpipe->psize_slot = vinfo->num_attribs;
        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
    }

    /* Figure out if we need viewport index */
    vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_VIEWPORT_INDEX,
                                       0);
    if (vs_index >= 0) {
        llvmpipe->viewport_index_slot = vinfo->num_attribs;
        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
    } else {
        llvmpipe->viewport_index_slot = 0;
    }

    /* Figure out if we need layer */
    vs_index = draw_find_shader_output(llvmpipe->draw,
                                       TGSI_SEMANTIC_LAYER,
                                       0);
    if (vs_index >= 0) {
        llvmpipe->layer_slot = vinfo->num_attribs;
        draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
    } else {
        llvmpipe->layer_slot = 0;
    }

    draw_compute_vertex_size(vinfo);
    lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
Ejemplo n.º 3
0
/**
 * The vertex info describes how to convert the post-transformed vertices
 * (simple float[][4]) used by the 'draw' module into vertices for
 * rasterization.
 *
 * This function validates the vertex layout.
 */
static void
compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
   struct vertex_info *vinfo = &llvmpipe->vertex_info;
   int vs_index;
   uint i;

   draw_prepare_shader_outputs(llvmpipe->draw);

   llvmpipe->color_slot[0] = 0;
   llvmpipe->color_slot[1] = 0;
   llvmpipe->bcolor_slot[0] = 0;
   llvmpipe->bcolor_slot[1] = 0;
   llvmpipe->viewport_index_slot = 0;
   llvmpipe->layer_slot = 0;
   llvmpipe->face_slot = 0;
   llvmpipe->psize_slot = 0;

   /*
    * Match FS inputs against VS outputs, emitting the necessary
    * attributes.  Could cache these structs and look them up with a
    * combination of fragment shader, vertex shader ids.
    */

   vinfo->num_attribs = 0;

   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_POSITION,
                                      0);

   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);

   for (i = 0; i < lpfs->info.base.num_inputs; i++) {
      /*
       * Search for each input in current vs output:
       */

      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         lpfs->info.base.input_semantic_name[i],
                                         lpfs->info.base.input_semantic_index[i]);

      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
          lpfs->info.base.input_semantic_index[i] < 2) {
         int idx = lpfs->info.base.input_semantic_index[i];
         llvmpipe->color_slot[idx] = vinfo->num_attribs;
      }

      if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_FACE) {
         llvmpipe->face_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_PRIMID) {
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      /*
       * For vp index and layer, if the fs requires them but the vs doesn't
       * provide them, store the slot - we'll later replace the data directly
       * with zero (as required by ARB_fragment_layer_viewport). This is
       * because draw itself just redirects them to whatever was at output 0.
       * We'll also store the real vpindex/layer slot for setup use.
       */
      } else if (lpfs->info.base.input_semantic_name[i] ==
                 TGSI_SEMANTIC_VIEWPORT_INDEX) {
         if (vs_index >= 0) {
            llvmpipe->viewport_index_slot = vinfo->num_attribs;
         }
         else {
            llvmpipe->fake_vpindex_slot = vinfo->num_attribs;
         }
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
         if (vs_index >= 0) {
            llvmpipe->layer_slot = vinfo->num_attribs;
         }
         else {
            llvmpipe->fake_layer_slot = vinfo->num_attribs;
         }
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      } else {
         /*
          * Emit the requested fs attribute for all but position.
          */
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
      }
   }

   /* Figure out if we need bcolor as well.
    */
   for (i = 0; i < 2; i++) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_BCOLOR, i);

      if (vs_index >= 0) {
         llvmpipe->bcolor_slot[i] = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
      }
   }

   /* Figure out if we need pointsize as well.
    */
   vs_index = draw_find_shader_output(llvmpipe->draw,
                                      TGSI_SEMANTIC_PSIZE, 0);

   if (vs_index >= 0) {
      llvmpipe->psize_slot = vinfo->num_attribs;
      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
   }

   /* Figure out if we need viewport index (if it wasn't already in fs input) */
   if (llvmpipe->viewport_index_slot == 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->viewport_index_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      }
   }

   /* Figure out if we need layer (if it wasn't already in fs input) */
   if (llvmpipe->layer_slot == 0) {
      vs_index = draw_find_shader_output(llvmpipe->draw,
                                         TGSI_SEMANTIC_LAYER,
                                         0);
      if (vs_index >= 0) {
         llvmpipe->layer_slot = vinfo->num_attribs;
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
      }
   }

   draw_compute_vertex_size(vinfo);
   lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
}
Ejemplo n.º 4
0
enum pipe_error
svga_swtnl_update_vdecl( struct svga_context *svga )
{
   struct svga_vbuf_render *svga_render = svga_vbuf_render(svga->swtnl.backend);
   struct draw_context *draw = svga->swtnl.draw;
   struct vertex_info *vinfo = &svga_render->vertex_info;
   SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS];
   const enum interp_mode colorInterp =
      svga->curr.rast->templ.flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
   struct svga_fragment_shader *fs = svga->curr.fs;
   int offset = 0;
   int nr_decls = 0;
   int src;
   unsigned i;

   memset(vinfo, 0, sizeof(*vinfo));
   memset(vdecl, 0, sizeof(vdecl));

   draw_prepare_shader_outputs(draw);
   /* always add position */
   src = draw_find_shader_output(draw, TGSI_SEMANTIC_POSITION, 0);
   draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
   vinfo->attrib[0].emit = EMIT_4F;
   vdecl[0].array.offset = offset;
   vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4;
   vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT;
   vdecl[0].identity.usageIndex = 0;
   offset += 16;
   nr_decls++;

   for (i = 0; i < fs->base.info.num_inputs; i++) {
      const unsigned sem_name = fs->base.info.input_semantic_name[i];
      const unsigned sem_index = fs->base.info.input_semantic_index[i];

      src = draw_find_shader_output(draw, sem_name, sem_index);

      vdecl[nr_decls].array.offset = offset;
      vdecl[nr_decls].identity.usageIndex = sem_index;

      switch (sem_name) {
      case TGSI_SEMANTIC_COLOR:
         draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_COLOR;
         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
         offset += 16;
         nr_decls++;
         break;
      case TGSI_SEMANTIC_GENERIC:
         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4;
         vdecl[nr_decls].identity.usageIndex =
            svga_remap_generic_index(fs->generic_remap_table, sem_index);
         offset += 16;
         nr_decls++;
         break;
      case TGSI_SEMANTIC_FOG:
         draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
         vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD;
         vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT1;
         assert(vdecl[nr_decls].identity.usageIndex == 0);
         offset += 4;
         nr_decls++;
         break;
      case TGSI_SEMANTIC_POSITION:
         /* generated internally, not a vertex shader output */
         break;
      default:
         assert(0);
      }
   }

   draw_compute_vertex_size(vinfo);

   svga_render->vdecl_count = nr_decls;
   for (i = 0; i < svga_render->vdecl_count; i++)
      vdecl[i].array.stride = offset;

   if (memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)) == 0)
      return PIPE_OK;

   memcpy(svga_render->vdecl, vdecl, sizeof(vdecl));
   svga->swtnl.new_vdecl = TRUE;

   return PIPE_OK;
}