Esempio n. 1
0
/* Only caller is lp_setup_vbuf_destroy()
 */
void 
lp_setup_destroy( struct lp_setup_context *setup )
{
   uint i;

   lp_setup_reset( setup );

   util_unreference_framebuffer_state(&setup->fb);

   for (i = 0; i < ARRAY_SIZE(setup->fs.current_tex); i++) {
      pipe_resource_reference(&setup->fs.current_tex[i], NULL);
   }

   for (i = 0; i < ARRAY_SIZE(setup->constants); i++) {
      pipe_resource_reference(&setup->constants[i].current.buffer, NULL);
   }

   /* free the scenes in the 'empty' queue */
   for (i = 0; i < ARRAY_SIZE(setup->scenes); i++) {
      struct lp_scene *scene = setup->scenes[i];

      if (scene->fence)
         lp_fence_wait(scene->fence);

      lp_scene_destroy(scene);
   }

   lp_fence_reference(&setup->last_fence, NULL);

   FREE( setup );
}
Esempio n. 2
0
static boolean
llvmpipe_get_query_result(struct pipe_context *pipe, 
                          struct pipe_query *q,
                          boolean wait,
                          union pipe_query_result *vresult)
{
   struct llvmpipe_query *pq = llvmpipe_query(q);
   uint64_t *result = (uint64_t *)vresult;
   int i;

   if (!pq->fence) {
      /* no fence because there was no scene, so results is zero */
      *result = 0;
      return TRUE;
   }

   if (!lp_fence_signalled(pq->fence)) {
      if (!lp_fence_issued(pq->fence))
         llvmpipe_flush(pipe, NULL, __FUNCTION__);

      if (!wait)
         return FALSE;

      lp_fence_wait(pq->fence);
   }

   /* Sum the results from each of the threads:
    */
   *result = 0;

   switch (pq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      for (i = 0; i < LP_MAX_THREADS; i++) {
         *result += pq->count[i];
      }
      break;
   case PIPE_QUERY_TIMESTAMP:
      for (i = 0; i < LP_MAX_THREADS; i++) {
         if (pq->count[i] > *result) {
            *result = pq->count[i];
         }
         if (*result == 0)
            *result = os_time_get_nano();
      }
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
      *result = pq->num_primitives_generated;
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      *result = pq->num_primitives_written;
      break;
   default:
      assert(0);
      break;
   }

   return TRUE;
}
Esempio n. 3
0
/**
 * Wait for the fence to finish.
 */
static boolean
llvmpipe_fence_finish(struct pipe_screen *screen,
                      struct pipe_fence_handle *fence_handle,
                      uint64_t timeout)
{
   struct lp_fence *f = (struct lp_fence *) fence_handle;

   lp_fence_wait(f);
   return TRUE;
}
Esempio n. 4
0
/**
 * Wait for the fence to finish.
 */
static int
llvmpipe_fence_finish(struct pipe_screen *screen,
                      struct pipe_fence_handle *fence_handle,
                      unsigned flag)
{
   struct lp_fence *f = (struct lp_fence *) fence_handle;

   lp_fence_wait(f);
   return 0;
}
Esempio n. 5
0
/**
 * Wait for the fence to finish.
 */
static boolean
llvmpipe_fence_finish(struct pipe_screen *screen,
                      struct pipe_context *ctx,
                      struct pipe_fence_handle *fence_handle,
                      uint64_t timeout)
{
   struct lp_fence *f = (struct lp_fence *) fence_handle;

   if (!timeout)
      return lp_fence_signalled(f);

   lp_fence_wait(f);
   return TRUE;
}
Esempio n. 6
0
/**
 * Wait for the fence to finish.
 */
static boolean
llvmpipe_fence_finish(struct pipe_screen *screen,
                      struct pipe_context *ctx,
                      struct pipe_fence_handle *fence_handle,
                      uint64_t timeout)
{
   struct lp_fence *f = (struct lp_fence *) fence_handle;

   if (!timeout)
      return lp_fence_signalled(f);

   if (!lp_fence_signalled(f)) {
      if (timeout != PIPE_TIMEOUT_INFINITE)
         return lp_fence_timedwait(f, timeout);

      lp_fence_wait(f);
   }
   return TRUE;
}
Esempio n. 7
0
static void
llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
{
   struct llvmpipe_query *pq = llvmpipe_query(q);

   /* Ideally we would refcount queries & not get destroyed until the
    * last scene had finished with us.
    */
   if (pq->fence) {
      if (!lp_fence_issued(pq->fence))
         llvmpipe_flush(pipe, NULL, __FUNCTION__);

      if (!lp_fence_signalled(pq->fence))
         lp_fence_wait(pq->fence);

      lp_fence_reference(&pq->fence, NULL);
   }

   FREE(pq);
}
Esempio n. 8
0
static void
lp_setup_get_empty_scene(struct lp_setup_context *setup)
{
   assert(setup->scene == NULL);

   setup->scene_idx++;
   setup->scene_idx %= ARRAY_SIZE(setup->scenes);

   setup->scene = setup->scenes[setup->scene_idx];

   if (setup->scene->fence) {
      if (LP_DEBUG & DEBUG_SETUP)
         debug_printf("%s: wait for scene %d\n",
                      __FUNCTION__, setup->scene->fence->id);

      lp_fence_wait(setup->scene->fence);
   }

   lp_scene_begin_binning(setup->scene, &setup->fb, setup->rasterizer_discard);

}
Esempio n. 9
0
static void
lp_setup_get_empty_scene(struct lp_setup_context *setup)
{
   struct llvmpipe_context *lp = llvmpipe_context(setup->pipe);
   boolean discard = lp->rasterizer ? lp->rasterizer->rasterizer_discard : FALSE;

   assert(setup->scene == NULL);

   setup->scene_idx++;
   setup->scene_idx %= Elements(setup->scenes);

   setup->scene = setup->scenes[setup->scene_idx];

   if (setup->scene->fence) {
      if (LP_DEBUG & DEBUG_SETUP)
         debug_printf("%s: wait for scene %d\n",
                      __FUNCTION__, setup->scene->fence->id);

      lp_fence_wait(setup->scene->fence);
   }

   lp_scene_begin_binning(setup->scene, &setup->fb, discard);
   
}
Esempio n. 10
0
static boolean
llvmpipe_get_query_result(struct pipe_context *pipe, 
                          struct pipe_query *q,
                          boolean wait,
                          union pipe_query_result *vresult)
{
   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
   unsigned num_threads = MAX2(1, screen->num_threads);
   struct llvmpipe_query *pq = llvmpipe_query(q);
   uint64_t *result = (uint64_t *)vresult;
   int i;

   if (pq->fence) {
      /* only have a fence if there was a scene */
      if (!lp_fence_signalled(pq->fence)) {
         if (!lp_fence_issued(pq->fence))
            llvmpipe_flush(pipe, NULL, __FUNCTION__);

         if (!wait)
            return FALSE;

         lp_fence_wait(pq->fence);
      }
   }

   /* Sum the results from each of the threads:
    */
   *result = 0;

   switch (pq->type) {
   case PIPE_QUERY_OCCLUSION_COUNTER:
      for (i = 0; i < num_threads; i++) {
         *result += pq->end[i];
      }
      break;
   case PIPE_QUERY_OCCLUSION_PREDICATE:
      for (i = 0; i < num_threads; i++) {
         /* safer (still not guaranteed) when there's an overflow */
         vresult->b = vresult->b || pq->end[i];
      }
      break;
   case PIPE_QUERY_TIMESTAMP:
      for (i = 0; i < num_threads; i++) {
         if (pq->end[i] > *result) {
            *result = pq->end[i];
         }
      }
      break;
   case PIPE_QUERY_TIMESTAMP_DISJOINT: {
      struct pipe_query_data_timestamp_disjoint *td =
         (struct pipe_query_data_timestamp_disjoint *)vresult;
      /* os_get_time_nano return nanoseconds */
      td->frequency = UINT64_C(1000000000);
      td->disjoint = FALSE;
   }
      break;
   case PIPE_QUERY_GPU_FINISHED:
      vresult->b = TRUE;
      break;
   case PIPE_QUERY_PRIMITIVES_GENERATED:
      *result = pq->num_primitives_generated;
      break;
   case PIPE_QUERY_PRIMITIVES_EMITTED:
      *result = pq->num_primitives_written;
      break;
   case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
      vresult->b = pq->num_primitives_generated > pq->num_primitives_written;
      break;
   case PIPE_QUERY_SO_STATISTICS: {
      struct pipe_query_data_so_statistics *stats =
         (struct pipe_query_data_so_statistics *)vresult;
      stats->num_primitives_written = pq->num_primitives_written;
      stats->primitives_storage_needed = pq->num_primitives_generated;
   }
      break;
   case PIPE_QUERY_PIPELINE_STATISTICS: {
      struct pipe_query_data_pipeline_statistics *stats =
         (struct pipe_query_data_pipeline_statistics *)vresult;
      /* only ps_invocations come from binned query */
      for (i = 0; i < num_threads; i++) {
         pq->stats.ps_invocations += pq->end[i];
      }
      pq->stats.ps_invocations *= LP_RASTER_BLOCK_SIZE * LP_RASTER_BLOCK_SIZE;
      *stats = pq->stats;
   }
      break;
   default:
      assert(0);
      break;
   }

   return TRUE;
}