Ejemplo n.º 1
0
void i810WaitAgeLocked( i810ContextPtr imesa, int age  ) 
{
   int i = 0, j;

   while (++i < 5000) {
      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
      if (GET_DISPATCH_AGE(imesa) >= age)
	 return;
      for (j = 0 ; j < 1000 ; j++)
	 ;
   }

   drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
}
Ejemplo n.º 2
0
void i830WaitAgeLocked( i830ContextPtr imesa, int age )
{
   int i = 0;
   while (++i < 5000) {
      drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
      if (GET_DISPATCH_AGE(imesa) >= age) return;
      imesa->sarea->perf_boxes |= I830_BOX_WAIT;
      UNLOCK_HARDWARE( imesa );
      if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, ".");
      usleep(1);
      LOCK_HARDWARE( imesa );
   }
   /* If that didn't work, just do a flush:
    */
   drmCommandNone(imesa->driFd, DRM_I830_FLUSH); 
}
Ejemplo n.º 3
0
void i830WaitAge( i830ContextPtr imesa, int age  ) 
{
   int i = 0;
   if (GET_DISPATCH_AGE(imesa) >= age) return;

   while (1) {
      drmCommandNone(imesa->driFd, DRM_I830_GETAGE);
      if (GET_DISPATCH_AGE(imesa) >= age) return;
      imesa->perf_boxes |= I830_BOX_WAIT;

      if (imesa->do_irqs) {
	 drmI830IrqEmit ie;
	 drmI830IrqWait iw;
	 int ret;
      
	 ie.irq_seq = &iw.irq_seq;
	 
	 LOCK_HARDWARE( imesa ); 
	 ret = drmCommandWriteRead( imesa->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) );
	 if ( ret ) {
	    fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
	    exit(1);
	 }
	 UNLOCK_HARDWARE(imesa);
	 
	 ret = drmCommandWrite( imesa->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
	 if ( ret ) {
	    fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
	    exit(1);
	 }
      } else {
	 if (++i > 5000) usleep(1); 
      }
   }
}
Ejemplo n.º 4
0
static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa )
{
   drmI830DMA dma;
   drmBufPtr buf;
   int retcode,i = 0;
   while (1) {
      retcode = drmCommandWriteRead(imesa->driFd, 
				    DRM_I830_GETBUF, 
				    &dma, 
				    sizeof(drmI830DMA));
      if (dma.granted == 1 && retcode == 0)
	break;

      if (++i > 1000) {
	 imesa->sarea->perf_boxes |= I830_BOX_WAIT;
	 retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH);
	 i = 0;
      }
   }

   buf = &(imesa->i830Screen->bufs->list[dma.request_idx]);
   buf->idx = dma.request_idx;
   buf->used = 0;
   buf->total = dma.request_size;
   buf->address = (drmAddress)dma.virtual;

   return buf;
}
bool IntelHWComposerDrm::setDisplayIed(bool on)
{
    int ret;

    ret = drmCommandNone(mDrmFd, DRM_PSB_HDCP_DISPLAY_IED_ON);

    return (ret == 0) ? true : false;
}
bool OMXVideoDecoderAVCSecure::EnableIEDSession(bool enable)
{
    if (mDrmDevFd < 0) {
        return false;
    }
    int request = enable ?  DRM_PSB_ENABLE_IED_SESSION : DRM_PSB_DISABLE_IED_SESSION;
    int ret = drmCommandNone(mDrmDevFd, request);
    return ret == 0;
}
Ejemplo n.º 7
0
void r128WaitForIdleLocked( r128ContextPtr rmesa )
{
    int fd = rmesa->r128Screen->driScreen->fd;
    int to = 0;
    int ret, i;

    do {
        i = 0;
        do {
            ret = drmCommandNone( fd, DRM_R128_CCE_IDLE);
        } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
    } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) );

    if ( ret < 0 ) {
        drmCommandNone( fd, DRM_R128_CCE_RESET);
        UNLOCK_HARDWARE( rmesa );
        fprintf( stderr, "Error: Rage 128 timed out... exiting\n" );
        exit( -1 );
    }
}
static bool drm_hdcp_disable()
{
    int fd = drm_get_dev_fd();
    if (fd <= 0) {
        ALOGE("Invalid DRM file descriptor.");
        return false;
    }
    int ret = drmCommandNone(fd, DRM_PSB_DISABLE_HDCP);
    if (ret != 0) {
        ALOGW("Failed to disable HDCP.");
        return false;
    }
    return true;
}
static bool drm_hdcp_enable_display_ied()
{
    int fd, ret;
    fd = drm_get_dev_fd();
    if (fd <= 0) {
        ALOGE("Invalid DRM file descriptor.");
        return false;
    }
    ret = drmCommandNone(fd, DRM_PSB_HDCP_DISPLAY_IED_ON);
    if (ret != 0) {
        ALOGE("Failed to enable HDCP-Display-IED.");
        return false;
    }
    return true;
}
Ejemplo n.º 10
0
void i810WaitAge( i810ContextPtr imesa, int age  ) 
{
   int i = 0, j;

   while (++i < 5000) {
      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
      if (GET_DISPATCH_AGE(imesa) >= age)
	 return;
      for (j = 0 ; j < 1000 ; j++)
	 ;
   }

   i = 0;
   while (++i < 1000) {
      drmCommandNone(imesa->driFd, DRM_I810_GETAGE);
      if (GET_DISPATCH_AGE(imesa) >= age)
	 return;
      usleep(1000);
   }

   LOCK_HARDWARE(imesa);
   drmCommandNone(imesa->driFd, DRM_I810_FLUSH);
   UNLOCK_HARDWARE(imesa);
}
OMX_ERRORTYPE OMXVideoDecoderAVCSecure::ProcessorStart(void) {
    uint32_t imrOffset = 0;
    uint32_t imrBufferSize = IMR_BUFFER_SIZE;
    uint32_t sessionID;

    EnableIEDSession(true);
    sec_result_t sepres = Drm_WV_CreateSession(&imrOffset, &imrBufferSize, &sessionID);
    if (sepres != 0) {
        LOGW("Drm_WV_CreateSession failed. Result = %#x", sepres);
        // Returning error will cause OMX client to crash.
        //return OMX_ErrorHardware;
    }
    if (sessionID != WV_SESSION_ID) {
        LOGE("Invalid session ID %#x created", sessionID);
        //return OMX_ErrorHardware;
    }
    LOGI("Drm_WV_CreateSession: IMR Offset = %d, IMR size = %#x", imrOffset, imrBufferSize);
    if (imrBufferSize != IMR_BUFFER_SIZE) {
        LOGE("Mismatch in IMR size: Requested: %#x Obtained: %#x", IMR_BUFFER_SIZE, imrBufferSize);
    }
    drmCommandNone(mDrmDevFd, DRM_PSB_HDCP_DISPLAY_IED_OFF);


    int ret;
    struct sigevent sev;
    memset(&sev, 0, sizeof(sev));
    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_value.sival_ptr = this;
    sev.sigev_notify_function = KeepAliveTimerCallback;

    ret = timer_create(CLOCK_REALTIME, &sev, &mKeepAliveTimer);
    if (ret != 0) {
        LOGE("Failed to create timer.");
    } else {
        struct itimerspec its;
        its.it_value.tv_sec = -1; // never expire
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = KEEP_ALIVE_INTERVAL;
        its.it_interval.tv_nsec = 0;

        ret = timer_settime(mKeepAliveTimer, TIMER_ABSTIME, &its, NULL);
        if (ret != 0) {
            LOGE("Failed to set timer.");
        }
    }
    mSessionPaused = false;
    return OMXVideoDecoderBase::ProcessorStart();
}
Ejemplo n.º 12
0
static void I810DRITransitionTo2d(ScreenPtr pScreen)
{
    ScrnInfoPtr         pScrn      = xf86ScreenToScrn(pScreen);
    I810Ptr       pI810       = I810PTR(pScrn);
    I810SAREAPtr  pSAREAPriv = DRIGetSAREAPrivate(pScreen);

    /* Try flipping back to the front page if necessary */
    if (pSAREAPriv->pf_current_page == 1)
	drmCommandNone(pI810->drmSubFD, DRM_I810_FLIP);

    /* Shut down shadowing if we've made it back to the front page */
    if (pSAREAPriv->pf_current_page == 0) {
	I810DisablePageFlip(pScreen);
    }
    pI810->have3DWindows = 0;
}
Ejemplo n.º 13
0
void r200WaitForIdleLocked( r200ContextPtr rmesa )
{
    int ret;
    int i = 0;
    
    do {
       ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_CP_IDLE);
       if (ret) 
	  DO_USLEEP( 1 );
    } while (ret && ++i < 100);
    
    if ( ret < 0 ) {
       UNLOCK_HARDWARE( rmesa );
       fprintf( stderr, "Error: R200 timed out... exiting\n" );
       exit( -1 );
    }
}
Ejemplo n.º 14
0
/* Flip the front & back buffes
 */
void i830PageFlip( const __DRIdrawablePrivate *dPriv )
{
   i830ContextPtr imesa;
   int tmp, ret;

   if (I830_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;

   I830_FIREVERTICES( imesa );
   LOCK_HARDWARE( imesa );

   imesa->sarea->perf_boxes |= imesa->perf_boxes;
   imesa->perf_boxes = 0;

   if (dPriv->pClipRects) {
      *(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0];
      imesa->sarea->nbox = 1;
   }

   ret = drmCommandNone(imesa->driFd, DRM_I830_FLIP); 
   if (ret) {
      fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
      UNLOCK_HARDWARE( imesa );
      exit(1);
   }

   tmp = GET_ENQUEUE_AGE(imesa);
   UNLOCK_HARDWARE( imesa );

   /* multiarb will suck the life out of the server without this throttle:
    */
   if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
      i830WaitAge(imesa, imesa->lastSwap);
   }

   i830SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );
   imesa->upload_cliprects = GL_TRUE;
   imesa->lastSwap = tmp;
}
Ejemplo n.º 15
0
/*
 * Copy the back buffer to the front buffer. 
 */
void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) 
{
   i830ContextPtr imesa;
   XF86DRIClipRectPtr pbox;
   int nbox, i, tmp;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate;

   I830_FIREVERTICES( imesa );
   LOCK_HARDWARE( imesa );

   imesa->sarea->perf_boxes |= imesa->perf_boxes;
   imesa->perf_boxes = 0;

   pbox = dPriv->pClipRects;
   nbox = dPriv->numClipRects;

   for (i = 0 ; i < nbox ; )
   {
      int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
      XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes;

      imesa->sarea->nbox = nr - i;

      for ( ; i < nr ; i++) 
	 *b++ = pbox[i];
      drmCommandNone(imesa->driFd, DRM_I830_SWAP);
   }

   tmp = GET_ENQUEUE_AGE(imesa);
   UNLOCK_HARDWARE( imesa );

   /* multiarb will suck the life out of the server without this throttle:
    */
   if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
      i830WaitAge(imesa, imesa->lastSwap);
   }

   imesa->lastSwap = tmp;
   imesa->upload_cliprects = GL_TRUE;
}
Ejemplo n.º 16
0
/* Get a new VB from the pool of vertex buffers in AGP space.
 */
drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa )
{
    int fd = rmesa->r128Screen->driScreen->fd;
    int index = 0;
    int size = 0;
    drmDMAReq dma;
    drmBufPtr buf = NULL;
    int to = 0;
    int ret;

    dma.context = rmesa->hHWContext;
    dma.send_count = 0;
    dma.send_list = NULL;
    dma.send_sizes = NULL;
    dma.flags = 0;
    dma.request_count = 1;
    dma.request_size = R128_BUFFER_SIZE;
    dma.request_list = &index;
    dma.request_sizes = &size;
    dma.granted_count = 0;

    while ( !buf && ( to++ < R128_TIMEOUT ) ) {
        ret = drmDMA( fd, &dma );

        if ( ret == 0 ) {
            buf = &rmesa->r128Screen->buffers->list[index];
            buf->used = 0;
#if ENABLE_PERF_BOXES
            /* Bump the performance counter */
            rmesa->c_vertexBuffers++;
#endif
            return buf;
        }
    }

    if ( !buf ) {
        drmCommandNone( fd, DRM_R128_CCE_RESET);
        UNLOCK_HARDWARE( rmesa );
        fprintf( stderr, "Error: Could not get new VB... exiting\n" );
        exit( -1 );
    }

    return buf;
}
Ejemplo n.º 17
0
/*
 * XXX implement when full-screen extension is done.
 */
void i810PageFlip( const __DRIdrawable *dPriv ) 
{
  i810ContextPtr imesa;
  int tmp, ret;

  assert(dPriv);
  assert(dPriv->driContextPriv);
  assert(dPriv->driContextPriv->driverPrivate);
    
  imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate;

  I810_FIREVERTICES( imesa );
  LOCK_HARDWARE( imesa );
  
  if (dPriv->pClipRects) {
     memcpy(&(imesa->sarea->boxes[0]), &(dPriv->pClipRects[0]),
            sizeof(drm_clip_rect_t));
     imesa->sarea->nbox = 1;
  }
  ret = drmCommandNone(imesa->driFd, DRM_I810_FLIP);
  if (ret) {
    fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
    UNLOCK_HARDWARE( imesa );
    exit(1);
  }

  tmp = GET_ENQUEUE_AGE(imesa);
  UNLOCK_HARDWARE( imesa );
  
   /* multiarb will suck the life out of the server without this throttle:
    */
  if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) {
    i810WaitAge(imesa, imesa->lastSwap);
   }

  /*  i810SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );*/
  i810DrawBuffer( imesa->glCtx, imesa->glCtx->Color.DrawBuffer[0] );
  imesa->upload_cliprects = GL_TRUE;
  imesa->lastSwap = tmp;
  return;
}
Ejemplo n.º 18
0
/* Flip the front & back buffes
 */
void intelPageFlip( const __DRIdrawablePrivate *dPriv )
{
#if 0
   intelContextPtr intel;
   int tmp, ret;

   if (INTEL_DEBUG & DEBUG_IOCTL)
      fprintf(stderr, "%s\n", __FUNCTION__);

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;

   intelFlush( &intel->ctx );
   LOCK_HARDWARE( intel );

   if (dPriv->pClipRects) {
      *(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
      intel->sarea->nbox = 1;
   }

   ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); 
   if (ret) {
      fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
      UNLOCK_HARDWARE( intel );
      exit(1);
   }

   tmp = intel->sarea->last_enqueue;
   intelRefillBatchLocked( intel );
   UNLOCK_HARDWARE( intel );


   intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
#endif
}
Ejemplo n.º 19
0
/* Copy the back color buffer to the front color buffer.
 */
void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
{
   r200ContextPtr rmesa;
   GLint nbox, i, ret;
   GLboolean   missed_target;
   int64_t ust;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;

   if ( R200_DEBUG & DEBUG_IOCTL ) {
      fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *)rmesa->glCtx );
   }

   R200_FIREVERTICES( rmesa );

   LOCK_HARDWARE( rmesa );


   /* Throttle the frame rate -- only allow one pending swap buffers
    * request at a time.
    */
   r200WaitForFrameCompletion( rmesa );
   UNLOCK_HARDWARE( rmesa );
   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
   LOCK_HARDWARE( rmesa );

   nbox = dPriv->numClipRects; /* must be in locked region */

   for ( i = 0 ; i < nbox ; ) {
      GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox );
      drm_clip_rect_t *box = dPriv->pClipRects;
      drm_clip_rect_t *b = rmesa->sarea->boxes;
      GLint n = 0;

      for ( ; i < nr ; i++ ) {
	 *b++ = box[i];
	 n++;
      }
      rmesa->sarea->nbox = n;

      ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );

      if ( ret ) {
	 fprintf( stderr, "DRM_R200_SWAP_BUFFERS: return = %d\n", ret );
	 UNLOCK_HARDWARE( rmesa );
	 exit( 1 );
      }
   }

   UNLOCK_HARDWARE( rmesa );
   rmesa->hw.all_dirty = GL_TRUE;

   rmesa->swap_count++;
   (*rmesa->get_ust)( & ust );
   if ( missed_target ) {
      rmesa->swap_missed_count++;
      rmesa->swap_missed_ust = ust - rmesa->swap_ust;
   }

   rmesa->swap_ust = ust;

   sched_yield();
}
static void
copy(int fd, uint32_t dst, uint32_t src)
{
	uint32_t batch[1024], *b = batch;
	struct drm_i915_gem_relocation_entry reloc[2], *r = reloc;
	struct drm_i915_gem_exec_object2 obj[3];
	struct drm_i915_gem_execbuffer2 exec;
	uint32_t handle;
	int ret;

	/* invariant state */
	*b++ = (_3DSTATE_AA_CMD |
		AA_LINE_ECAAR_WIDTH_ENABLE |
		AA_LINE_ECAAR_WIDTH_1_0 |
		AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
	*b++ = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
		IAB_MODIFY_ENABLE |
		IAB_MODIFY_FUNC | (BLENDFUNC_ADD << IAB_FUNC_SHIFT) |
		IAB_MODIFY_SRC_FACTOR | (BLENDFACT_ONE <<
					 IAB_SRC_FACTOR_SHIFT) |
		IAB_MODIFY_DST_FACTOR | (BLENDFACT_ZERO <<
					 IAB_DST_FACTOR_SHIFT));
	*b++ = (_3DSTATE_DFLT_DIFFUSE_CMD);
	*b++ = (0);
	*b++ = (_3DSTATE_DFLT_SPEC_CMD);
	*b++ = (0);
	*b++ = (_3DSTATE_DFLT_Z_CMD);
	*b++ = (0);
	*b++ = (_3DSTATE_COORD_SET_BINDINGS |
		CSB_TCB(0, 0) |
		CSB_TCB(1, 1) |
		CSB_TCB(2, 2) |
		CSB_TCB(3, 3) |
		CSB_TCB(4, 4) |
		CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7));
	*b++ = (_3DSTATE_RASTER_RULES_CMD |
		ENABLE_POINT_RASTER_RULE |
		OGL_POINT_RASTER_RULE |
		ENABLE_LINE_STRIP_PROVOKE_VRTX |
		ENABLE_TRI_FAN_PROVOKE_VRTX |
		LINE_STRIP_PROVOKE_VRTX(1) |
		TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D);
	*b++ = (_3DSTATE_MODES_4_CMD |
		ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(LOGICOP_COPY) |
		ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff) |
		ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(0xff));
	*b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | I1_LOAD_S(4) | I1_LOAD_S(5) | 2);
	*b++ = (0x00000000);	/* Disable texture coordinate wrap-shortest */
	*b++ = ((1 << S4_POINT_WIDTH_SHIFT) |
		S4_LINE_WIDTH_ONE |
		S4_CULLMODE_NONE |
		S4_VFMT_XY);
	*b++ = (0x00000000);	/* Stencil. */
	*b++ = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
	*b++ = (_3DSTATE_SCISSOR_RECT_0_CMD);
	*b++ = (0);
	*b++ = (0);
	*b++ = (_3DSTATE_DEPTH_SUBRECT_DISABLE);
	*b++ = (_3DSTATE_LOAD_INDIRECT | 0);	/* disable indirect state */
	*b++ = (0);
	*b++ = (_3DSTATE_STIPPLE);
	*b++ = (0x00000000);
	*b++ = (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);

	/* samler state */
#define TEX_COUNT 1
	*b++ = (_3DSTATE_MAP_STATE | (3 * TEX_COUNT));
	*b++ = ((1 << TEX_COUNT) - 1);
	*b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_SAMPLER, 0); b++;
	*b++ = (MAPSURF_32BIT | MT_32BIT_ARGB8888 |
		MS3_TILED_SURFACE |
		(HEIGHT - 1) << MS3_HEIGHT_SHIFT |
		(WIDTH - 1) << MS3_WIDTH_SHIFT);
	*b++ = ((WIDTH-1) << MS4_PITCH_SHIFT);

	*b++ = (_3DSTATE_SAMPLER_STATE | (3 * TEX_COUNT));
	*b++ = ((1 << TEX_COUNT) - 1);
	*b++ = (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT |
		FILTER_NEAREST << SS2_MAG_FILTER_SHIFT |
		FILTER_NEAREST << SS2_MIN_FILTER_SHIFT);
	*b++ = (TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT |
		TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT |
		0 << SS3_TEXTUREMAP_INDEX_SHIFT);
	*b++ = (0x00000000);

	/* render target state */
	*b++ = (_3DSTATE_BUF_INFO_CMD);
	*b++ = (BUF_3D_ID_COLOR_BACK | BUF_3D_TILED_SURFACE |  WIDTH*4);
	*b = fill_reloc(r++, b-batch, dst,
			I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
	b++;

	*b++ = (_3DSTATE_DST_BUF_VARS_CMD);
	*b++ = (COLR_BUF_ARGB8888 |
		DSTORG_HORT_BIAS(0x8) |
		DSTORG_VERT_BIAS(0x8));

	/* draw rect is unconditional */
	*b++ = (_3DSTATE_DRAW_RECT_CMD);
	*b++ = (0x00000000);
	*b++ = (0x00000000);	/* ymin, xmin */
	*b++ = (DRAW_YMAX(HEIGHT - 1) |
		DRAW_XMAX(WIDTH - 1));
	/* yorig, xorig (relate to color buffer?) */
	*b++ = (0x00000000);

	/* texfmt */
	*b++ = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(1) | I1_LOAD_S(2) | I1_LOAD_S(6) | 2);
	*b++ = ((4 << S1_VERTEX_WIDTH_SHIFT) | (4 << S1_VERTEX_PITCH_SHIFT));
	*b++ = (~S2_TEXCOORD_FMT(0, TEXCOORDFMT_NOT_PRESENT) |
		S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D));
	*b++ = (S6_CBUF_BLEND_ENABLE | S6_COLOR_WRITE_ENABLE |
		BLENDFUNC_ADD << S6_CBUF_BLEND_FUNC_SHIFT |
		BLENDFACT_ONE << S6_CBUF_SRC_BLEND_FACT_SHIFT |
		BLENDFACT_ZERO << S6_CBUF_DST_BLEND_FACT_SHIFT);

	/* pixel shader */
	*b++ = (_3DSTATE_PIXEL_SHADER_PROGRAM | (1 + 3*3 - 2));
	/* decl FS_T0 */
	*b++ = (D0_DCL |
		REG_TYPE(FS_T0) << D0_TYPE_SHIFT |
		REG_NR(FS_T0) << D0_NR_SHIFT |
		((REG_TYPE(FS_T0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0));
	*b++ = (0);
	*b++ = (0);
	/* decl FS_S0 */
	*b++ = (D0_DCL |
		(REG_TYPE(FS_S0) << D0_TYPE_SHIFT) |
		(REG_NR(FS_S0) << D0_NR_SHIFT) |
		((REG_TYPE(FS_S0) != REG_TYPE_S) ? D0_CHANNEL_ALL : 0));
	*b++ = (0);
	*b++ = (0);
	/* texld(FS_OC, FS_S0, FS_T0 */
	*b++ = (T0_TEXLD |
		(REG_TYPE(FS_OC) << T0_DEST_TYPE_SHIFT) |
		(REG_NR(FS_OC) << T0_DEST_NR_SHIFT) |
		(REG_NR(FS_S0) << T0_SAMPLER_NR_SHIFT));
	*b++ = ((REG_TYPE(FS_T0) << T1_ADDRESS_REG_TYPE_SHIFT) |
		(REG_NR(FS_T0) << T1_ADDRESS_REG_NR_SHIFT));
	*b++ = (0);

	*b++ = (PRIM3D_RECTLIST | (3*4 - 1));
	*b++ = pack_float(WIDTH);
	*b++ = pack_float(HEIGHT);
	*b++ = pack_float(WIDTH);
	*b++ = pack_float(HEIGHT);

	*b++ = pack_float(0);
	*b++ = pack_float(HEIGHT);
	*b++ = pack_float(0);
	*b++ = pack_float(HEIGHT);

	*b++ = pack_float(0);
	*b++ = pack_float(0);
	*b++ = pack_float(0);
	*b++ = pack_float(0);

	*b++ = MI_BATCH_BUFFER_END;
	if ((b - batch) & 1)
		*b++ = 0;

	igt_assert(b - batch <= 1024);
	handle = gem_create(fd, 4096);
	gem_write(fd, handle, 0, batch, (b-batch)*sizeof(batch[0]));

	igt_assert(r-reloc == 2);

	obj[0].handle = dst;
	obj[0].relocation_count = 0;
	obj[0].relocs_ptr = 0;
	obj[0].alignment = 0;
	obj[0].offset = 0;
	obj[0].flags = 0;
	obj[0].rsvd1 = 0;
	obj[0].rsvd2 = 0;

	obj[1].handle = src;
	obj[1].relocation_count = 0;
	obj[1].relocs_ptr = 0;
	obj[1].alignment = 0;
	obj[1].offset = 0;
	obj[1].flags = 0;
	obj[1].rsvd1 = 0;
	obj[1].rsvd2 = 0;

	obj[2].handle = handle;
	obj[2].relocation_count = 2;
	obj[2].relocs_ptr = (uintptr_t)reloc;
	obj[2].alignment = 0;
	obj[2].offset = 0;
	obj[2].flags = 0;
	obj[2].rsvd1 = obj[2].rsvd2 = 0;

	exec.buffers_ptr = (uintptr_t)obj;
	exec.buffer_count = 3;
	exec.batch_start_offset = 0;
	exec.batch_len = (b-batch)*sizeof(batch[0]);
	exec.DR1 = exec.DR4 = 0;
	exec.num_cliprects = 0;
	exec.cliprects_ptr = 0;
	exec.flags = 0;
	i915_execbuffer2_set_context_id(exec, 0);
	exec.rsvd2 = 0;

	ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
	while (ret && errno == EBUSY) {
		drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
		ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
	}
	igt_assert_eq(ret, 0);

	gem_close(fd, handle);
}
Ejemplo n.º 21
0
int i830_check_copy(int fd)
{
   return drmCommandNone(fd, DRM_I830_DOCOPY);
}
Ejemplo n.º 22
0
void r200PageFlip( const __DRIdrawablePrivate *dPriv )
{
   r200ContextPtr rmesa;
   GLint ret;
   GLboolean   missed_target;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   rmesa = (r200ContextPtr) dPriv->driContextPriv->driverPrivate;

   if ( R200_DEBUG & DEBUG_IOCTL ) {
      fprintf(stderr, "%s: pfCurrentPage: %d\n", __FUNCTION__,
	      rmesa->sarea->pfCurrentPage);
   }

   R200_FIREVERTICES( rmesa );
   LOCK_HARDWARE( rmesa );

   if (!dPriv->numClipRects) {
      UNLOCK_HARDWARE( rmesa );
      usleep( 10000 );		/* throttle invisible client 10ms */
      return;
   }

   /* Need to do this for the perf box placement:
    */
   {
      drm_clip_rect_t *box = dPriv->pClipRects;
      drm_clip_rect_t *b = rmesa->sarea->boxes;
      b[0] = box[0];
      rmesa->sarea->nbox = 1;
   }

   /* Throttle the frame rate -- only allow a few pending swap buffers
    * request at a time.
    */
   r200WaitForFrameCompletion( rmesa );
   UNLOCK_HARDWARE( rmesa );
   driWaitForVBlank( dPriv, & rmesa->vbl_seq, rmesa->vblank_flags, & missed_target );
   if ( missed_target ) {
      rmesa->swap_missed_count++;
      (void) (*rmesa->get_ust)( & rmesa->swap_missed_ust );
   }
   LOCK_HARDWARE( rmesa );

   ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_FLIP );

   UNLOCK_HARDWARE( rmesa );

   if ( ret ) {
      fprintf( stderr, "DRM_RADEON_FLIP: return = %d\n", ret );
      exit( 1 );
   }

   rmesa->swap_count++;
   (void) (*rmesa->get_ust)( & rmesa->swap_ust );

   if ( rmesa->sarea->pfCurrentPage == 1 ) {
	 rmesa->state.color.drawOffset = rmesa->r200Screen->frontOffset;
	 rmesa->state.color.drawPitch  = rmesa->r200Screen->frontPitch;
   } else {
	 rmesa->state.color.drawOffset = rmesa->r200Screen->backOffset;
	 rmesa->state.color.drawPitch  = rmesa->r200Screen->backPitch;
   }

   R200_STATECHANGE( rmesa, ctx );
   rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
					   + rmesa->r200Screen->fbLocation;
   rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
}
static void blt_copy(int fd, uint32_t dst, uint32_t src)
{
	uint32_t batch[1024], *b = batch;
	struct drm_i915_gem_relocation_entry reloc[2], *r = reloc;
	struct drm_i915_gem_exec_object2 obj[3];
	struct drm_i915_gem_execbuffer2 exec;
	uint32_t handle;
	int ret;

	*b++ = (XY_SRC_COPY_BLT_CMD |
		XY_SRC_COPY_BLT_WRITE_ALPHA |
		XY_SRC_COPY_BLT_WRITE_RGB);
	*b++ = 3 << 24 | 0xcc << 16 | WIDTH * 4;
	*b++ = 0;
	*b++ = HEIGHT << 16 | WIDTH;
	*b = fill_reloc(r++, b-batch, dst,
			I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); b++;
	*b++ = 0;
	*b++ = WIDTH*4;
	*b = fill_reloc(r++, b-batch, src, I915_GEM_DOMAIN_RENDER, 0); b++;

	*b++ = MI_BATCH_BUFFER_END;
	if ((b - batch) & 1)
		*b++ = 0;

	assert(b - batch <= 1024);
	handle = gem_create(fd, 4096);
	gem_write(fd, handle, 0, (b-batch)*sizeof(batch[0]), batch);

	assert(r-reloc == 2);

	obj[0].handle = dst;
	obj[0].relocation_count = 0;
	obj[0].relocs_ptr = 0;
	obj[0].alignment = 0;
	obj[0].offset = 0;
	obj[0].flags = EXEC_OBJECT_NEEDS_FENCE;
	obj[0].rsvd1 = 0;
	obj[0].rsvd2 = 0;

	obj[1].handle = src;
	obj[1].relocation_count = 0;
	obj[1].relocs_ptr = 0;
	obj[1].alignment = 0;
	obj[1].offset = 0;
	obj[1].flags = EXEC_OBJECT_NEEDS_FENCE;
	obj[1].rsvd1 = 0;
	obj[1].rsvd2 = 0;

	obj[2].handle = handle;
	obj[2].relocation_count = 2;
	obj[2].relocs_ptr = (uintptr_t)reloc;
	obj[2].alignment = 0;
	obj[2].offset = 0;
	obj[2].flags = 0;
	obj[2].rsvd1 = obj[2].rsvd2 = 0;

	exec.buffers_ptr = (uintptr_t)obj;
	exec.buffer_count = 3;
	exec.batch_start_offset = 0;
	exec.batch_len = (b-batch)*sizeof(batch[0]);
	exec.DR1 = exec.DR4 = 0;
	exec.num_cliprects = 0;
	exec.cliprects_ptr = 0;
	exec.flags = 0;
	exec.rsvd1 = exec.rsvd2 = 0;

	ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
	while (ret && errno == EBUSY) {
		drmCommandNone(fd, DRM_I915_GEM_THROTTLE);
		ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &exec);
	}
	assert(ret == 0);

	gem_close(fd, handle);
}
Ejemplo n.º 24
0
/*
 * Correct a drawablePrivate's set of vblank flags WRT the current context.
 * When considering multiple crtcs.
 */
GLuint
intelFixupVblank(struct intel_context *intel, __DRIdrawablePrivate *dPriv)
{
   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
      volatile drm_i915_sarea_t *sarea = intel->sarea;
      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
				     .x2 = sarea->planeA_x + sarea->planeA_w,
				     .y2 = sarea->planeA_y + sarea->planeA_h };
      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
				     .x2 = sarea->planeB_x + sarea->planeB_w,
				     .y2 = sarea->planeB_y + sarea->planeB_h };
      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
      GLuint flags = dPriv->vblFlags;

      /* Update vblank info
       */
      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
      } else {
	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
      }

      /* Do the stupid test: Is one of them actually disabled?
       */
      if (sarea->planeA_w == 0 || sarea->planeA_h == 0) {
	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
      } else if (sarea->planeB_w == 0 || sarea->planeB_h == 0) {
	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
      }

      return flags;
   } else {
      return dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
   }
}


/**
 * Called from driSwapBuffers()
 */
void
intelSwapBuffers(__DRIdrawablePrivate * dPriv)
{
   __DRIscreenPrivate *psp = dPriv->driScreenPriv;

   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      GET_CURRENT_CONTEXT(ctx);
      struct intel_context *intel;

      if (ctx == NULL)
	 return;

      intel = intel_context(ctx);

      if (ctx->Visual.doubleBufferMode) {
	 GLboolean missed_target;
	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
	 int64_t ust;
         
	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */

	/*
	 * The old swapping ioctl was incredibly racy, just wait for vblank
	 * and do the swap ourselves.
	 */
	 driWaitForVBlank(dPriv, &missed_target);

	 /*
	  * Update each buffer's vbl_pending so we don't get too out of
	  * sync
	  */
	 intel_get_renderbuffer(&intel_fb->Base,
		   		BUFFER_BACK_LEFT)->vbl_pending = dPriv->vblSeq;
         intel_get_renderbuffer(&intel_fb->Base,
		   		BUFFER_FRONT_LEFT)->vbl_pending = dPriv->vblSeq;

	 intelCopyBuffer(dPriv, NULL);

	 intel_fb->swap_count++;
	 (*psp->systemTime->getUST) (&ust);
	 if (missed_target) {
	    intel_fb->swap_missed_count++;
	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust;
	 }

	 intel_fb->swap_ust = ust;
      }
      drmCommandNone(intel->driFd, DRM_I915_GEM_THROTTLE);
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
   }
}


/**
 * Called from driCopySubBuffer()
 */
void
intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
{
   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
      struct intel_context *intel =
         (struct intel_context *) dPriv->driContextPriv->driverPrivate;
      GLcontext *ctx = &intel->ctx;

      if (ctx->Visual.doubleBufferMode) {
         drm_clip_rect_t rect;
         rect.x1 = x + dPriv->x;
         rect.y1 = (dPriv->h - y - h) + dPriv->y;
         rect.x2 = rect.x1 + w;
         rect.y2 = rect.y1 + h;
         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
         intelCopyBuffer(dPriv, &rect);
      }
   }
   else {
      /* XXX this shouldn't be an error but we can't handle it for now */
      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
   }
}


/**
 * This will be called whenever the currently bound window is moved/resized.
 * XXX: actually, it seems to NOT be called when the window is only moved (BP).
 */
void
intelWindowMoved(struct intel_context *intel)
{
   GLcontext *ctx = &intel->ctx;
   __DRIdrawablePrivate *dPriv = intel->driDrawable;
   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;

   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
      GLuint flags = intelFixupVblank(intel, dPriv);

      /* Check to see if we changed pipes */
      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
	 int64_t count;
	 drmVBlank vbl;
	 int i;

	 /*
	  * Deal with page flipping
	  */
	 vbl.request.type = DRM_VBLANK_ABSOLUTE;

	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
	    vbl.request.type |= DRM_VBLANK_SECONDARY;
	 }

	 for (i = 0; i < 2; i++) {
	    if (!intel_fb->color_rb[i] ||
		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=
		(1<<23))
	       continue;

	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;
	    drmWaitVBlank(intel->driFd, &vbl);
	 }

	 /*
	  * Update msc_base from old pipe
	  */
	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
	 dPriv->msc_base = count;
	 /*
	  * Then get new vblank_base and vblSeq values
	  */
	 dPriv->vblFlags = flags;
	 driGetCurrentVBlank(dPriv);
	 dPriv->vblank_base = dPriv->vblSeq;

	 intel_fb->vbl_waited = dPriv->vblSeq;

	 for (i = 0; i < 2; i++) {
	    if (intel_fb->color_rb[i])
	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited;
	 }
      }
   } else {
      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
   }

   /* Update Mesa's notion of window size */
   driUpdateFramebufferSize(ctx, dPriv);
   intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */

   /* Update hardware scissor */
   if (ctx->Driver.Scissor != NULL) {
      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
			  ctx->Scissor.Width, ctx->Scissor.Height);
   }

   /* Re-calculate viewport related state */
   if (ctx->Driver.DepthRange != NULL)
      ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
}
Ejemplo n.º 25
0
/*
 * Copy the back buffer to the front buffer.
 */
void mgaSwapBuffers(Display *dpy, void *drawablePrivate)
{
   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
   mgaContextPtr mmesa;
   XF86DRIClipRectPtr pbox;
   GLint nbox;
   GLint ret, wait = 0;
   GLint i;
   GLuint last_frame, last_wrap;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;

   FLUSH_BATCH( mmesa );

   mgaWaitForVBlank( mmesa );

   LOCK_HARDWARE( mmesa );

   last_frame = mmesa->sarea->last_frame.head;
   last_wrap = mmesa->sarea->last_frame.wrap;

   /* FIXME: Add a timeout to this loop...
    */
   while ( 1 ) {
      if ( last_wrap < mmesa->sarea->last_wrap ||
	   ( last_wrap == mmesa->sarea->last_wrap &&
	     last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -
			    mmesa->primary_offset) ) ) {
	 break;
      }
      if ( 0 ) {
	 wait++;
	 fprintf( stderr, "   last: head=0x%06x wrap=%d\n",
		  last_frame, last_wrap );
	 fprintf( stderr, "   head: head=0x%06lx wrap=%d\n",
		  (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),
		  mmesa->sarea->last_wrap );
      }
      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );

      for ( i = 0 ; i < 1024 ; i++ ) {
	 /* Don't just hammer the register... */
      }
   }
   if ( wait )
      fprintf( stderr, "\n" );

   /* Use the frontbuffer cliprects
    */
   if (mmesa->dirty_cliprects & MGA_FRONT)
      mgaUpdateRects( mmesa, MGA_FRONT );


   pbox = dPriv->pClipRects;
   nbox = dPriv->numClipRects;

   for (i = 0 ; i < nbox ; )
   {
      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
      XF86DRIClipRectPtr b = mmesa->sarea->boxes;

      mmesa->sarea->nbox = nr - i;

      for ( ; i < nr ; i++)
	 *b++ = pbox[i];

      if (0)
	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");

      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
      if ( ret ) {
	 printf("send swap retcode = %d\n", ret);
	 exit(1);
      }
   }

   UNLOCK_HARDWARE( mmesa );

   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
Ejemplo n.º 26
0
int i810_check_copy(int fd)
{
   return(drmCommandNone(fd, DRM_I810_DOCOPY));
}
Ejemplo n.º 27
0
/* Copy the back color buffer to the front color buffer.
 */
