コード例 #1
0
ファイル: sp_setup.c プロジェクト: nikai3d/mesa
/**
 * Called by vbuf code just before we start buffering primitives.
 */
void
sp_setup_prepare(struct setup_context *setup)
{
   struct softpipe_context *sp = setup->softpipe;

   if (sp->dirty) {
      softpipe_update_derived(sp, sp->reduced_api_prim);
   }

   /* Note: nr_attrs is only used for debugging (vertex printing) */
   setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);

   sp->quad.first->begin( sp->quad.first );

   if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
       sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL &&
       sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) {
      /* we'll do culling */
      setup->cull_face = sp->rasterizer->cull_face;
   }
   else {
      /* 'draw' will do culling */
      setup->cull_face = PIPE_FACE_NONE;
   }
}
コード例 #2
0
ファイル: sp_setup.c プロジェクト: ChristophHaag/mesa-mesa
/**
 * Called by vbuf code just before we start buffering primitives.
 */
void
sp_setup_prepare(struct setup_context *setup)
{
   struct softpipe_context *sp = setup->softpipe;
   int i;
   unsigned max_layer = ~0;
   if (sp->dirty) {
      softpipe_update_derived(sp, sp->reduced_api_prim);
   }

   /* Note: nr_attrs is only used for debugging (vertex printing) */
   setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);

   /*
    * Determine how many layers the fb has (used for clamping layer value).
    * OpenGL (but not d3d10) permits different amount of layers per rt, however
    * results are undefined if layer exceeds the amount of layers of ANY
    * attachment hence don't need separate per cbuf and zsbuf max.
    */
   for (i = 0; i < setup->softpipe->framebuffer.nr_cbufs; i++) {
      struct pipe_surface *cbuf = setup->softpipe->framebuffer.cbufs[i];
      if (cbuf) {
         max_layer = MIN2(max_layer,
                          cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);

      }
   }

   /* Prepare pixel offset for rasterisation:
    *  - pixel center (0.5, 0.5) for GL, or
    *  - assume (0.0, 0.0) for other APIs.
    */
   if (setup->softpipe->rasterizer->half_pixel_center) {
      setup->pixel_offset = 0.5f;
   } else {
      setup->pixel_offset = 0.0f;
   }

   setup->max_layer = max_layer;

   sp->quad.first->begin( sp->quad.first );

   if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
       sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL &&
       sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) {
      /* we'll do culling */
      setup->cull_face = sp->rasterizer->cull_face;
   }
   else {
      /* 'draw' will do culling */
      setup->cull_face = PIPE_FACE_NONE;
   }
}
コード例 #3
0
ファイル: sp_state_derived.c プロジェクト: altf4/mesa
/**
 * 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 and returns a pointer to a
 * vertex_info object.
 */
struct vertex_info *
softpipe_get_vertex_info(struct softpipe_context *softpipe)
{
    struct vertex_info *vinfo = &softpipe->vertex_info;

    if (vinfo->num_attribs == 0) {
        /* compute vertex layout now */
        const struct tgsi_shader_info *fsInfo = &softpipe->fs_variant->info;
        struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
        const uint num = draw_num_shader_outputs(softpipe->draw);
        uint i;

        /* Tell draw_vbuf to simply emit the whole post-xform vertex
         * as-is.  No longer any need to try and emit draw vertex_header
         * info.
         */
        vinfo_vbuf->num_attribs = 0;
        for (i = 0; i < num; i++) {
            draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
        }
        draw_compute_vertex_size(vinfo_vbuf);

        /*
         * Loop over fragment shader inputs, searching for the matching output
         * from the vertex shader.
         */
        vinfo->num_attribs = 0;
        for (i = 0; i < fsInfo->num_inputs; i++) {
            int src;
            enum interp_mode interp = INTERP_LINEAR;

            switch (fsInfo->input_interpolate[i]) {
            case TGSI_INTERPOLATE_CONSTANT:
                interp = INTERP_CONSTANT;
                break;
            case TGSI_INTERPOLATE_LINEAR:
                interp = INTERP_LINEAR;
                break;
            case TGSI_INTERPOLATE_PERSPECTIVE:
                interp = INTERP_PERSPECTIVE;
                break;
            case TGSI_INTERPOLATE_COLOR:
                assert(fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR);
                break;
            default:
                assert(0);
            }

            switch (fsInfo->input_semantic_name[i]) {
            case TGSI_SEMANTIC_POSITION:
                interp = INTERP_POS;
                break;

            case TGSI_SEMANTIC_COLOR:
                if (fsInfo->input_interpolate[i] == TGSI_INTERPOLATE_COLOR) {
                    if (softpipe->rasterizer->flatshade)
                        interp = INTERP_CONSTANT;
                    else
                        interp = INTERP_PERSPECTIVE;
                }
                break;
            }

            /* this includes texcoords and varying vars */
            src = draw_find_shader_output(softpipe->draw,
                                          fsInfo->input_semantic_name[i],
                                          fsInfo->input_semantic_index[i]);
            if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR && src == 0)
                /* try and find a bcolor */
                src = draw_find_shader_output(softpipe->draw,
                                              TGSI_SEMANTIC_BCOLOR, fsInfo->input_semantic_index[i]);

            draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
        }

        softpipe->psize_slot = draw_find_shader_output(softpipe->draw,
                               TGSI_SEMANTIC_PSIZE, 0);
        if (softpipe->psize_slot > 0) {
            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
                                  softpipe->psize_slot);
        }

        draw_compute_vertex_size(vinfo);
    }

    return vinfo;
}
コード例 #4
0
ファイル: draw_pipe_clip.c プロジェクト: dumbbell/mesa
/**
 * Emit a post-clip polygon to the next pipeline stage.  The polygon
 * will be convex and the provoking vertex will always be vertex[0].
 */
static void emit_poly( struct draw_stage *stage,
		       struct vertex_header **inlist,
                       const boolean *edgeflags,
		       unsigned n,
		       const struct prim_header *origPrim)
{
   struct prim_header header;
   unsigned i;
   ushort edge_first, edge_middle, edge_last;
   boolean last_tri_was_null = FALSE;
   boolean tri_was_not_null = FALSE;

   if (stage->draw->rasterizer->flatshade_first) {
      edge_first  = DRAW_PIPE_EDGE_FLAG_0;
      edge_middle = DRAW_PIPE_EDGE_FLAG_1;
      edge_last   = DRAW_PIPE_EDGE_FLAG_2;
   }
   else {
      edge_first  = DRAW_PIPE_EDGE_FLAG_2;
      edge_middle = DRAW_PIPE_EDGE_FLAG_0;
      edge_last   = DRAW_PIPE_EDGE_FLAG_1;
   }

   if (!edgeflags[0])
      edge_first = 0;

   /* later stages may need the determinant, but only the sign matters */
   header.det = origPrim->det;
   header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
   header.pad = 0;

   for (i = 2; i < n; i++, header.flags = edge_middle) {
      boolean tri_null;
      /* order the triangle verts to respect the provoking vertex mode */
      if (stage->draw->rasterizer->flatshade_first) {
         header.v[0] = inlist[0];  /* the provoking vertex */
         header.v[1] = inlist[i-1];
         header.v[2] = inlist[i];
      }
      else {
         header.v[0] = inlist[i-1];
         header.v[1] = inlist[i];
         header.v[2] = inlist[0];  /* the provoking vertex */
      }

      tri_null = is_tri_null(stage->draw, &header);
      /* If we generated a triangle with an area, aka. non-null triangle,
       * or if the previous triangle was also null then skip all subsequent
       * null triangles */
      if ((tri_was_not_null && tri_null) || (last_tri_was_null && tri_null)) {
         last_tri_was_null = tri_null;
         continue;
      }
      last_tri_was_null = tri_null;
      if (!tri_null) {
         tri_was_not_null = TRUE;
      }

      if (!edgeflags[i-1]) {
         header.flags &= ~edge_middle;
      }

      if (i == n - 1 && edgeflags[i])
         header.flags |= edge_last;

      if (DEBUG_CLIP) {
         uint j, k;
         debug_printf("Clipped tri: (flat-shade-first = %d)\n",
                      stage->draw->rasterizer->flatshade_first);
         for (j = 0; j < 3; j++) {
            debug_printf("  Vert %d: clip: %f %f %f %f\n", j,
                         header.v[j]->clip[0],
                         header.v[j]->clip[1],
                         header.v[j]->clip[2],
                         header.v[j]->clip[3]);
            for (k = 0; k < draw_num_shader_outputs(stage->draw); k++) {
               debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
                            header.v[j]->data[k][0],
                            header.v[j]->data[k][1],
                            header.v[j]->data[k][2],
                            header.v[j]->data[k][3]);
            }
         }
      }
      stage->next->tri( stage->next, &header );
   }
}
コード例 #5
0
ファイル: draw_pipe_clip.c プロジェクト: dumbbell/mesa
/* Interpolate between two vertices to produce a third.  
 */
