| /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.7 2002/12/16 16:18:52 dawes Exp $*/ |
| /* |
| * 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. |
| * |
| * Authors: |
| * Keith Whitwell <keith@tungstengraphics.com> |
| */ |
| |
| #ifndef MGALIB_INC |
| #define MGALIB_INC |
| |
| #include <stdint.h> |
| #include "drm.h" |
| #include "mga_drm.h" |
| #include "dri_util.h" |
| #include "mtypes.h" |
| #include "xf86drm.h" |
| #include "mm.h" |
| #include "colormac.h" |
| #include "texmem.h" |
| #include "macros.h" |
| #include "xmlconfig.h" |
| |
| #define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask)) |
| #define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) |
| #define MGA_GET_FIELD(field, val) ((val & ~(field ## _MASK)) >> (field ## _SHIFT)) |
| |
| #define MGA_IS_G200(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G200) |
| #define MGA_IS_G400(mmesa) (mmesa->mgaScreen->chipset == MGA_CARD_TYPE_G400) |
| |
| |
| /* SoftwareFallback |
| * - texture env GL_BLEND -- can be fixed |
| * - 1D and 3D textures |
| * - incomplete textures |
| * - GL_DEPTH_FUNC == GL_NEVER not in h/w |
| */ |
| #define MGA_FALLBACK_TEXTURE 0x1 |
| #define MGA_FALLBACK_DRAW_BUFFER 0x2 |
| #define MGA_FALLBACK_READ_BUFFER 0x4 |
| #define MGA_FALLBACK_BLEND 0x8 |
| #define MGA_FALLBACK_RENDERMODE 0x10 |
| #define MGA_FALLBACK_STENCIL 0x20 |
| #define MGA_FALLBACK_DEPTH 0x40 |
| #define MGA_FALLBACK_BORDER_MODE 0x80 |
| #define MGA_FALLBACK_DISABLE 0x100 |
| |
| |
| /* Use the templated vertex formats: |
| */ |
| #define TAG(x) mga##x |
| #include "tnl_dd/t_dd_vertex.h" |
| #undef TAG |
| |
| typedef struct mga_context_t mgaContext; |
| typedef struct mga_context_t *mgaContextPtr; |
| |
| typedef void (*mga_tri_func)( mgaContextPtr, mgaVertex *, mgaVertex *, |
| mgaVertex * ); |
| typedef void (*mga_line_func)( mgaContextPtr, mgaVertex *, mgaVertex * ); |
| typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * ); |
| |
| |
| |
| /* Texture environment color |
| */ |
| #define RGB_ZERO(c) (((c) & 0xffffff) == 0x000000) |
| #define RGB_ONE(c) (((c) & 0xffffff) == 0xffffff) |
| #define ALPHA_ZERO(c) (((c) >> 24) == 0x00) |
| #define ALPHA_ONE(c) (((c) >> 24) == 0xff) |
| #define RGBA_EQUAL(c) ((c) == PACK_COLOR_8888( (c) & 0xff, (c) & 0xff, \ |
| (c) & 0xff, (c) & 0xff )) |
| |
| struct mga_texture_object_s; |
| struct mga_screen_private_s; |
| |
| #define G200_TEX_MAXLEVELS 5 |
| #define G400_TEX_MAXLEVELS 11 |
| |
| typedef struct mga_texture_object_s |
| { |
| driTextureObject base; |
| |
| /* The G200 only has the ability to use 5 mipmap levels (including the |
| * base level). The G400 does not have this restriction, but it still |
| * only has 5 offset pointers in the hardware. The trick on the G400 is |
| * upto the first 4 offset pointers point to mipmap levels. The last |
| * offset pointer tells how large the preceeding mipmap is. This value is |
| * then used to determine where the remaining mipmaps are. |
| * |
| * For example, if the first offsets[0] through offsets[2] are used as |
| * pointers, then offset[3] will be the size of the mipmap pointed to by |
| * offsets[2]. So mipmap level 3 will be at (offsets[2]+offsets[3]). For |
| * each successive mipmap level, offsets[3] is divided by 4 and added to |
| * the previous address. So mipmap level 4 will be at |
| * (offsets[2]+offsets[3]+(offsets[3] / 4)). |
| * |
| * The last pointer is selected by setting TO_texorgoffsetsel in its |
| * pointer. In the previous example, offset[2] would have |
| * TO_texorgoffsetsel or'ed in before writing it to the hardware. |
| * |
| * In the current driver all of the mipmaps are packed together linearly |
| * with mipmap level 0. Therefore offsets[0] points to the base of the |
| * texture (and has TO_texorgoffsetsel or'ed in), and offsets[1] is the |
| * size of the base texture. |
| * |
| * There is a possible optimization available here. At times the driver |
| * may not be able to allocate a single block of memory for the complete |
| * texture without ejecting some other textures from memory. It may be |
| * possible to put some of the lower mipmap levels (i.e., the larger |
| * mipmaps) in memory separate from the higher levels. |
| * |
| * The implementation should be fairly obvious, but getting "right" would |
| * likely be non-trivial. A first allocation for the entire texture would |
| * be attempted with a flag that says "don't eject other textures." If |
| * that failed, an additional allocation would be attmpted for just the |
| * base map. The process would repeat with the block of lower maps. The |
| * tricky parts would be in detecting when some of the levels had been |
| * ejected from texture memory by other textures and preventing the |
| * 4th allocation (for all the smallest mipmap levels) from kicking out |
| * any of the first three. |
| * |
| * This array holds G400_TEX_MAXLEVELS pointers to remove an if-statement |
| * in a loop in mgaSetTexImages. Values past G200_TEX_MAXLEVELS are not |
| * used. |
| */ |
| GLuint offsets[G400_TEX_MAXLEVELS]; |
| |
| int texelBytes; |
| GLuint age; |
| |
| drm_mga_texture_regs_t setup; |
| |
| /* If one texture dimension wraps with GL_CLAMP and the other with |
| * GL_CLAMP_TO_EDGE, we have to fallback to software. We would also have |
| * to fallback for GL_CLAMP_TO_BORDER. |
| */ |
| GLboolean border_fallback; |
| /* Depending on multitxturing and environment color |
| * GL_BLEND may have to be a software fallback. |
| */ |
| GLboolean texenv_fallback; |
| } mgaTextureObject_t; |
| |
| struct mga_hw_state { |
| GLuint specen; |
| GLuint cull; |
| GLuint cull_dualtex; |
| GLuint stencil; |
| GLuint stencilctl; |
| GLuint stencil_enable; |
| GLuint zmode; |
| GLuint rop; |
| GLuint alpha_func; |
| GLuint alpha_func_enable; |
| GLuint blend_func; |
| GLuint blend_func_enable; |
| GLuint alpha_sel; |
| }; |
| |
| struct mga_context_t { |
| |
| GLcontext *glCtx; |
| unsigned int lastStamp; /* fullscreen breaks dpriv->laststamp, |
| * need to shadow it here. */ |
| |
| /* Hardware state management |
| */ |
| struct mga_hw_state hw; |
| |
| /* Bookkeeping for texturing |
| */ |
| unsigned nr_heaps; |
| driTexHeap * texture_heaps[ MGA_NR_TEX_HEAPS ]; |
| driTextureObject swapped; |
| |
| struct mga_texture_object_s *CurrentTexObj[2]; |
| |
| |
| /* Map GL texture units onto hardware. |
| */ |
| GLuint tmu_source[2]; |
| |
| int texture_depth; |
| |
| /* Manage fallbacks |
| */ |
| GLuint Fallback; |
| |
| /* Texture environment color. |
| */ |
| unsigned int envcolor[2]; |
| GLboolean fcol_used; |
| GLboolean force_dualtex; |
| |
| /* Rasterization state |
| */ |
| GLuint SetupNewInputs; |
| GLuint SetupIndex; |
| GLuint RenderIndex; |
| |
| GLuint hw_primitive; |
| GLenum raster_primitive; |
| GLenum render_primitive; |
| |
| GLubyte *verts; |
| GLint vertex_stride_shift; |
| GLuint vertex_format; |
| GLuint vertex_size; |
| |
| /* Fallback rasterization functions |
| */ |
| mga_point_func draw_point; |
| mga_line_func draw_line; |
| mga_tri_func draw_tri; |
| |
| |
| /* Manage driver and hardware state |
| */ |
| GLuint NewGLState; |
| GLuint dirty; |
| |
| drm_mga_context_regs_t setup; |
| |
| GLuint ClearColor; |
| GLuint ClearDepth; |
| GLuint poly_stipple; |
| GLfloat depth_scale; |
| |
| GLuint depth_clear_mask; |
| GLuint stencil_clear_mask; |
| GLuint hw_stencil; |
| GLuint haveHwStipple; |
| GLfloat hw_viewport[16]; |
| |
| /* Dma buffers |
| */ |
| drmBufPtr vertex_dma_buffer; |
| drmBufPtr iload_buffer; |
| |
| int64_t swap_ust; |
| int64_t swap_missed_ust; |
| |
| GLuint swap_count; |
| GLuint swap_missed_count; |
| |
| uint32_t last_frame_fence; |
| |
| /* Drawable, cliprect and scissor information |
| */ |
| int dirty_cliprects; /* which sets of cliprects are uptodate? */ |
| int draw_buffer; /* which buffer are we rendering to */ |
| unsigned int drawOffset; /* draw buffer address in space */ |
| int readOffset; |
| int drawX, drawY; /* origin of drawable in draw buffer */ |
| int lastX, lastY; /* detect DSTORG bug */ |
| GLuint numClipRects; /* cliprects for the draw buffer */ |
| drm_clip_rect_t *pClipRects; |
| drm_clip_rect_t draw_rect; |
| drm_clip_rect_t scissor_rect; |
| int scissor; |
| |
| drm_clip_rect_t tmp_boxes[2][MGA_NR_SAREA_CLIPRECTS]; |
| |
| |
| /* Texture aging and DMA based aging. |
| */ |
| unsigned int texAge[MGA_NR_TEX_HEAPS];/* texture LRU age */ |
| unsigned int dirtyAge; /* buffer age for synchronization */ |
| |
| GLuint primary_offset; |
| |
| /* Mirrors of some DRI state. |
| */ |
| drm_context_t hHWContext; |
| drm_hw_lock_t *driHwLock; |
| int driFd; |
| __DRIdrawablePrivate *driDrawable; |
| __DRIdrawablePrivate *driReadable; |
| |
| __DRIscreenPrivate *driScreen; |
| struct mga_screen_private_s *mgaScreen; |
| drm_mga_sarea_t *sarea; |
| |
| /* Configuration cache |
| */ |
| driOptionCache optionCache; |
| }; |
| |
| #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx)) |
| |
| |
| |
| |
| /* ================================================================ |
| * Debugging: |
| */ |
| #define DO_DEBUG 1 |
| |
| #if DO_DEBUG |
| extern int MGA_DEBUG; |
| #else |
| #define MGA_DEBUG 0 |
| #endif |
| |
| #define DEBUG_VERBOSE_MSG 0x01 |
| #define DEBUG_VERBOSE_DRI 0x02 |
| #define DEBUG_VERBOSE_IOCTL 0x04 |
| #define DEBUG_VERBOSE_TEXTURE 0x08 |
| #define DEBUG_VERBOSE_FALLBACK 0x10 |
| |
| static INLINE GLuint mgaPackColor(GLuint cpp, |
| GLubyte r, GLubyte g, |
| GLubyte b, GLubyte a) |
| { |
| switch (cpp) { |
| case 2: |
| return PACK_COLOR_565( r, g, b ); |
| case 4: |
| return PACK_COLOR_8888( a, r, g, b ); |
| default: |
| return 0; |
| } |
| } |
| |
| |
| /* |
| * Subpixel offsets for window coordinates: |
| */ |
| #define SUBPIXEL_X (-0.5F) |
| #define SUBPIXEL_Y (-0.5F + 0.125) |
| |
| |
| #define MGA_WA_TRIANGLES 0x18000000 |
| #define MGA_WA_TRISTRIP_T0 0x02010200 |
| #define MGA_WA_TRIFAN_T0 0x01000408 |
| #define MGA_WA_TRISTRIP_T0T1 0x02010400 |
| #define MGA_WA_TRIFAN_T0T1 0x01000810 |
| |
| #endif |