📄 radeon_state.c
字号:
}static voidradeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); RADEON_STATECHANGE( rmesa, msk ); rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK; rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);}static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP, and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC, but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */ GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP; GLuint tempRADEON_STENCIL_FAIL_INC_WRAP; GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP; GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP; GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP; GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP; if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) { tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC; tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC; tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC; tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC; tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC; tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC; } else { tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP; tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP; tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP; tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP; tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP; tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP; } RADEON_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK | RADEON_STENCIL_ZFAIL_MASK | RADEON_STENCIL_ZPASS_MASK); switch ( ctx->Stencil.FailFunc[0] ) { case GL_KEEP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP; break; case GL_ZERO: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO; break; case GL_REPLACE: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE; break; case GL_INCR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC; break; case GL_DECR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC; break; case GL_INCR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP; break; case GL_DECR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP; break; case GL_INVERT: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT; break; } switch ( ctx->Stencil.ZFailFunc[0] ) { case GL_KEEP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP; break; case GL_ZERO: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO; break; case GL_REPLACE: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE; break; case GL_INCR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC; break; case GL_DECR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC; break; case GL_INCR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP; break; case GL_DECR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP; break; case GL_INVERT: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT; break; } switch ( ctx->Stencil.ZPassFunc[0] ) { case GL_KEEP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP; break; case GL_ZERO: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO; break; case GL_REPLACE: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE; break; case GL_INCR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC; break; case GL_DECR: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC; break; case GL_INCR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP; break; case GL_DECR_WRAP: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP; break; case GL_INVERT: rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT; break; }}static void radeonClearStencil( GLcontext *ctx, GLint s ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); rmesa->state.stencil.clear = ((GLuint) (ctx->Stencil.Clear & 0xff) | (0xff << RADEON_STENCIL_MASK_SHIFT) | ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));}/* ============================================================= * Window position and viewport transformation *//* * To correctly position primitives: */#define SUBPIXEL_X 0.125#define SUBPIXEL_Y 0.125/** * Called when window size or position changes or viewport or depth range * state is changed. We update the hardware viewport state here. */void radeonUpdateWindow( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; GLfloat xoffset = (GLfloat)dPriv->x; GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; float_ui32_type sx = { v[MAT_SX] }; float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X }; float_ui32_type sy = { - v[MAT_SY] }; float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y }; float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale }; float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale }; RADEON_FIREVERTICES( rmesa ); RADEON_STATECHANGE( rmesa, vpt ); rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;}static void radeonViewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ){ /* Don't pipeline viewport changes, conflict with window offset * setting below. Could apply deltas to rescue pipelined viewport * values, or keep the originals hanging around. */ radeonUpdateWindow( ctx );}static void radeonDepthRange( GLcontext *ctx, GLclampd nearval, GLclampd farval ){ radeonUpdateWindow( ctx );}void radeonUpdateViewportOffset( GLcontext *ctx ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; GLfloat xoffset = (GLfloat)dPriv->x; GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; const GLfloat *v = ctx->Viewport._WindowMap.m; float_ui32_type tx; float_ui32_type ty; tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X; ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y; if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 || rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 ) { /* Note: this should also modify whatever data the context reset * code uses... */ RADEON_STATECHANGE( rmesa, vpt ); rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32; rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32; /* update polygon stipple x/y screen offset */ { GLuint stx, sty; GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC]; m &= ~(RADEON_STIPPLE_X_OFFSET_MASK | RADEON_STIPPLE_Y_OFFSET_MASK); /* add magic offsets, then invert */ stx = 31 - ((rmesa->dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK); sty = 31 - ((rmesa->dri.drawable->y + rmesa->dri.drawable->h - 1) & RADEON_STIPPLE_COORD_MASK); m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) | (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT)); if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) { RADEON_STATECHANGE( rmesa, msc ); rmesa->hw.msc.cmd[MSC_RE_MISC] = m; } } } radeonUpdateScissor( ctx );}/* ============================================================= * Miscellaneous */static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] ){ radeonContextPtr rmesa = RADEON_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]); rmesa->state.color.clear = radeonPackColor( rmesa->radeonScreen->cpp, c[0], c[1], c[2], c[3] );}static void radeonRenderMode( GLcontext *ctx, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );}static GLuint radeon_rop_tab[] = { RADEON_ROP_CLEAR, RADEON_ROP_AND, RADEON_ROP_AND_REVERSE, RADEON_ROP_COPY, RADEON_ROP_AND_INVERTED, RADEON_ROP_NOOP, RADEON_ROP_XOR, RADEON_ROP_OR, RADEON_ROP_NOR, RADEON_ROP_EQUIV, RADEON_ROP_INVERT, RADEON_ROP_OR_REVERSE, RADEON_ROP_COPY_INVERTED, RADEON_ROP_OR_INVERTED, RADEON_ROP_NAND, RADEON_ROP_SET,};static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint rop = (GLuint)opcode - GL_CLEAR; ASSERT( rop < 16 ); RADEON_STATECHANGE( rmesa, msk ); rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];}/** * Set up the cliprects for either front or back-buffer drawing. */void radeonSetCliprects( radeonContextPtr rmesa ){ __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; __DRIdrawablePrivate *const readable = rmesa->dri.readable; GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) { /* Can't ignore 2d windows if we are page flipping. */ if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) { rmesa->numClipRects = drawable->numClipRects; rmesa->pClipRects = drawable->pClipRects; } else { rmesa->numClipRects = drawable->numBackClipRects; rmesa->pClipRects = drawable->pBackClipRects; } } else { /* front buffer (or none, or multiple buffers */ rmesa->numClipRects = drawable->numClipRects; rmesa->pClipRects = drawable->pClipRects; } if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, drawable->w, drawable->h); draw_fb->Initialized = GL_TRUE; } if (drawable != readable) { if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) { _mesa_resize_framebuffer(rmesa->glCtx, read_fb, readable->w, readable->h); read_fb->Initialized = GL_TRUE; } } if (rmesa->state.scissor.enabled) radeonRecalcScissorRects( rmesa ); rmesa->lastStamp = drawable->lastStamp;}/** * Called via glDrawBuffer. */static void radeonDrawBuffer( GLcontext *ctx, GLenum mode ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr( mode )); RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { /* 0 (GL_NONE) buffers or multiple color drawing buffers */ FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) { case BUFFER_FRONT_LEFT: case BUFFER_BACK_LEFT: FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } radeonSetCliprects( rmesa ); /* We'll set the drawing engine's offset/pitch parameters later * when we update other state. */}static void radeonReadBuffer( GLcontext *ctx, GLenum mode ){ /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */}/* ============================================================= * State enable/disable */static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint p, flag; if ( RADEON_DEBUG & DEBUG_STATE ) fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr( cap ), state ? "GL_TRUE" : "GL_FALSE" ); switch ( cap ) { /* Fast track this one... */ case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: break; case GL_ALPHA_TEST: RADEON_STATECHANGE( rmesa, ctx ); if (state) { rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE; } else { rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE; } break; case GL_BLEND: RADEON_STATECHANGE( rmesa, ctx ); if (state) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ALPHA_BLEND_ENABLE; } else { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE; } if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) { rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -