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

📄 intel_batchbuffer.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** *  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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 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 TUNGSTEN GRAPHICS 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. *  **************************************************************************/#include <stdio.h>#include <errno.h>#include "mtypes.h"#include "context.h"#include "enums.h"#include "vblank.h"#include "intel_reg.h"#include "intel_batchbuffer.h"#include "intel_context.h"/* ================================================================ * Performance monitoring functions */static void intel_fill_box( intelContextPtr intel,			    GLshort x, GLshort y,			    GLshort w, GLshort h,			    GLubyte r, GLubyte g, GLubyte b ){   x += intel->drawX;   y += intel->drawY;   if (x >= 0 && y >= 0 &&       x+w < intel->intelScreen->width &&       y+h < intel->intelScreen->height)      intelEmitFillBlitLocked( intel, 			       intel->intelScreen->cpp,			       intel->intelScreen->back.pitch,			       intel->intelScreen->back.offset,			       x, y, w, h,			       INTEL_PACKCOLOR(intel->intelScreen->fbFormat,					       r,g,b,0xff));}static void intel_draw_performance_boxes( intelContextPtr intel ){   /* Purple box for page flipping    */   if ( intel->perf_boxes & I830_BOX_FLIP )       intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 );   /* Red box if we have to wait for idle at any point    */   if ( intel->perf_boxes & I830_BOX_WAIT )       intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 );   /* Blue box: lost context?    */   if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT )       intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 );   /* Yellow box for texture swaps    */   if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD )       intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 );   /* Green box if hardware never idles (as far as we can tell)    */   if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) )       intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 );   /* Draw bars indicating number of buffers allocated     * (not a great measure, easily confused)    */#if 0   if (intel->dma_used) {      int bar = intel->dma_used / 10240;      if (bar > 100) bar = 100;      if (bar < 1) bar = 1;      intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 );      intel->dma_used = 0;   }#endif   intel->perf_boxes = 0;}static int bad_prim_vertex_nr( int primitive, int nr ){   switch (primitive & PRIM3D_MASK) {   case PRIM3D_POINTLIST:      return nr < 1;   case PRIM3D_LINELIST:      return (nr & 1) || nr == 0;   case PRIM3D_LINESTRIP:      return nr < 2;   case PRIM3D_TRILIST:   case PRIM3D_RECTLIST:      return nr % 3 || nr == 0;   case PRIM3D_POLY:   case PRIM3D_TRIFAN:   case PRIM3D_TRISTRIP:   case PRIM3D_TRISTRIP_RVRSE:      return nr < 3;   default:      return 1;   }	}static void intel_flush_inline_primitive( GLcontext *ctx ){   intelContextPtr intel = INTEL_CONTEXT( ctx );   GLuint used = intel->batch.ptr - intel->prim.start_ptr;   GLuint vertcount;   assert(intel->prim.primitive != ~0);   if (1) {      /* Check vertex size against the vertex we're specifying to       * hardware.  If it's wrong, ditch the primitive.       */       if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size )) 	 goto do_discard;      vertcount = (used - 4)/ (intel->vertex_size * 4);      if (!vertcount)	 goto do_discard;            if (vertcount * intel->vertex_size * 4 != used - 4) {	 fprintf(stderr, "vertex size confusion %d %d\n", used, 		 intel->vertex_size * vertcount * 4);	 goto do_discard;      }      if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {	 fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,		 vertcount);	 goto do_discard;      }   }   if (used < 8)      goto do_discard;   *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | 				    intel->prim.primitive |				    (used/4-2));   goto finished;    do_discard:   intel->batch.ptr -= used;   intel->batch.space += used;   assert(intel->batch.space >= 0); finished:   intel->prim.primitive = ~0;   intel->prim.start_ptr = 0;   intel->prim.flush = 0;}/* Emit a primitive referencing vertices in a vertex buffer. */void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ){   BATCH_LOCALS;   if (0)      fprintf(stderr, "%s %x\n", __FUNCTION__, prim);   /* Finish any in-progress primitive:    */   INTEL_FIREVERTICES( intel );      /* Emit outstanding state:    */   intel->vtbl.emit_state( intel );      /* Make sure there is some space in this buffer:    */   if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) {      intelFlushBatch(intel, GL_TRUE);       intel->vtbl.emit_state( intel );   }#if 1   if (((int)intel->batch.ptr) & 0x4) {      BEGIN_BATCH(1);      OUT_BATCH(0);      ADVANCE_BATCH();   }#endif   /* Emit a slot which will be filled with the inline primitive    * command later.    */   BEGIN_BATCH(2);   OUT_BATCH( 0 );   intel->prim.start_ptr = batch_ptr;   intel->prim.primitive = prim;   intel->prim.flush = intel_flush_inline_primitive;   intel->batch.contains_geometry = 1;   OUT_BATCH( 0 );   ADVANCE_BATCH();}void intelRestartInlinePrimitive( intelContextPtr intel ){   GLuint prim = intel->prim.primitive;   intel_flush_inline_primitive( &intel->ctx );   if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */   intelStartInlinePrimitive( intel, prim );}void intelWrapInlinePrimitive( intelContextPtr intel ){   GLuint prim = intel->prim.primitive;   if (0)      fprintf(stderr, "%s\n", __FUNCTION__);   intel_flush_inline_primitive( &intel->ctx );   intelFlushBatch(intel, GL_TRUE);   intelStartInlinePrimitive( intel, prim );}/* Emit a primitive with space for inline vertices. */GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, 				       int primitive,				       int dwords,				       int vertex_size ){   GLuint *tmp = 0;   BATCH_LOCALS;   if (0)      fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords);   /* Emit outstanding state:    */   intel->vtbl.emit_state( intel );   if ((1+dwords)*4 >= intel->batch.space) {      intelFlushBatch(intel, GL_TRUE);       intel->vtbl.emit_state( intel );   }   if (1) {      int used = dwords * 4;      int vertcount;      /* Check vertex size against the vertex we're specifying to       * hardware.  If it's wrong, ditch the primitive.       */       if (!intel->vtbl.check_vertex_size( intel, vertex_size )) 	 goto do_discard;      vertcount = dwords / vertex_size;            if (dwords % vertex_size) {	 fprintf(stderr, "did not request a whole number of vertices\n");	 goto do_discard;      }      if (bad_prim_vertex_nr( primitive, vertcount )) {	 fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount);	 goto do_discard;      }      if (used < 8)	 goto do_discard;   }   /* Emit 3D_PRIMITIVE commands:    */   BEGIN_BATCH(1 + dwords);   OUT_BATCH( _3DPRIMITIVE | 	      primitive |	      (dwords-1) );   tmp = (GLuint *)batch_ptr;   batch_ptr += dwords * 4;   ADVANCE_BATCH();   intel->batch.contains_geometry = 1; do_discard:   return tmp;}static void intelWaitForFrameCompletion( intelContextPtr intel ){  drm_i915_sarea_t *sarea = (drm_i915_sarea_t *)intel->sarea;   if (intel->do_irqs) {      if (intelGetLastFrame(intel) < sarea->last_dispatch) {	 if (!intel->irqsEmitted) {	    while (intelGetLastFrame (intel) < sarea->last_dispatch)	       ;	 }	 else {	    UNLOCK_HARDWARE( intel ); 	    intelWaitIrq( intel, intel->alloc.irq_emitted );		    LOCK_HARDWARE( intel ); 	 }	 intel->irqsEmitted = 10;      }      if (intel->irqsEmitted) {	 intelEmitIrqLocked( intel );	 intel->irqsEmitted--;      }   }    else {      while (intelGetLastFrame (intel) < sarea->last_dispatch) {	 UNLOCK_HARDWARE( intel ); 	 if (intel->do_usleeps) 	    DO_USLEEP( 1 );	 LOCK_HARDWARE( intel );       }   }}/* * Copy the back buffer to the front buffer.  */void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,		      const drm_clip_rect_t	 *rect){   intelContextPtr intel;   GLboolean   missed_target;   int64_t ust;   if (0)      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 );   intelWaitForFrameCompletion( intel );   if (!rect)   {       UNLOCK_HARDWARE( intel );       driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target );       LOCK_HARDWARE( intel );   }

⌨️ 快捷键说明

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