static void 
i915_vbuf_render_draw_elements(struct vbuf_render *render,
                               const ushort *indices,
                               uint nr_indices)
{
   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
   struct i915_context *i915 = i915_render->i915;
   unsigned save_nr_indices;

   save_nr_indices = nr_indices;

   nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback);
   if (!nr_indices)
      return;

   i915_vbuf_ensure_index_bounds(render, i915_render->vbo_max_index);

   if (i915->dirty)
      i915_update_derived(i915);

   if (i915->hardware_dirty)
      i915_emit_hardware_state(i915);

   if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
      FLUSH_BATCH(NULL);

      /* Make sure state is re-emitted after a flush: 
       */
      i915_update_derived(i915);
      i915_emit_hardware_state(i915);
      i915->vbo_flushed = 1;

      if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
         assert(0);
         goto out;
      }
   }

   OUT_BATCH(_3DPRIMITIVE |
             PRIM_INDIRECT |
             i915_render->hwprim |
             PRIM_INDIRECT_ELTS |
             nr_indices);
   draw_generate_indices(render,
                         indices,
                         save_nr_indices,
                         i915_render->fallback);

out:
   return;
}
static void
i915_vbuf_render_draw_arrays(struct vbuf_render *render,
                             unsigned start,
                             uint nr)
{
   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
   struct i915_context *i915 = i915_render->i915;

   if (i915_render->fallback) {
      draw_arrays_fallback(render, start, nr);
      return;
   }

   i915_vbuf_ensure_index_bounds(render, start + nr);
   start += i915_render->vbo_index;

   if (i915->dirty)
      i915_update_derived(i915);

   if (i915->hardware_dirty)
      i915_emit_hardware_state(i915);

   if (!BEGIN_BATCH(2, 0)) {
      FLUSH_BATCH(NULL);

      /* Make sure state is re-emitted after a flush:
       */
      i915_update_derived(i915);
      i915_emit_hardware_state(i915);
      i915->vbo_flushed = 1;

      if (!BEGIN_BATCH(2, 0)) {
         assert(0);
         goto out;
      }
   }

   OUT_BATCH(_3DPRIMITIVE |
             PRIM_INDIRECT |
             PRIM_INDIRECT_SEQUENTIAL |
             i915_render->hwprim |
             nr);
   OUT_BATCH(start); /* Beginning vertex index */

out:
   return;
}
Beispiel #3
0
static INLINE void 
emit_prim( struct draw_stage *stage, 
	   struct prim_header *prim,
	   unsigned hwprim,
	   unsigned nr )
{
   struct i915_context *i915 = setup_stage(stage)->i915;
   unsigned vertex_size;
   unsigned i;

   if (i915->dirty)
      i915_update_derived( i915 );

   if (i915->hardware_dirty)
      i915_emit_hardware_state( i915 );

   /* need to do this after validation! */
   vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
   assert(vertex_size >= 12); /* never smaller than 12 bytes */

   if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
      FLUSH_BATCH(NULL);

      /* Make sure state is re-emitted after a flush: 
       */
      i915_emit_hardware_state( i915 );

      if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
	 assert(0);
	 return;
      }
   }

   /* Emit each triangle as a single primitive.  I told you this was
    * simple.
    */
   OUT_BATCH(_3DPRIMITIVE | 
	     hwprim |
	     ((4 + vertex_size * nr)/4 - 2));

   for (i = 0; i < nr; i++)
      emit_hw_vertex(i915, prim->v[i]);
}
Beispiel #4
0
void
i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
                double depth, unsigned stencil,
                unsigned destx, unsigned desty, unsigned width, unsigned height)
{
   struct i915_context *i915 = i915_context(pipe);
   uint32_t clear_params, clear_color, clear_depth, clear_stencil,
            clear_color8888, packed_z_stencil;
   union util_color u_color;
   float f_depth = depth;
   struct i915_texture *cbuf_tex, *depth_tex;

   cbuf_tex = depth_tex = NULL;
   clear_params = 0;

   if (buffers & PIPE_CLEAR_COLOR) {
      struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];

      clear_params |= CLEARPARAM_WRITE_COLOR;
      cbuf_tex = i915_texture(cbuf->texture);
      util_pack_color(rgba, cbuf->format, &u_color);
      if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4)
         clear_color = u_color.ui;
      else
         clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);

      util_pack_color(rgba, cbuf->format, &u_color);
      clear_color8888 = u_color.ui;
   } else
      clear_color = clear_color8888 = 0;

   clear_depth = clear_stencil = 0;
   if (buffers & PIPE_CLEAR_DEPTH) {
      struct pipe_surface *zbuf = i915->framebuffer.zsbuf;

      clear_params |= CLEARPARAM_WRITE_DEPTH;
      depth_tex = i915_texture(zbuf->texture);
      packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);

      if (util_format_get_blocksize(depth_tex->b.b.format) == 4) {
         /* Avoid read-modify-write if there's no stencil. */
         if (buffers & PIPE_CLEAR_STENCIL
               || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_USCALED) {
            clear_params |= CLEARPARAM_WRITE_STENCIL;
            clear_stencil = packed_z_stencil & 0xff;
            clear_depth = packed_z_stencil;
         } else
            clear_depth = packed_z_stencil & 0xffffff00;
      } else {
         clear_depth = (clear_depth & 0xffff) | (clear_depth << 16);
      }
   }

   if (i915->hardware_dirty)
      i915_emit_hardware_state(i915);

   if (!BEGIN_BATCH(7 + 7)) {
      FLUSH_BATCH(NULL);

      i915_emit_hardware_state(i915);
      i915->vbo_flushed = 1;

      assert(BEGIN_BATCH(7 + 7));
   }

   OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
   OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT);
   OUT_BATCH(clear_color);
   OUT_BATCH(clear_depth);
   OUT_BATCH(clear_color8888);
   OUT_BATCH_F(f_depth);
   OUT_BATCH(clear_stencil);

   OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
   OUT_BATCH_F(destx + width);
   OUT_BATCH_F(desty + height);
   OUT_BATCH_F(destx);
   OUT_BATCH_F(desty + height);
   OUT_BATCH_F(destx);
   OUT_BATCH_F(desty);

   /* Flush after clear, its expected to be a costly operation.
    * This is not required, just a heuristic
    */
   FLUSH_BATCH(NULL);
}