コード例 #1
0
ファイル: rbug_context.c プロジェクト: gcampax/mesa
static void
rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag)
{

   if (rb_pipe->draw_blocker & flag) {
      rb_pipe->draw_blocked |= flag;
   } else if ((rb_pipe->draw_rule.blocker & flag) &&
              (rb_pipe->draw_blocker & RBUG_BLOCK_RULE)) {
      unsigned k;
      boolean block = FALSE;
      unsigned sh;

      debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__,
                   (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_FRAGMENT],
                   (void *) rb_pipe->curr.shader[PIPE_SHADER_FRAGMENT],
                   (void *) rb_pipe->draw_rule.shader[PIPE_SHADER_VERTEX],
                   (void *) rb_pipe->curr.shader[PIPE_SHADER_VERTEX],
                   (void *) rb_pipe->draw_rule.surf, 0,
                   (void *) rb_pipe->draw_rule.texture, 0);
      for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
         if (rb_pipe->draw_rule.shader[sh] &&
             rb_pipe->draw_rule.shader[sh] == rb_pipe->curr.shader[sh])
            block = TRUE;
      }

      if (rb_pipe->draw_rule.surf &&
          rb_pipe->draw_rule.surf == rb_pipe->curr.zsbuf)
            block = TRUE;
      if (rb_pipe->draw_rule.surf)
         for (k = 0; k < rb_pipe->curr.nr_cbufs; k++)
            if (rb_pipe->draw_rule.surf == rb_pipe->curr.cbufs[k])
               block = TRUE;
      if (rb_pipe->draw_rule.texture) {
         for (sh = 0; sh < Elements(rb_pipe->curr.num_views); sh++) {
            for (k = 0; k < rb_pipe->curr.num_views[sh]; k++) {
               if (rb_pipe->draw_rule.texture == rb_pipe->curr.texs[sh][k]) {
                  block = TRUE;
                  sh = PIPE_SHADER_TYPES; /* to break out of both loops */
                  break;
               }
            }
         }
      }

      if (block)
         rb_pipe->draw_blocked |= (flag | RBUG_BLOCK_RULE);
   }

   if (rb_pipe->draw_blocked)
      rbug_notify_draw_blocked(rb_pipe);

   /* wait for rbug to clear the blocked flag */
   while (rb_pipe->draw_blocked & flag) {
      rb_pipe->draw_blocked |= flag;
      pipe_condvar_wait(rb_pipe->draw_cond, rb_pipe->draw_mutex);
   }

}
コード例 #2
0
ファイル: tr_context.c プロジェクト: MttDs/new-rexeno-tindpe
static INLINE void
trace_context_draw_block(struct trace_context *tr_ctx, int flag)
{
   int k;

   pipe_mutex_lock(tr_ctx->draw_mutex);

   if (tr_ctx->draw_blocker & flag) {
      tr_ctx->draw_blocked |= flag;
   } else if ((tr_ctx->draw_rule.blocker & flag) &&
              (tr_ctx->draw_blocker & 4)) {
      boolean block = FALSE;
      debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__,
                   (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,
                   (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,
                   (void *) tr_ctx->draw_rule.surf, 0,
                   (void *) tr_ctx->draw_rule.tex, 0);
      if (tr_ctx->draw_rule.fs &&
          tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
         block = TRUE;
      if (tr_ctx->draw_rule.vs &&
          tr_ctx->draw_rule.vs == tr_ctx->curr.vs)
         block = TRUE;
      if (tr_ctx->draw_rule.surf &&
          tr_ctx->draw_rule.surf == tr_ctx->curr.zsbuf)
            block = TRUE;
      if (tr_ctx->draw_rule.surf)
         for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
            if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
               block = TRUE;
      if (tr_ctx->draw_rule.tex)
         for (k = 0; k < tr_ctx->curr.num_texs; k++)
            if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
               block = TRUE;

      if (block)
         tr_ctx->draw_blocked |= (flag | 4);
   }

   if (tr_ctx->draw_blocked)
      trace_rbug_notify_draw_blocked(tr_ctx);

   /* wait for rbug to clear the blocked flag */
   while (tr_ctx->draw_blocked & flag) {
      tr_ctx->draw_blocked |= flag;
#ifdef PIPE_THREAD_HAVE_CONDVAR
      pipe_condvar_wait(tr_ctx->draw_cond, tr_ctx->draw_mutex);
#else
      pipe_mutex_unlock(tr_ctx->draw_mutex);
#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
      Sleep(1);
#endif
      pipe_mutex_lock(tr_ctx->draw_mutex);
#endif
   }

   pipe_mutex_unlock(tr_ctx->draw_mutex);
}
コード例 #3
0
enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring,
                                         struct util_packet *packet,
                                         unsigned max_dwords,
                                         boolean wait )
{
   const struct util_packet *ring_packet;
   unsigned i;
   int ret = PIPE_OK;

   /* XXX: over-reliance on mutexes, etc:
    */
   pipe_mutex_lock(ring->mutex);

   /* Get next ring entry:
    */
   if (wait) {
      while (util_ringbuffer_empty(ring))
         pipe_condvar_wait(ring->change, ring->mutex);
   }
   else {
      if (util_ringbuffer_empty(ring)) {
         ret = PIPE_ERROR_OUT_OF_MEMORY;
         goto out;
      }
   }

   ring_packet = &ring->buf[ring->tail];

   /* Both of these are considered bugs.  Raise an assert on debug builds.
    */
   if (ring_packet->dwords > ring->mask + 1 - util_ringbuffer_space(ring) ||
       ring_packet->dwords > max_dwords) {
      assert(0);
      ret = PIPE_ERROR_BAD_INPUT;
      goto out;
   }

   /* Copy data from ring:
    */
   for (i = 0; i < ring_packet->dwords; i++) {
      packet[i] = ring->buf[ring->tail];
      ring->tail++;
      ring->tail &= ring->mask;
   }

out:
   /* Signal change:
    */
   pipe_condvar_signal(ring->change);
   pipe_mutex_unlock(ring->mutex);
   return ret;
}
コード例 #4
0
ファイル: lp_fence.c プロジェクト: venkatarajasekhar/Qt
void
lp_fence_wait(struct lp_fence *f)
{
   if (LP_DEBUG & DEBUG_FENCE)
      debug_printf("%s %d\n", __FUNCTION__, f->id);

   pipe_mutex_lock(f->mutex);
   assert(f->issued);
   while (f->count < f->rank) {
      pipe_condvar_wait(f->signalled, f->mutex);
   }
   pipe_mutex_unlock(f->mutex);
}
コード例 #5
0
ファイル: sp_setup.c プロジェクト: aljen/haiku-opengl
static PIPE_THREAD_ROUTINE( quad_thread, param )
{
   struct thread_info *info = (struct thread_info *) param;
   struct quad_job_que *que = &info->setup->que;

   for (;;) {
      struct quad_job job;
      boolean full;

      /* Wait for an available job.
       */
      pipe_mutex_lock( que->que_mutex );
      while (que->last == que->first)
         pipe_condvar_wait( que->que_notempty_condvar, que->que_mutex );

      /* See if the que is full.
       */
      full = (que->last + 1) % NUM_QUAD_JOBS == que->first;

      /* Take a job and remove it from que.
       */
      job = que->jobs[que->first];
      que->first = (que->first + 1) % NUM_QUAD_JOBS;

      /* Notify the producer if the que is not full.
       */
      if (full)
         pipe_condvar_signal( que->que_notfull_condvar );
      pipe_mutex_unlock( que->que_mutex );

      job.routine( info->setup, info->id, &job );

      /* Notify the producer if that's the last finished job.
       */
      pipe_mutex_lock( que->que_mutex );
      que->jobs_done++;
      if (que->jobs_added == que->jobs_done)
         pipe_condvar_signal( que->que_done_condvar );
      pipe_mutex_unlock( que->que_mutex );
   }

   return NULL;
}
コード例 #6
0
ファイル: sp_setup.c プロジェクト: aljen/haiku-opengl
static void
add_quad_job( struct quad_job_que *que, struct quad_header *quad, quad_job_routine routine )
{
#if INSTANT_NOTEMPTY_NOTIFY
   boolean empty;
#endif

   /* Wait for empty slot, see if the que is empty.
    */
   pipe_mutex_lock( que->que_mutex );
   while ((que->last + 1) % NUM_QUAD_JOBS == que->first) {
#if !INSTANT_NOTEMPTY_NOTIFY
      pipe_condvar_broadcast( que->que_notempty_condvar );
#endif
      pipe_condvar_wait( que->que_notfull_condvar, que->que_mutex );
   }
#if INSTANT_NOTEMPTY_NOTIFY
   empty = que->last == que->first;
#endif
   que->jobs_added++;
   pipe_mutex_unlock( que->que_mutex );

   /* Submit new job.
    */
   que->jobs[que->last].input = quad->input;
   que->jobs[que->last].inout = quad->inout;
   que->jobs[que->last].routine = routine;
   que->last = (que->last + 1) % NUM_QUAD_JOBS;

#if INSTANT_NOTEMPTY_NOTIFY
   /* If the que was empty, notify consumers there's a job to be done.
    */
   if (empty) {
      pipe_mutex_lock( que->que_mutex );
      pipe_condvar_broadcast( que->que_notempty_condvar );
      pipe_mutex_unlock( que->que_mutex );
   }
#endif
}
コード例 #7
0
void util_ringbuffer_enqueue( struct util_ringbuffer *ring,
                              const struct util_packet *packet )
{
   unsigned i;

   /* XXX: over-reliance on mutexes, etc:
    */
   pipe_mutex_lock(ring->mutex);

   /* make sure we don't request an impossible amount of space
    */
   assert(packet->dwords <= ring->mask);

   /* Wait for free space:
    */
   while (util_ringbuffer_space(ring) < packet->dwords)
      pipe_condvar_wait(ring->change, ring->mutex);

   /* Copy data to ring:
    */
   for (i = 0; i < packet->dwords; i++) {

      /* Copy all dwords of the packet.  Note we're abusing the
       * typesystem a little - we're being passed a pointer to
       * something, but probably not an array of packet structs:
       */
      ring->buf[ring->head] = packet[i];
      ring->head++;
      ring->head &= ring->mask;
   }

   /* Signal change:
    */
   pipe_condvar_signal(ring->change);
   pipe_mutex_unlock(ring->mutex);
}
コード例 #8
0
ファイル: radeon_drm_cs.c プロジェクト: ashmew2/kolibriosSVN
static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags, uint32_t cs_trace_id)
{
    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
    struct radeon_cs_context *tmp;

    switch (cs->base.ring_type) {
    case RING_DMA:
        /* pad DMA ring to 8 DWs */
        if (cs->ws->info.chip_class <= SI) {
            while (rcs->cdw & 7)
                OUT_CS(&cs->base, 0xf0000000); /* NOP packet */
        } else {
            while (rcs->cdw & 7)
                OUT_CS(&cs->base, 0x00000000); /* NOP packet */
        }
        break;
    case RING_GFX:
        /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements
         * r6xx, requires at least 4 dw alignment to avoid a hw bug.
         */
        if (flags & RADEON_FLUSH_COMPUTE) {
            if (cs->ws->info.chip_class <= SI) {
                while (rcs->cdw & 7)
                    OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
            } else {
                while (rcs->cdw & 7)
                    OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */
            }
        } else {
            while (rcs->cdw & 7)
                OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
        }
        break;
    }

    if (rcs->cdw > RADEON_MAX_CMDBUF_DWORDS) {
        fprintf(stderr, "radeon: command stream overflowed\n");
    }

    radeon_drm_cs_sync_flush(rcs);

    /* Flip command streams. */
    tmp = cs->csc;
    cs->csc = cs->cst;
    cs->cst = tmp;

    cs->cst->cs_trace_id = cs_trace_id;

    /* If the CS is not empty or overflowed, emit it in a separate thread. */
    if (cs->base.cdw && cs->base.cdw <= RADEON_MAX_CMDBUF_DWORDS && !debug_get_option_noop()) {
        unsigned i, crelocs = cs->cst->crelocs;

        cs->cst->chunks[0].length_dw = cs->base.cdw;

        for (i = 0; i < crelocs; i++) {
            /* Update the number of active asynchronous CS ioctls for the buffer. */
            p_atomic_inc(&cs->cst->relocs_bo[i]->num_active_ioctls);
        }

        switch (cs->base.ring_type) {
        case RING_DMA:
            cs->cst->flags[0] = 0;
            cs->cst->flags[1] = RADEON_CS_RING_DMA;
            cs->cst->cs.num_chunks = 3;
            if (cs->ws->info.r600_virtual_address) {
                cs->cst->flags[0] |= RADEON_CS_USE_VM;
            }
            break;

        case RING_UVD:
            cs->cst->flags[0] = 0;
            cs->cst->flags[1] = RADEON_CS_RING_UVD;
            cs->cst->cs.num_chunks = 3;
            break;

        default:
        case RING_GFX:
            cs->cst->flags[0] = 0;
            cs->cst->flags[1] = RADEON_CS_RING_GFX;
            cs->cst->cs.num_chunks = 2;
            if (flags & RADEON_FLUSH_KEEP_TILING_FLAGS) {
                cs->cst->flags[0] |= RADEON_CS_KEEP_TILING_FLAGS;
                cs->cst->cs.num_chunks = 3;
            }
            if (cs->ws->info.r600_virtual_address) {
                cs->cst->flags[0] |= RADEON_CS_USE_VM;
                cs->cst->cs.num_chunks = 3;
            }
            if (flags & RADEON_FLUSH_END_OF_FRAME) {
                cs->cst->flags[0] |= RADEON_CS_END_OF_FRAME;
                cs->cst->cs.num_chunks = 3;
            }
            if (flags & RADEON_FLUSH_COMPUTE) {
                cs->cst->flags[1] = RADEON_CS_RING_COMPUTE;
                cs->cst->cs.num_chunks = 3;
            }
            break;
        }

        if (cs->ws->thread && (flags & RADEON_FLUSH_ASYNC)) {
            cs->flush_started = 1;
            radeon_drm_ws_queue_cs(cs->ws, cs);
        } else {
            pipe_mutex_lock(cs->ws->cs_stack_lock);
            if (cs->ws->thread) {
                while (p_atomic_read(&cs->ws->ncs)) {
                    pipe_condvar_wait(cs->ws->cs_queue_empty, cs->ws->cs_stack_lock);
                }
            }
            pipe_mutex_unlock(cs->ws->cs_stack_lock);
            radeon_drm_cs_emit_ioctl_oneshot(cs, cs->cst);
        }
    } else {
        radeon_cs_context_cleanup(cs->cst);
    }

    /* Prepare a new CS. */
    cs->base.buf = cs->csc->buf;
    cs->base.cdw = 0;
}