Beispiel #1
0
/**
 * Rasterize/execute all bins within a scene.
 * Called per thread.
 */
static void
rasterize_scene(struct lp_rasterizer_task *task,
                struct lp_scene *scene)
{
   task->scene = scene;
   /* loop over scene bins, rasterize each */
#if 0
   {
      unsigned i, j;
      for (i = 0; i < scene->tiles_x; i++) {
         for (j = 0; j < scene->tiles_y; j++) {
            struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
            rasterize_bin(task, bin, i, j);
         }
      }
   }
#else
   {
      struct cmd_bin *bin;

      assert(scene);
      while ((bin = lp_scene_bin_iter_next(scene))) {
         if (!is_empty_bin( bin ))
            rasterize_bin(task, bin);
      }
   }
#endif

   if (scene->fence) {
      lp_fence_signal(scene->fence);
   }

   task->scene = NULL;
}
Beispiel #2
0
void
lp_debug_draw_bins_by_coverage( struct lp_scene *scene )
{
   unsigned x, y;
   unsigned total = 0;
   unsigned possible = 0;
   static unsigned long long _total;
   static unsigned long long _possible;

   for (x = 0; x < scene->tiles_x; x++)
      debug_printf("-");
   debug_printf("\n");

   for (y = 0; y < scene->tiles_y; y++) {
      for (x = 0; x < scene->tiles_x; x++) {
         struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
         const char *bits = "0123456789";
         struct tile tile;

         if (bin->head) {
            //lp_debug_bin(bin);

            do_debug_bin(&tile, bin, FALSE);

            total += tile.coverage;
            possible += 64*64;

            if (tile.coverage == 64*64)
               debug_printf("*");
            else if (tile.coverage) {
               int bit = tile.coverage/(64.0*64.0)*10;
               debug_printf("%c", bits[MIN2(bit,10)]);
            }
            else
               debug_printf("?");
         }
         else {
            debug_printf(" ");
         }
      }
      debug_printf("|\n");
   }

   for (x = 0; x < scene->tiles_x; x++)
      debug_printf("-");
   debug_printf("\n");

   debug_printf("this tile total: %u possible %u: percentage: %f\n",
                total,
                possible,
                total * 100.0 / (float)possible);

   _total += total;
   _possible += possible;

   debug_printf("overall   total: %llu possible %llu: percentage: %f\n",
                _total,
                _possible,
                _total * 100.0 / (double)_possible);
}
/* Remove all commands from a bin.  Tries to reuse some of the memory
 * allocated to the bin, however.
 */
void
lp_scene_bin_reset(struct lp_scene *scene, unsigned x, unsigned y)
{
   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);

   bin->head = bin->tail;
   if (bin->tail) {
      bin->tail->next = NULL;
      bin->tail->count = 0;
   }
}
Beispiel #4
0
/** Return number of bytes used for a single bin */
static unsigned
lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y )
{
   struct cmd_bin *bin = lp_scene_get_bin((struct lp_scene *) scene, x, y);
   const struct cmd_block *cmd;
   unsigned size = 0;
   for (cmd = bin->head; cmd; cmd = cmd->next) {
      size += (cmd->count *
               (sizeof(uint8_t) + sizeof(union lp_rast_cmd_arg)));
   }
   return size;
}
Beispiel #5
0
void
lp_debug_bins( struct lp_scene *scene )
{
   unsigned x, y;

   for (y = 0; y < scene->tiles_y; y++) {
      for (x = 0; x < scene->tiles_x; x++) {
         struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
         if (bin->head) {
            debug_bin(bin, x, y);
         }
      }
   }
}
Beispiel #6
0
/**
 * Check if the scene's bins are all empty.
 * For debugging purposes.
 */
boolean
lp_scene_is_empty(struct lp_scene *scene )
{
   unsigned x, y;

   for (y = 0; y < TILES_Y; y++) {
      for (x = 0; x < TILES_X; x++) {
         const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
         if (bin->head) {
            return FALSE;
         }
      }
   }
   return TRUE;
}
Beispiel #7
0
/**
 * Return pointer to next bin to be rendered.
 * The lp_scene::curr_x and ::curr_y fields will be advanced.
 * Multiple rendering threads will call this function to get a chunk
 * of work (a bin) to work on.
 */
struct cmd_bin *
lp_scene_bin_iter_next( struct lp_scene *scene )
{
   struct cmd_bin *bin = NULL;

   pipe_mutex_lock(scene->mutex);

   if (scene->curr_x < 0) {
      /* first bin */
      scene->curr_x = 0;
      scene->curr_y = 0;
   }
   else if (!next_bin(scene)) {
      /* no more bins left */
      goto end;
   }

   bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y);

end:
   /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
   pipe_mutex_unlock(scene->mutex);
   return bin;
}
Beispiel #8
0
/**
 * Free all the temporary data in a scene.
 */
void
lp_scene_end_rasterization(struct lp_scene *scene )
{
   int i, j;

   /* Unmap color buffers */
   for (i = 0; i < scene->fb.nr_cbufs; i++) {
      if (scene->cbufs[i].map) {
         struct pipe_surface *cbuf = scene->fb.cbufs[i];
         if (llvmpipe_resource_is_texture(cbuf->texture)) {
            llvmpipe_resource_unmap(cbuf->texture,
                                    cbuf->u.tex.level,
                                    cbuf->u.tex.first_layer);
         }
         scene->cbufs[i].map = NULL;
      }
   }

   /* Unmap z/stencil buffer */
   if (scene->zsbuf.map) {
      struct pipe_surface *zsbuf = scene->fb.zsbuf;
      llvmpipe_resource_unmap(zsbuf->texture,
                              zsbuf->u.tex.level,
                              zsbuf->u.tex.first_layer);
      scene->zsbuf.map = NULL;
   }

   /* Reset all command lists:
    */
   for (i = 0; i < scene->tiles_x; i++) {
      for (j = 0; j < scene->tiles_y; j++) {
         struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
         bin->head = NULL;
         bin->tail = NULL;
         bin->last_state = NULL;
      }
   }

   /* If there are any bins which weren't cleared by the loop above,
    * they will be caught (on debug builds at least) by this assert:
    */
   assert(lp_scene_is_empty(scene));

   /* Decrement texture ref counts
    */
   {
      struct resource_ref *ref;
      int i, j = 0;

      for (ref = scene->resources; ref; ref = ref->next) {
         for (i = 0; i < ref->count; i++) {
            if (LP_DEBUG & DEBUG_SETUP)
               debug_printf("resource %d: %p %dx%d sz %d\n",
                            j,
                            (void *) ref->resource[i],
                            ref->resource[i]->width0,
                            ref->resource[i]->height0,
                            llvmpipe_resource_size(ref->resource[i]));
            j++;
            pipe_resource_reference(&ref->resource[i], NULL);
         }
      }

      if (LP_DEBUG & DEBUG_SETUP)
         debug_printf("scene %d resources, sz %d\n",
                      j, scene->resource_reference_size);
   }

   /* Free all scene data blocks:
    */
   {
      struct data_block_list *list = &scene->data;
      struct data_block *block, *tmp;

      for (block = list->head->next; block; block = tmp) {
         tmp = block->next;
	 FREE(block);
      }

      list->head->next = NULL;
      list->head->used = 0;
   }

   lp_fence_reference(&scene->fence, NULL);

   scene->resources = NULL;
   scene->scene_size = 0;
   scene->resource_reference_size = 0;

   scene->has_depthstencil_clear = FALSE;
   scene->alloc_failed = FALSE;

   util_unreference_framebuffer_state( &scene->fb );
}