static void interp( const struct clip_stage *clip,
		    struct vertex_header *dst,
		    float t,
		    const struct vertex_header *out, 
		    const struct vertex_header *in,
                    unsigned viewport_index )
{
   const unsigned nr_attrs = draw_num_shader_outputs(clip->stage.draw);
   const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
   const unsigned clip_attr = draw_current_shader_clipvertex_output(clip->stage.draw);
   unsigned j;
   float t_nopersp;

   /* Vertex header.
    */
   dst->clipmask = 0;
   dst->edgeflag = 0;        /* will get overwritten later */
   dst->have_clipdist = in->have_clipdist;
   dst->vertex_id = UNDEFINED_VERTEX_ID;

   /* Interpolate the clip-space coords.
    */
   interp_attr(dst->clip, t, in->clip, out->clip);
   /* interpolate the clip-space position */
   interp_attr(dst->pre_clip_pos, t, in->pre_clip_pos, out->pre_clip_pos);

   /* Do the projective divide and viewport transformation to get
    * new window coordinates:
    */
   {
      const float *pos = dst->pre_clip_pos;
      const float *scale =
         clip->stage.draw->viewports[viewport_index].scale;
      const float *trans =
         clip->stage.draw->viewports[viewport_index].translate;
      const float oow = 1.0f / pos[3];

      dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
      dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
      dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
      dst->data[pos_attr][3] = oow;
   }
   
   /**
    * Compute the t in screen-space instead of 3d space to use
    * for noperspective interpolation.
    *
    * The points can be aligned with the X axis, so in that case try
    * the Y.  When both points are at the same screen position, we can
    * pick whatever value (the interpolated point won't be in front
    * anyway), so just use the 3d t.
    */
   {
      int k;
      t_nopersp = t;
      /* find either in.x != out.x or in.y != out.y */
      for (k = 0; k < 2; k++) {
         if (in->clip[k] != out->clip[k]) {
            /* do divide by W, then compute linear interpolation factor */
            float in_coord = in->clip[k] / in->clip[3];
            float out_coord = out->clip[k] / out->clip[3];
            float dst_coord = dst->clip[k] / dst->clip[3];
            t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord);
            break;
         }
      }
   }

   /* Other attributes
    */
   for (j = 0; j < nr_attrs; j++) {
      if (j != pos_attr && j != clip_attr) {
         if (clip->noperspective_attribs[j])
            interp_attr(dst->data[j], t_nopersp, in->data[j], out->data[j]);
         else
            interp_attr(dst->data[j], t, in->data[j], out->data[j]);
      }
   }
}