void r128CopyBuffer( const __DRIdrawablePrivate *dPriv )
{
    r128ContextPtr rmesa;
    GLint nbox, i, ret;
    GLboolean missed_target;

    assert(dPriv);
    assert(dPriv->driContextPriv);
    assert(dPriv->driContextPriv->driverPrivate);

    rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;

    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
        fprintf( stderr, "\n********************************\n" );
        fprintf( stderr, "\n%s( %p )\n\n",
                 __FUNCTION__, (void *)rmesa->glCtx );
        fflush( stderr );
    }

    FLUSH_BATCH( rmesa );

    LOCK_HARDWARE( rmesa );

    /* Throttle the frame rate -- only allow one pending swap buffers
     * request at a time.
     */
    if ( !r128WaitForFrameCompletion( rmesa ) ) {
        rmesa->hardwareWentIdle = 1;
    } else {
        rmesa->hardwareWentIdle = 0;
    }

    UNLOCK_HARDWARE( rmesa );
    driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
    LOCK_HARDWARE( rmesa );

    nbox = dPriv->numClipRects;	/* must be in locked region */

    for ( i = 0 ; i < nbox ; ) {
        GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , nbox );
        drm_clip_rect_t *box = dPriv->pClipRects;
        drm_clip_rect_t *b = rmesa->sarea->boxes;
        GLint n = 0;

        for ( ; i < nr ; i++ ) {
            *b++ = box[i];
            n++;
        }
        rmesa->sarea->nbox = n;

        ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP );

        if ( ret ) {
            UNLOCK_HARDWARE( rmesa );
            fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret );
            exit( 1 );
        }
    }

    if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) {
        i = 0;
        do {
            ret = drmCommandNone(rmesa->driFd, DRM_R128_CCE_IDLE);
        } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY );
    }

    UNLOCK_HARDWARE( rmesa );

    rmesa->new_state |= R128_NEW_CONTEXT;
    rmesa->dirty |= (R128_UPLOAD_CONTEXT |
                     R128_UPLOAD_MASKS |
                     R128_UPLOAD_CLIPRECTS);

#if ENABLE_PERF_BOXES
    /* Log the performance counters if necessary */
    r128PerformanceCounters( rmesa );
#endif
}
/*
 * Copy the back buffer to the front buffer.
 */
void mgaCopyBuffer( __DRIdrawablePrivate *dPriv )
{
   mgaContextPtr mmesa;
   drm_clip_rect_t *pbox;
   GLint nbox;
   GLint ret;
   GLint i;
   GLboolean   missed_target;


   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;

   FLUSH_BATCH( mmesa );

   mgaWaitForFrameCompletion( mmesa );
   driWaitForVBlank( dPriv, & missed_target );
   if ( missed_target ) {
      mmesa->swap_missed_count++;
      (void) (*dri_interface->getUST)( & mmesa->swap_missed_ust );
   }
   LOCK_HARDWARE( mmesa );

   /* Use the frontbuffer cliprects
    */
   if (mmesa->dirty_cliprects & MGA_FRONT)
      mgaUpdateRects( mmesa, MGA_FRONT );


   pbox = dPriv->pClipRects;
   nbox = dPriv->numClipRects;

   for (i = 0 ; i < nbox ; )
   {
      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
      drm_clip_rect_t *b = mmesa->sarea->boxes;

      mmesa->sarea->nbox = nr - i;

      for ( ; i < nr ; i++)
	 *b++ = pbox[i];

      if (0)
	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");

      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
      if ( ret ) {
	 printf("send swap retcode = %d\n", ret);
	 exit(1);
      }
   }

   (void) mgaSetFence( mmesa, & mmesa->last_frame_fence );
   UNLOCK_HARDWARE( mmesa );

   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
   mmesa->swap_count++;
   (void) (*dri_interface->getUST)( & mmesa->swap_ust );
}
Ejemplo n.º 29
0
void r128PageFlip( const __DRIdrawablePrivate *dPriv )
{
    r128ContextPtr rmesa;
    GLint ret;
    GLboolean missed_target;

    assert(dPriv);
    assert(dPriv->driContextPriv);
    assert(dPriv->driContextPriv->driverPrivate);

    rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate;

    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
        fprintf( stderr, "\n%s( %p ): page=%d\n\n",
                 __FUNCTION__, (void *)rmesa->glCtx, rmesa->sarea->pfCurrentPage );
    }

    FLUSH_BATCH( rmesa );

    LOCK_HARDWARE( rmesa );

    /* Throttle the frame rate -- only allow one pending swap buffers
     * request at a time.
     */
    if ( !r128WaitForFrameCompletion( rmesa ) ) {
        rmesa->hardwareWentIdle = 1;
    } else {
        rmesa->hardwareWentIdle = 0;
    }

    UNLOCK_HARDWARE( rmesa );
    driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target );
    LOCK_HARDWARE( rmesa );

    /* The kernel will have been initialized to perform page flipping
     * on a swapbuffers ioctl.
     */
    ret = drmCommandNone( rmesa->driFd, DRM_R128_FLIP );

    UNLOCK_HARDWARE( rmesa );

    if ( ret ) {
        fprintf( stderr, "DRM_R128_FLIP: return = %d\n", ret );
        exit( 1 );
    }

    /* Get ready for drawing next frame.  Update the renderbuffers'
     * flippedOffset/Pitch fields so we draw into the right place.
     */
    driFlipRenderbuffers(rmesa->glCtx->WinSysDrawBuffer,
                         rmesa->sarea->pfCurrentPage);

    rmesa->new_state |= R128_NEW_WINDOW;

    /* FIXME: Do we need this anymore? */
    rmesa->new_state |= R128_NEW_CONTEXT;
    rmesa->dirty |= (R128_UPLOAD_CONTEXT |
                     R128_UPLOAD_MASKS |
                     R128_UPLOAD_CLIPRECTS);

#if ENABLE_PERF_BOXES
    /* Log the performance counters if necessary */
    r128PerformanceCounters( rmesa );
#endif
}