static void mgaDDDepthFunc(GLcontext *ctx, GLenum func) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); int zmode; switch (func) { case GL_NEVER: /* can't do this in h/w, we'll use a s/w fallback */ FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test); /* FALLTHROUGH */ case GL_ALWAYS: zmode = DC_zmode_nozcmp; break; case GL_LESS: zmode = DC_zmode_zlt; break; case GL_LEQUAL: zmode = DC_zmode_zlte; break; case GL_EQUAL: zmode = DC_zmode_ze; break; case GL_GREATER: zmode = DC_zmode_zgt; break; case GL_GEQUAL: zmode = DC_zmode_zgte; break; case GL_NOTEQUAL: zmode = DC_zmode_zne; break; default: zmode = 0; break; } MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.zmode &= DC_zmode_MASK; mmesa->hw.zmode |= zmode; }
void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint oldfallback = mmesa->Fallback; if (mode) { mmesa->Fallback |= bit; if (oldfallback == 0) { FLUSH_BATCH(mmesa); _swsetup_Wakeup( ctx ); mmesa->RenderIndex = ~0; } } else { mmesa->Fallback &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = mgaCheckTexSizes; tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive; tnl->Driver.Render.Finish = mgaRenderFinish; tnl->Driver.Render.BuildVertices = mgaBuildVertices; mmesa->new_gl_state |= (_MGA_NEW_RENDERSTATE | _MGA_NEW_RASTERSETUP); } } }
void mgaDDInitTextureFuncs( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); ctx->Driver.ChooseTextureFormat = mgaChooseTextureFormat; ctx->Driver.TexImage1D = _mesa_store_teximage1d; ctx->Driver.TexImage2D = mgaTexImage2D; ctx->Driver.TexImage3D = _mesa_store_teximage3d; ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; ctx->Driver.TexSubImage2D = mgaTexSubImage2D; ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; ctx->Driver.BindTexture = mgaDDBindTexture; ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ ctx->Driver.DeleteTexture = mgaDDDeleteTexture; ctx->Driver.IsTextureResident = driIsTextureResident; ctx->Driver.PrioritizeTexture = NULL; ctx->Driver.ActiveTexture = NULL; ctx->Driver.UpdateTexturePalette = NULL; ctx->Driver.TexEnv = mgaDDTexEnv; ctx->Driver.TexParameter = mgaDDTexParameter; driInitTextureObjects( ctx, & mmesa->swapped, (DRI_TEXMGR_DO_TEXTURE_2D | DRI_TEXMGR_DO_TEXTURE_RECT) ); }
void mgaUpdateClipping(const GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (mmesa->driDrawable) { int x1 = mmesa->driDrawable->x + ctx->Scissor.X; int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y + ctx->Scissor.Height); int x2 = x1 + ctx->Scissor.Width; int y2 = y1 + ctx->Scissor.Height; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 < 0) x2 = 0; if (y2 < 0) y2 = 0; mmesa->scissor_rect.x1 = x1; mmesa->scissor_rect.y1 = y1; mmesa->scissor_rect.x2 = x2; mmesa->scissor_rect.y2 = y2; mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } }
static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ]; }
static void mgaChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint index = 0; if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { if (flags & ANY_RASTER_FLAGS) { if (flags & DD_TRI_LIGHT_TWOSIDE) index |= MGA_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= MGA_OFFSET_BIT; if (flags & DD_TRI_UNFILLED) index |= MGA_UNFILLED_BIT; if (flags & DD_FLATSHADE) index |= MGA_FLAT_BIT; } mmesa->draw_point = mga_draw_point; mmesa->draw_line = mga_draw_line; mmesa->draw_tri = mga_draw_triangle; /* Hook in fallbacks for specific primitives. */ if (flags & ANY_FALLBACK_FLAGS) { if (flags & POINT_FALLBACK) mmesa->draw_point = mga_fallback_point; if (flags & LINE_FALLBACK) mmesa->draw_line = mga_fallback_line; if (flags & TRI_FALLBACK) mmesa->draw_tri = mga_fallback_tri; if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple) mmesa->draw_tri = mga_fallback_tri; index |= MGA_FALLBACK_BIT; } } if (mmesa->RenderIndex != index) { mmesa->RenderIndex = index; tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (index == 0) { tnl->Driver.Render.PrimTabVerts = mga_render_tab_verts; tnl->Driver.Render.PrimTabElts = mga_render_tab_elts; tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ tnl->Driver.Render.ClippedPolygon = mgaFastRenderClippedPoly; } else { tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.ClippedLine = mgaRenderClippedLine; tnl->Driver.Render.ClippedPolygon = mgaRenderClippedPoly; } } }
void mgaFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint oldfallback = mmesa->Fallback; if (mode) { mmesa->Fallback |= bit; if (oldfallback == 0) { FLUSH_BATCH(mmesa); _swsetup_Wakeup( ctx ); mmesa->RenderIndex = ~0; if (MGA_DEBUG & DEBUG_VERBOSE_FALLBACK) { fprintf(stderr, "MGA begin rasterization fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } } else { mmesa->Fallback &= ~bit; if (oldfallback == bit) { _swrast_flush( ctx ); tnl->Driver.Render.Start = mgaCheckTexSizes; tnl->Driver.Render.PrimitiveNotify = mgaRenderPrimitive; tnl->Driver.Render.Finish = mgaRenderFinish; tnl->Driver.Render.BuildVertices = mgaBuildVertices; mmesa->NewGLState |= (_MGA_NEW_RENDERSTATE | _MGA_NEW_RASTERSETUP); if (MGA_DEBUG & DEBUG_VERBOSE_FALLBACK) { fprintf(stderr, "MGA end rasterization fallback: 0x%x %s\n", bit, getFallbackString(bit)); } } } }
static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); FLUSH_BATCH( mmesa ); /* * _DrawDestMask is easier to cope with than <mode>. */ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { case BUFFER_BIT_FRONT_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->draw_buffer = MGA_FRONT; mgaXMesaSetFrontClipRects( mmesa ); FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; case BUFFER_BIT_BACK_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; mmesa->draw_buffer = MGA_BACK; mmesa->dirty |= MGA_UPLOAD_CONTEXT; mgaXMesaSetBackClipRects( mmesa ); FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } }
static void mgaDmaPrimitive( GLcontext *ctx, GLenum prim ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint hwprim; switch (prim) { case GL_TRIANGLES: hwprim = MGA_WA_TRIANGLES; break; case GL_TRIANGLE_STRIP: if (mmesa->vertex_size == 8) hwprim = MGA_WA_TRISTRIP_T0; else hwprim = MGA_WA_TRISTRIP_T0T1; break; case GL_TRIANGLE_FAN: if (mmesa->vertex_size == 8) hwprim = MGA_WA_TRIFAN_T0; else hwprim = MGA_WA_TRIFAN_T0T1; break; default: return; } mgaRasterPrimitive( ctx, GL_TRIANGLES, hwprim ); }
static void mgaRunPipeline( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (mmesa->new_state) { mgaDDUpdateHwState( ctx ); } if (!mmesa->Fallback && mmesa->new_gl_state) { if (mmesa->new_gl_state & _MGA_NEW_RASTERSETUP) mgaChooseVertexState( ctx ); if (mmesa->new_gl_state & _MGA_NEW_RENDERSTATE) mgaChooseRenderState( ctx ); mmesa->new_gl_state = 0; /* Circularity: mgaDDUpdateHwState can affect mmesa->Fallback, * but mgaChooseVertexState can affect mmesa->new_state. Hence * the second check. (Fix this...) */ if (mmesa->new_state) { mgaDDUpdateHwState( ctx ); } } _tnl_run_pipeline( ctx ); }
static GLboolean mga_run_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint i; /* Don't handle clipping or indexed vertices or vertex manipulations. */ if (mmesa->RenderIndex != 0 || !mga_validate_render( ctx, VB )) { return GL_TRUE; } tnl->Driver.Render.Start( ctx ); mmesa->SetupNewInputs = ~0; for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (!length) continue; mga_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim); } tnl->Driver.Render.Finish( ctx ); return GL_FALSE; /* finished the pipe */ }
static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); FLUSH_BATCH( mmesa ); /* * _DrawDestMask is easier to cope with than <mode>. */ switch ( ctx->Color._DrawDestMask[0] ) { case DD_FRONT_LEFT_BIT: mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->draw_buffer = MGA_FRONT; mgaXMesaSetFrontClipRects( mmesa ); FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; case DD_BACK_LEFT_BIT: mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; mmesa->draw_buffer = MGA_BACK; mmesa->dirty |= MGA_UPLOAD_CONTEXT; mgaXMesaSetBackClipRects( mmesa ); FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } /* We want to update the s/w rast state too so that r200SetBuffer() * gets called. */ _swrast_DrawBuffer(ctx, mode); }
static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); updateSpecularLighting( ctx ); } }
static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MGA_CONTEXT(ctx)->NewGLState |= new_state; }
static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { if ( ctx->Scissor.Enabled ) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */ mgaUpdateClipping( ctx ); } }
static void mgaDDStencilMask(GLcontext *ctx, GLuint mask) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.stencil &= S_swtmsk_MASK; mmesa->hw.stencil |= MGA_FIELD( S_swtmsk, mask ); }
static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.zmode &= DC_atype_MASK; mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i; }
static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP]) return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP]; else return 0; }
static void mgaDDTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaTextureObjectPtr t; t = (mgaTextureObjectPtr) tObj->DriverData; /* If we don't have a hardware texture, it will be automatically * created with current state before it is used, so we don't have * to do anything now */ if ( (t == NULL) || (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV) ) { return; } switch (pname) { case GL_TEXTURE_MIN_FILTER: driSwapOutTextureObject( (driTextureObject *) t ); /* FALLTHROUGH */ case GL_TEXTURE_MAG_FILTER: FLUSH_BATCH(mmesa); mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: FLUSH_BATCH(mmesa); mgaSetTexWrapping(t,tObj->WrapS,tObj->WrapT); break; case GL_TEXTURE_BORDER_COLOR: FLUSH_BATCH(mmesa); mgaSetTexBorderColor(t, tObj->_BorderChan); break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* This isn't the most efficient solution but there doesn't appear to * be a nice alternative. Since there's no LOD clamping, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ driSwapOutTextureObject( (driTextureObject *) t ); break; default: return; } }
void mga_emit_contiguous_verts( GLcontext *ctx, GLuint start, GLuint count ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint vertex_size = mmesa->vertex_size * 4; GLuint *dest = mgaAllocDmaLow( mmesa, (count-start) * vertex_size); setup_tab[mmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); }
static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (!IS_AGP_MEM(mmesa, ptr)) return -1; return AGP_OFFSET(mmesa, ptr); }
static void updateSpecularLighting( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); unsigned int specen; specen = NEED_SECONDARY_COLOR(ctx) ? TMC_specen_enable : 0; if ( specen != mmesa->hw.specen ) { mmesa->hw.specen = specen; mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1; } }
/** * Implement the hardware-specific portion of \c glFlush. * * \param ctx Context to be flushed. * * \sa glFlush, mgaFinish, mgaFlushDMA */ static void mgaFlush( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); LOCK_HARDWARE( mmesa ); if ( mmesa->vertex_dma_buffer != NULL ) { mgaFlushVerticesLocked( mmesa ); } UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH ); UNLOCK_HARDWARE( mmesa ); }
static void updateBlendLogicOp(GLcontext *ctx) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.blend_func_enable = (ctx->Color.BlendEnabled && !ctx->Color._LogicOpEnabled) ? ~0 : 0; FALLBACK( ctx, MGA_FALLBACK_BLEND, ctx->Color.BlendEnabled && !ctx->Color._LogicOpEnabled && mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) ); }
static void mgaDDClearColor(GLcontext *ctx, const GLfloat color[4] ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLubyte c[4]; CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3]); }
static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (pname == GL_FOG_COLOR) { GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F), (GLubyte)(ctx->Fog.Color[1]*255.0F), (GLubyte)(ctx->Fog.Color[2]*255.0F)); MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT); mmesa->setup.fogcolor = color; } }
/* Determine the rasterized primitive when not drawing unfilled * polygons. * * Used only for the default render stage which always decomposes * primitives to trianges/lines/points. For the accelerated stage, * which renders strips as strips, the equivalent calculations are * performed in mgarender.c. */ static void mgaRenderPrimitive( GLcontext *ctx, GLenum prim ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint rprim = reduced_prim[prim]; mmesa->render_primitive = prim; if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; if (mmesa->raster_primitive != rprim) { mgaRasterPrimitive( ctx, rprim, MGA_WA_TRIANGLES ); } }
static void mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); driTextureObject * t = (driTextureObject *) tObj->DriverData; if ( t ) { if ( mmesa ) { FLUSH_BATCH( mmesa ); } driDestroyTextureObject( t ); } }
static void mgaRunPipeline( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (mmesa->NewGLState) { mgaDDValidateState( ctx ); } if (mmesa->dirty) { mgaEmitHwStateLocked( mmesa ); } _tnl_run_pipeline( ctx ); }
static void mgaDDClearDepth(GLcontext *ctx, GLclampd d) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); /* Select the Z depth. The ~ is used because the _MASK values in the * MGA driver are used to mask OFF the selected bits. In this case, * we want to mask off everything except the MA_zwidth bits. */ switch (mmesa->setup.maccess & ~MA_zwidth_MASK) { case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; default: return; } }