⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgaioctl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. *//** * \file mgaioctl.c * MGA IOCTL related wrapper functions. * * \author Keith Whitwell <keith@tungstengraphics.com> * \author Gareth Hughes <gareth@valinux.com> */#include <errno.h>#include "mtypes.h"#include "macros.h"#include "dd.h"#include "swrast/swrast.h"#include "mm.h"#include "drm.h"#include "mga_drm.h"#include "mgacontext.h"#include "mgadd.h"#include "mgastate.h"#include "mgatex.h"#include "mgavb.h"#include "mgaioctl.h"#include "mgatris.h"#include "vblank.h"static intmgaSetFence( mgaContextPtr mmesa, uint32_t * fence ){    int ret = ENOSYS;    if ( mmesa->driScreen->drm_version.minor >= 2 ) {	ret = drmCommandWriteRead( mmesa->driScreen->fd, DRM_MGA_SET_FENCE,				   fence, sizeof( uint32_t ));	if (ret) {	    fprintf(stderr, "drmMgaSetFence: %d\n", ret);	    exit(1);	}    }    return ret;}static intmgaWaitFence( mgaContextPtr mmesa, uint32_t fence, uint32_t * curr_fence ){    int ret = ENOSYS;    if ( mmesa->driScreen->drm_version.minor >= 2 ) {	uint32_t temp = fence;		ret = drmCommandWriteRead( mmesa->driScreen->fd,				   DRM_MGA_WAIT_FENCE,				   & temp, sizeof( uint32_t ));	if (ret) {	   fprintf(stderr, "drmMgaSetFence: %d\n", ret);	    exit(1);	}	if ( curr_fence ) {	    *curr_fence = temp;	}    }    return ret;}static void mga_iload_dma_ioctl(mgaContextPtr mmesa,				unsigned long dest,				int length){   drmBufPtr buf = mmesa->iload_buffer;   drm_mga_iload_t iload;   int ret, i;   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "DRM_IOCTL_MGA_ILOAD idx %d dst %x length %d\n",	      buf->idx, (int) dest, length);   if ( (length & MGA_ILOAD_MASK) != 0 ) {      UNLOCK_HARDWARE( mmesa );      fprintf( stderr, "%s: Invalid ILOAD datasize (%d), must be "	       "multiple of %u.\n", __FUNCTION__, length, MGA_ILOAD_ALIGN );      exit( 1 );   }   iload.idx = buf->idx;   iload.dstorg = dest;   iload.length = length;   i = 0;   do {      ret = drmCommandWrite( mmesa->driFd, DRM_MGA_ILOAD,                              &iload, sizeof(iload) );   } while ( ret == -EBUSY && i++ < DRM_MGA_IDLE_RETRY );   if ( ret < 0 ) {      printf("send iload retcode = %d\n", ret);      exit(1);   }   mmesa->iload_buffer = 0;   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "finished iload dma put\n");}drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ){   int idx = 0;   int size = 0;   drmDMAReq dma;   int retcode;   drmBufPtr buf;   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr,  "Getting dma buffer\n");   dma.context = mmesa->hHWContext;   dma.send_count = 0;   dma.send_list = NULL;   dma.send_sizes = NULL;   dma.flags = 0;   dma.request_count = 1;   dma.request_size = MGA_BUFFER_SIZE;   dma.request_list = &idx;   dma.request_sizes = &size;   dma.granted_count = 0;   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "drmDMA (get) ctx %d count %d size 0x%x\n",	   dma.context, dma.request_count,	   dma.request_size);   while (1) {      retcode = drmDMA(mmesa->driFd, &dma);      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)	 fprintf(stderr, "retcode %d sz %d idx %d count %d\n",		 retcode,		 dma.request_sizes[0],		 dma.request_list[0],		 dma.granted_count);      if (retcode == 0 &&	  dma.request_sizes[0] &&	  dma.granted_count)	 break;      if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)	 fprintf(stderr, "\n\nflush");      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT );   }   buf = &(mmesa->mgaScreen->bufs->list[idx]);   buf->used = 0;   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr,	   "drmDMA (get) returns size[0] 0x%x idx[0] %d\n"	   "dma_buffer now: buf idx: %d size: %d used: %d addr %p\n",	   dma.request_sizes[0], dma.request_list[0],	   buf->idx, buf->total,	   buf->used, buf->address);   if (MGA_DEBUG&DEBUG_VERBOSE_IOCTL)      fprintf(stderr, "finished getbuffer\n");   return buf;}static voidmgaClear( GLcontext *ctx, GLbitfield mask ){   mgaContextPtr mmesa = MGA_CONTEXT(ctx);   __DRIdrawablePrivate *dPriv = mmesa->driDrawable;   GLuint flags = 0;   GLuint clear_color = mmesa->ClearColor;   GLuint clear_depth = 0;   GLuint color_mask = 0;   GLuint depth_mask = 0;   int ret;   int i;   static int nrclears;   drm_mga_clear_t clear;   GLint cx, cy, cw, ch;   FLUSH_BATCH( mmesa );   if ( mask & BUFFER_BIT_FRONT_LEFT ) {      flags |= MGA_FRONT;      color_mask = mmesa->setup.plnwt;      mask &= ~BUFFER_BIT_FRONT_LEFT;   }   if ( mask & BUFFER_BIT_BACK_LEFT ) {      flags |= MGA_BACK;      color_mask = mmesa->setup.plnwt;      mask &= ~BUFFER_BIT_BACK_LEFT;   }   if ( (mask & BUFFER_BIT_DEPTH) && ctx->Depth.Mask ) {      flags |= MGA_DEPTH;      clear_depth = (mmesa->ClearDepth & mmesa->depth_clear_mask);      depth_mask |= mmesa->depth_clear_mask;      mask &= ~BUFFER_BIT_DEPTH;   }   if ( (mask & BUFFER_BIT_STENCIL) && mmesa->hw_stencil ) {      flags |= MGA_DEPTH;      clear_depth |= (ctx->Stencil.Clear & mmesa->stencil_clear_mask);      depth_mask |= mmesa->stencil_clear_mask;      mask &= ~BUFFER_BIT_STENCIL;   }   if ( flags ) {      LOCK_HARDWARE( mmesa );      /* compute region after locking: */      cx = ctx->DrawBuffer->_Xmin;      cy = ctx->DrawBuffer->_Ymin;      cw = ctx->DrawBuffer->_Xmax - cx;      ch = ctx->DrawBuffer->_Ymax - cy;      if ( mmesa->dirty_cliprects )	 mgaUpdateRects( mmesa, (MGA_FRONT | MGA_BACK) );      /* flip top to bottom */      cy = dPriv->h-cy-ch;      cx += mmesa->drawX;      cy += mmesa->drawY;      if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )	 fprintf( stderr, "Clear, bufs %x nbox %d\n",		  (int)flags, (int)mmesa->numClipRects );      for (i = 0 ; i < mmesa->numClipRects ; )      {	 int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, mmesa->numClipRects);	 drm_clip_rect_t *box = mmesa->pClipRects;	 drm_clip_rect_t *b = mmesa->sarea->boxes;	 int n = 0;	 if (cw != dPriv->w || ch != dPriv->h) {            /* clear subregion */	    for ( ; i < nr ; i++) {	       GLint x = box[i].x1;	       GLint y = box[i].y1;	       GLint w = box[i].x2 - x;	       GLint h = box[i].y2 - y;	       if (x < cx) w -= cx - x, x = cx;	       if (y < cy) h -= cy - y, y = cy;	       if (x + w > cx + cw) w = cx + cw - x;	       if (y + h > cy + ch) h = cy + ch - y;	       if (w <= 0) continue;	       if (h <= 0) continue;	       b->x1 = x;	       b->y1 = y;	       b->x2 = x + w;	       b->y2 = y + h;	       b++;	       n++;	    }	 } else {            /* clear whole window */	    for ( ; i < nr ; i++) {	       *b++ = box[i];	       n++;	    }	 }	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )	    fprintf( stderr,		     "DRM_IOCTL_MGA_CLEAR flag 0x%x color %x depth %x nbox %d\n",		     flags, clear_color, clear_depth, mmesa->sarea->nbox );	 mmesa->sarea->nbox = n;         clear.flags = flags;         clear.clear_color = clear_color;         clear.clear_depth = clear_depth;         clear.color_mask = color_mask;         clear.depth_mask = depth_mask;         ret = drmCommandWrite( mmesa->driFd, DRM_MGA_CLEAR,                                 &clear, sizeof(clear));	 if ( ret ) {	    fprintf( stderr, "send clear retcode = %d\n", ret );	    exit( 1 );	 }	 if ( MGA_DEBUG & DEBUG_VERBOSE_IOCTL )	    fprintf( stderr, "finished clear %d\n", ++nrclears );      }      UNLOCK_HARDWARE( mmesa );      mmesa->dirty |= MGA_UPLOAD_CLIPRECTS|MGA_UPLOAD_CONTEXT;   }   if (mask)       _swrast_Clear( ctx, mask );}/** * Wait for the previous frame of rendering has completed. *  * \param mmesa  Hardware context pointer. * * \bug * The loop in this function should have some sort of a timeout mechanism. * * \warning * This routine used to assume that the hardware lock was held on entry.  It * now assumes that the lock is \b not held on entry. */static void mgaWaitForFrameCompletion( mgaContextPtr mmesa ){    if ( mgaWaitFence( mmesa, mmesa->last_frame_fence, NULL ) == ENOSYS ) {	unsigned wait = 0;	GLuint last_frame;	GLuint last_wrap;	LOCK_HARDWARE( mmesa );	last_frame = mmesa->sarea->last_frame.head;	last_wrap = mmesa->sarea->last_frame.wrap;	/* The DMA routines in the kernel track a couple values in the SAREA	 * that we use here.  The number of times that the primary DMA buffer	 * has "wrapped" around is tracked in last_wrap.  In addition, the	 * wrap count and the buffer position at the end of the last frame are	 * stored in last_frame.wrap and last_frame.head.	 * 	 * By comparing the wrap counts and the current DMA pointer value	 * (read directly from the hardware) to last_frame.head, we can	 * determine when the graphics processor has processed all of the	 * commands for the last frame.	 * 	 * In this case "last frame" means the frame of the *previous* swap-

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -