📄 radeon_state.c
字号:
} if (rmesa->state.scissor.pClipRects) FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = MALLOC( rmesa->state.scissor.numAllocedClipRects * sizeof(drm_clip_rect_t) ); if ( rmesa->state.scissor.pClipRects == NULL ) { rmesa->state.scissor.numAllocedClipRects = 0; return; } } out = rmesa->state.scissor.pClipRects; rmesa->state.scissor.numClipRects = 0; for ( i = 0 ; i < rmesa->numClipRects ; i++ ) { if ( intersect_rect( out, &rmesa->pClipRects[i], &rmesa->state.scissor.rect ) ) { rmesa->state.scissor.numClipRects++; out++; } }}static void radeonUpdateScissor( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if ( rmesa->dri.drawable ) { __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; int x = ctx->Scissor.X; int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height; int w = ctx->Scissor.X + ctx->Scissor.Width - 1; int h = dPriv->h - ctx->Scissor.Y - 1; rmesa->state.scissor.rect.x1 = x + dPriv->x; rmesa->state.scissor.rect.y1 = y + dPriv->y; rmesa->state.scissor.rect.x2 = w + dPriv->x + 1; rmesa->state.scissor.rect.y2 = h + dPriv->y + 1; radeonRecalcScissorRects( rmesa ); }}static void radeonScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if ( ctx->Scissor.Enabled ) { RADEON_FIREVERTICES( rmesa ); /* don't pipeline cliprect changes */ radeonUpdateScissor( ctx ); }}/* ============================================================= * Culling */static void radeonCullFace( GLcontext *ctx, GLenum unused ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL]; GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL]; s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK); if ( ctx->Polygon.CullFlag ) { switch ( ctx->Polygon.CullFaceMode ) { case GL_FRONT: s &= ~RADEON_FFACE_SOLID; t |= RADEON_CULL_FRONT; break; case GL_BACK: s &= ~RADEON_BFACE_SOLID; t |= RADEON_CULL_BACK; break; case GL_FRONT_AND_BACK: s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK); break; } } if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) { RADEON_STATECHANGE(rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] = s; } if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) { RADEON_STATECHANGE(rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t; }}static void radeonFrontFace( GLcontext *ctx, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); RADEON_STATECHANGE( rmesa, set ); rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK; RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW; switch ( mode ) { case GL_CW: rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW; break; case GL_CCW: rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CCW; rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW; break; }}/* ============================================================= * Line state */static void radeonLineWidth( GLcontext *ctx, GLfloat widthf ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); RADEON_STATECHANGE( rmesa, lin ); RADEON_STATECHANGE( rmesa, set ); /* Line width is stored in U6.4 format. */ rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0); if ( widthf > 1.0 ) { rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_WIDELINE_ENABLE; } else { rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE; }}static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); RADEON_STATECHANGE( rmesa, lin ); rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));}/* ============================================================= * Masks */static void radeonColorMask( GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] ); if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) { RADEON_STATECHANGE( rmesa, msk ); rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask; }}/* ============================================================= * Polygon state */static void radeonPolygonOffset( GLcontext *ctx, GLfloat factor, GLfloat units ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); float_ui32_type constant = { units * rmesa->state.depth.scale }; float_ui32_type factoru = { factor }; RADEON_STATECHANGE( rmesa, zbs ); rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32; rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;}static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint i; drm_radeon_stipple_t stipple; /* Must flip pattern upside down. */ for ( i = 0 ; i < 32 ; i++ ) { rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i]; } /* TODO: push this into cmd mechanism */ RADEON_FIREVERTICES( rmesa ); LOCK_HARDWARE( rmesa ); /* FIXME: Use window x,y offsets into stipple RAM. */ stipple.mask = rmesa->state.stipple.mask; drmCommandWrite( rmesa->dri.fd, DRM_RADEON_STIPPLE, &stipple, sizeof(drm_radeon_stipple_t) ); UNLOCK_HARDWARE( rmesa );}static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0; /* Can't generally do unfilled via tcl, but some good special * cases work. */ TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag); if (rmesa->TclFallback) { radeonChooseRenderState( ctx ); radeonChooseVertexState( ctx ); }}/* ============================================================= * Rendering attributes * * We really don't want to recalculate all this every time we bind a * texture. These things shouldn't change all that often, so it makes * sense to break them out of the core texture state update routines. *//* Examine lighting and texture state to determine if separate specular * should be enabled. */static void radeonUpdateSpecular( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL]; GLuint flag = 0; RADEON_STATECHANGE( rmesa, tcl ); rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE; p &= ~RADEON_SPECULAR_ENABLE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE; if (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; p |= RADEON_SPECULAR_ENABLE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_DIFFUSE_SPECULAR_COMBINE; } else if (ctx->Light.Enabled) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; } else if (ctx->Fog.ColorSumEnabled ) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; p |= RADEON_SPECULAR_ENABLE; } else { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE; } if (ctx->Fog.Enabled) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC; if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) { rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR; /* Bizzare: have to leave lighting enabled to get fog. */ rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE; } else { /* cannot do tcl fog factor calculation with fog coord source * (send precomputed factors). Cannot use precomputed fog * factors together with tcl spec light (need tcl fallback) */ flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] & RADEON_TCL_COMPUTE_SPECULAR) != 0; } } TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag); if (NEED_SECONDARY_COLOR(ctx)) { assert( (p & RADEON_SPECULAR_ENABLE) != 0 ); } else { assert( (p & RADEON_SPECULAR_ENABLE) == 0 ); } if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) { RADEON_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p; } /* Update vertex/render formats */ if (rmesa->TclFallback) { radeonChooseRenderState( ctx ); radeonChooseVertexState( ctx ); }}/* ============================================================= * Materials *//* Update on colormaterial, material emmissive/ambient, * lightmodel.globalambient */static void update_global_ambient( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); float *fcmd = (float *)RADEON_DB_STATE( glt ); /* Need to do more if both emmissive & ambient are PREMULT: * Hope this is not needed for MULT */ if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] & ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) { COPY_3V( &fcmd[GLT_RED], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); ACC_SCALE_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); } else { COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient ); } RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);}/* Update on change to * - light[p].colors * - light[p].enabled */static void update_light_colors( GLcontext *ctx, GLuint p ){ struct gl_light *l = &ctx->Light.Light[p];/* fprintf(stderr, "%s\n", __FUNCTION__); */ if (l->Enabled) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); float *fcmd = (float *)RADEON_DB_STATE( lit[p] ); COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); }}/* Also fallback for asym colormaterial mode in twoside lighting... */static void check_twoside_fallback( GLcontext *ctx ){ GLboolean fallback = GL_FALSE; GLint i; if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { if (ctx->Light.ColorMaterialEnabled && (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) fallback = GL_TRUE; else { for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2) if (memcmp( ctx->Light.Material.Attrib[i], ctx->Light.Material.Attrib[i+1], sizeof(GLfloat)*4) != 0) { fallback = GL_TRUE; break; } } } TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );}static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]; light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) | (3 << RADEON_AMBIENT_SOURCE_SHIFT) | (3 << RADEON_DIFFUSE_SOURCE_SHIFT) | (3 << RADEON_SPECULAR_SOURCE_SHIFT)); if (ctx->Light.ColorMaterialEnabled) { GLuint mask = ctx->Light.ColorMaterialBitmask; if (mask & MAT_BIT_FRONT_EMISSION) { light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << RADEON_EMISSIVE_SOURCE_SHIFT); } else { light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT); } if (mask & MAT_BIT_FRONT_AMBIENT) { light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE << RADEON_AMBIENT_SOURCE_SHIFT); } else { light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT); } if (mask & MAT_BIT_FRONT_DIFFUSE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -