📄 r300_state.c
字号:
(char *)ctx->FragmentProgram._Current; return (fp && fp->WritesDepth); } else { struct r500_fragment_program* fp = (struct r500_fragment_program*)(char*) ctx->FragmentProgram._Current; return (fp && fp->writes_depth); }}static void r300SetEarlyZState(GLcontext * ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); GLuint topZ = R300_ZTOP_ENABLE; if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) topZ = R300_ZTOP_DISABLE; if (current_fragment_program_writes_depth(ctx)) topZ = R300_ZTOP_DISABLE; if (topZ != r300->hw.zstencil_format.cmd[2]) { /* Note: This completely reemits the stencil format. * I have not tested whether this is strictly necessary, * or if emitting a write to ZB_ZTOP is enough. */ R300_STATECHANGE(r300, zstencil_format); r300->hw.zstencil_format.cmd[2] = topZ; }}static void r300SetAlphaState(GLcontext * ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); GLubyte refByte; uint32_t pp_misc = 0x0; GLboolean really_enabled = ctx->Color.AlphaEnabled; CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef); switch (ctx->Color.AlphaFunc) { case GL_NEVER: pp_misc |= R300_FG_ALPHA_FUNC_NEVER; break; case GL_LESS: pp_misc |= R300_FG_ALPHA_FUNC_LESS; break; case GL_EQUAL: pp_misc |= R300_FG_ALPHA_FUNC_EQUAL; break; case GL_LEQUAL: pp_misc |= R300_FG_ALPHA_FUNC_LE; break; case GL_GREATER: pp_misc |= R300_FG_ALPHA_FUNC_GREATER; break; case GL_NOTEQUAL: pp_misc |= R300_FG_ALPHA_FUNC_NOTEQUAL; break; case GL_GEQUAL: pp_misc |= R300_FG_ALPHA_FUNC_GE; break; case GL_ALWAYS: /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */ really_enabled = GL_FALSE; break; } if (really_enabled) { pp_misc |= R300_FG_ALPHA_FUNC_ENABLE; pp_misc |= R500_FG_ALPHA_FUNC_8BIT; pp_misc |= (refByte & R300_FG_ALPHA_FUNC_VAL_MASK); } else { pp_misc = 0x0; } R300_STATECHANGE(r300, at); r300->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc; r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; r300SetEarlyZState(ctx);}static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref){ (void)func; (void)ref; r300SetAlphaState(ctx);}static int translate_func(int func){ switch (func) { case GL_NEVER: return R300_ZS_NEVER; case GL_LESS: return R300_ZS_LESS; case GL_EQUAL: return R300_ZS_EQUAL; case GL_LEQUAL: return R300_ZS_LEQUAL; case GL_GREATER: return R300_ZS_GREATER; case GL_NOTEQUAL: return R300_ZS_NOTEQUAL; case GL_GEQUAL: return R300_ZS_GEQUAL; case GL_ALWAYS: return R300_ZS_ALWAYS; } return 0;}static void r300SetDepthState(GLcontext * ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); R300_STATECHANGE(r300, zs); r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE|R300_STENCIL_FRONT_BACK; r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT); if (ctx->Depth.Test) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE; if (ctx->Depth.Mask) r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_WRITE_ENABLE; r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(ctx->Depth.Func) << R300_Z_FUNC_SHIFT; } r300SetEarlyZState(ctx);}static void r300SetStencilState(GLcontext * ctx, GLboolean state){ r300ContextPtr r300 = R300_CONTEXT(ctx); if (r300->state.stencil.hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_ENABLE; } else { r300->hw.zs.cmd[R300_ZS_CNTL_0] &= ~R300_STENCIL_ENABLE; } } else {#if R200_MERGED FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state);#endif }}static void r300UpdatePolygonMode(GLcontext * ctx){ r300ContextPtr r300 = R300_CONTEXT(ctx); uint32_t hw_mode = R300_GA_POLY_MODE_DISABLE; /* Only do something if a polygon mode is wanted, default is GL_FILL */ if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) { GLenum f, b; /* Handle GL_CW (clock wise and GL_CCW (counter clock wise) * correctly by selecting the correct front and back face */ if (ctx->Polygon.FrontFace == GL_CCW) { f = ctx->Polygon.FrontMode; b = ctx->Polygon.BackMode; } else { f = ctx->Polygon.BackMode; b = ctx->Polygon.FrontMode; } /* Enable polygon mode */ hw_mode |= R300_GA_POLY_MODE_DUAL; switch (f) { case GL_LINE: hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_LINE; break; case GL_POINT: hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_POINT; break; case GL_FILL: hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_TRI; break; } switch (b) { case GL_LINE: hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_LINE; break; case GL_POINT: hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_POINT; break; case GL_FILL: hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_TRI; break; } } if (r300->hw.polygon_mode.cmd[1] != hw_mode) { R300_STATECHANGE(r300, polygon_mode); r300->hw.polygon_mode.cmd[1] = hw_mode; } r300->hw.polygon_mode.cmd[2] = 0x00000001; r300->hw.polygon_mode.cmd[3] = 0x00000000;}/** * Change the culling mode. * * \note Mesa already filters redundant calls to this function. */static void r300CullFace(GLcontext * ctx, GLenum mode){ (void)mode; r300UpdateCulling(ctx);}/** * Change the polygon orientation. * * \note Mesa already filters redundant calls to this function. */static void r300FrontFace(GLcontext * ctx, GLenum mode){ (void)mode; r300UpdateCulling(ctx); r300UpdatePolygonMode(ctx);}/** * Change the depth testing function. * * \note Mesa already filters redundant calls to this function. */static void r300DepthFunc(GLcontext * ctx, GLenum func){ (void)func; r300SetDepthState(ctx);}/** * Enable/Disable depth writing. * * \note Mesa already filters redundant calls to this function. */static void r300DepthMask(GLcontext * ctx, GLboolean mask){ (void)mask; r300SetDepthState(ctx);}/** * Handle glColorMask() */static void r300ColorMask(GLcontext * ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a){ r300ContextPtr r300 = R300_CONTEXT(ctx); int mask = (r ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | (g ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | (b ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | (a ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0); if (mask != r300->hw.cmk.cmd[R300_CMK_COLORMASK]) { R300_STATECHANGE(r300, cmk); r300->hw.cmk.cmd[R300_CMK_COLORMASK] = mask; }}/* ============================================================= * Fog */static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param){ r300ContextPtr r300 = R300_CONTEXT(ctx); union { int i; float f; } fogScale, fogStart; (void)param; fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE]; fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START]; switch (pname) { case GL_FOG_MODE: switch (ctx->Fog.Mode) { case GL_LINEAR: R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | R300_FG_FOG_BLEND_FN_LINEAR; if (ctx->Fog.Start == ctx->Fog.End) { fogScale.f = -1.0; fogStart.f = 1.0; } else { fogScale.f = 1.0 / (ctx->Fog.End - ctx->Fog.Start); fogStart.f = -ctx->Fog.Start / (ctx->Fog.End - ctx->Fog.Start); } break; case GL_EXP: R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | R300_FG_FOG_BLEND_FN_EXP; fogScale.f = 0.0933 * ctx->Fog.Density; fogStart.f = 0.0; break; case GL_EXP2: R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | R300_FG_FOG_BLEND_FN_EXP2; fogScale.f = 0.3 * ctx->Fog.Density; fogStart.f = 0.0; default: return; } break; case GL_FOG_DENSITY: switch (ctx->Fog.Mode) { case GL_EXP: fogScale.f = 0.0933 * ctx->Fog.Density; fogStart.f = 0.0; break; case GL_EXP2: fogScale.f = 0.3 * ctx->Fog.Density; fogStart.f = 0.0; default: break; } break; case GL_FOG_START: case GL_FOG_END: if (ctx->Fog.Mode == GL_LINEAR) { if (ctx->Fog.Start == ctx->Fog.End) { fogScale.f = -1.0; fogStart.f = 1.0; } else { fogScale.f = 1.0 / (ctx->Fog.End - ctx->Fog.Start); fogStart.f = -ctx->Fog.Start / (ctx->Fog.End - ctx->Fog.Start); } } break; case GL_FOG_COLOR: R300_STATECHANGE(r300, fogc); r300->hw.fogc.cmd[R300_FOGC_R] = (GLuint) (ctx->Fog.Color[0] * 1023.0F) & 0x3FF; r300->hw.fogc.cmd[R300_FOGC_G] = (GLuint) (ctx->Fog.Color[1] * 1023.0F) & 0x3FF; r300->hw.fogc.cmd[R300_FOGC_B] = (GLuint) (ctx->Fog.Color[2] * 1023.0F) & 0x3FF; break; case GL_FOG_COORD_SRC: break; default: return; } if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] || fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) { R300_STATECHANGE(r300, fogp); r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i; r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i; }}static void r300SetFogState(GLcontext * ctx, GLboolean state){ r300ContextPtr r300 = R300_CONTEXT(ctx); R300_STATECHANGE(r300, fogs); if (state) { r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FG_FOG_BLEND_ENABLE; r300Fogfv(ctx, GL_FOG_MODE, NULL); r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); } else { r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FG_FOG_BLEND_ENABLE; }}/* ============================================================= * Point state */static void r300PointSize(GLcontext * ctx, GLfloat size){ r300ContextPtr r300 = R300_CONTEXT(ctx); /* same size limits for AA, non-AA points */ size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); R300_STATECHANGE(r300, ps); r300->hw.ps.cmd[R300_PS_POINTSIZE] = ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) | ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);}static void r300PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * param){ r300ContextPtr r300 = R300_CONTEXT(ctx); switch (pname) { case GL_POINT_SIZE_MIN: R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MIN_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MinSize * 6.0); break; case GL_POINT_SIZE_MAX: R300_STATECHANGE(r300, ga_point_minmax); r300->hw.ga_point_minmax.cmd[1] &= ~R300_GA_POINT_MINMAX_MAX_MASK; r300->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MaxSize * 6.0) << R300_GA_POINT_MINMAX_MAX_SHIFT; break; case GL_POINT_DISTANCE_ATTENUATION: break; case GL_POINT_FADE_THRESHOLD_SIZE: break; default: break; }}/* ============================================================= * Line state */static void r300LineWidth(GLcontext * ctx, GLfloat widthf){ r300ContextPtr r300 = R300_CONTEXT(ctx); widthf = CLAMP(widthf, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); R300_STATECHANGE(r300, lcntl); r300->hw.lcntl.cmd[1] = R300_LINE_CNT_HO | R300_LINE_CNT_VE | (int)(widthf * 6.0);}static void r300PolygonMode(GLcontext * ctx, GLenum face, GLenum mode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -