⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r300_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
{	(void)face;	(void)mode;	r300UpdatePolygonMode(ctx);}/* ============================================================= * Stencil */static int translate_stencil_op(int op){	switch (op) {	case GL_KEEP:		return R300_ZS_KEEP;	case GL_ZERO:		return R300_ZS_ZERO;	case GL_REPLACE:		return R300_ZS_REPLACE;	case GL_INCR:		return R300_ZS_INCR;	case GL_DECR:		return R300_ZS_DECR;	case GL_INCR_WRAP_EXT:		return R300_ZS_INCR_WRAP;	case GL_DECR_WRAP_EXT:		return R300_ZS_DECR_WRAP;	case GL_INVERT:		return R300_ZS_INVERT;	default:		WARN_ONCE("Do not know how to translate stencil op");		return R300_ZS_KEEP;	}	return 0;}static void r300ShadeModel(GLcontext * ctx, GLenum mode){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	R300_STATECHANGE(rmesa, shade);	rmesa->hw.shade.cmd[1] = 0x00000002;	switch (mode) {	case GL_FLAT:		rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_FLAT;		break;	case GL_SMOOTH:		rmesa->hw.shade.cmd[2] = R300_RE_SHADE_MODEL_SMOOTH;		break;	default:		return;	}	rmesa->hw.shade.cmd[3] = 0x00000000;	rmesa->hw.shade.cmd[4] = 0x00000000;}static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,				    GLenum func, GLint ref, GLuint mask){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	GLuint refmask =	    (((ctx->Stencil.	       Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ((ctx->							    Stencil.							    ValueMask							    [0] &							    0xff)							   <<							   R300_STENCILMASK_SHIFT));	GLuint flag;	R300_STATECHANGE(rmesa, zs);	rmesa->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK;	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK <<					       R300_S_FRONT_FUNC_SHIFT)					      | (R300_ZS_MASK <<						 R300_S_BACK_FUNC_SHIFT));	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=	    ~((R300_STENCILREF_MASK << R300_STENCILREF_SHIFT) |	      (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT));	flag = translate_func(ctx->Stencil.Function[0]);	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=	    (flag << R300_S_FRONT_FUNC_SHIFT);	if (ctx->Stencil._TestTwoSide)		flag = translate_func(ctx->Stencil.Function[1]);	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=	    (flag << R300_S_BACK_FUNC_SHIFT);	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;}static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	R300_STATECHANGE(rmesa, zs);	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &=	    ~(R300_STENCILREF_MASK <<	      R300_STENCILWRITEMASK_SHIFT);	rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |=	    (ctx->Stencil.	     WriteMask[0] & R300_STENCILREF_MASK) <<	     R300_STENCILWRITEMASK_SHIFT;}static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,				  GLenum fail, GLenum zfail, GLenum zpass){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	R300_STATECHANGE(rmesa, zs);	/* It is easier to mask what's left.. */	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &=	    (R300_ZS_MASK << R300_Z_FUNC_SHIFT) |	    (R300_ZS_MASK << R300_S_FRONT_FUNC_SHIFT) |	    (R300_ZS_MASK << R300_S_BACK_FUNC_SHIFT);	rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=	    (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<	     R300_S_FRONT_SFAIL_OP_SHIFT)	    | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<	       R300_S_FRONT_ZFAIL_OP_SHIFT)	    | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<	       R300_S_FRONT_ZPASS_OP_SHIFT);	if (ctx->Stencil._TestTwoSide) {		rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=		    (translate_stencil_op(ctx->Stencil.FailFunc[1]) <<		     R300_S_BACK_SFAIL_OP_SHIFT)		    | (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) <<		       R300_S_BACK_ZFAIL_OP_SHIFT)		    | (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) <<		       R300_S_BACK_ZPASS_OP_SHIFT);	} else {		rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=		    (translate_stencil_op(ctx->Stencil.FailFunc[0]) <<		     R300_S_BACK_SFAIL_OP_SHIFT)		    | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) <<		       R300_S_BACK_ZFAIL_OP_SHIFT)		    | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) <<		       R300_S_BACK_ZPASS_OP_SHIFT);	}}/* ============================================================= * Window position and viewport transformation *//* * To correctly position primitives: */#define SUBPIXEL_X 0.125#define SUBPIXEL_Y 0.125static void r300UpdateWindow(GLcontext * ctx){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	__DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;	GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;	GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;	const GLfloat *v = ctx->Viewport._WindowMap.m;	GLfloat sx = v[MAT_SX];	GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;	GLfloat sy = -v[MAT_SY];	GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;	GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;	GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;	R300_FIREVERTICES(rmesa);	R300_STATECHANGE(rmesa, vpt);	rmesa->hw.vpt.cmd[R300_VPT_XSCALE] = r300PackFloat32(sx);	rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);	rmesa->hw.vpt.cmd[R300_VPT_YSCALE] = r300PackFloat32(sy);	rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);	rmesa->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(sz);	rmesa->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(tz);}static void r300Viewport(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.	 */	r300UpdateWindow(ctx);}static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval){	r300UpdateWindow(ctx);}void r300UpdateViewportOffset(GLcontext * ctx){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	__DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable;	GLfloat xoffset = (GLfloat) dPriv->x;	GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h;	const GLfloat *v = ctx->Viewport._WindowMap.m;	GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;	GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y;	if (rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] != r300PackFloat32(tx) ||	    rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] != r300PackFloat32(ty)) {		/* Note: this should also modify whatever data the context reset		 * code uses...		 */		R300_STATECHANGE(rmesa, vpt);		rmesa->hw.vpt.cmd[R300_VPT_XOFFSET] = r300PackFloat32(tx);		rmesa->hw.vpt.cmd[R300_VPT_YOFFSET] = r300PackFloat32(ty);	}	radeonUpdateScissor(ctx);}/** * Tell the card where to render (offset, pitch). * Effected by glDrawBuffer, etc */void r300UpdateDrawBuffer(GLcontext * ctx){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	r300ContextPtr r300 = rmesa;	struct gl_framebuffer *fb = ctx->DrawBuffer;	driRenderbuffer *drb;	if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {		/* draw to front */		drb =		    (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].		    Renderbuffer;	} else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {		/* draw to back */		drb =		    (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].		    Renderbuffer;	} else {		/* drawing to multiple buffers, or none */		return;	}	assert(drb);	assert(drb->flippedPitch);	R300_STATECHANGE(rmesa, cb);	r300->hw.cb.cmd[R300_CB_OFFSET] = drb->flippedOffset +	//r300->radeon.state.color.drawOffset +	    r300->radeon.radeonScreen->fbLocation;	r300->hw.cb.cmd[R300_CB_PITCH] = drb->flippedPitch;	//r300->radeon.state.color.drawPitch;	if (r300->radeon.radeonScreen->cpp == 4)		r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_ARGB8888;	else		r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_FORMAT_RGB565;	if (r300->radeon.sarea->tiling_enabled)		r300->hw.cb.cmd[R300_CB_PITCH] |= R300_COLOR_TILE_ENABLE;#if 0	R200_STATECHANGE(rmesa, ctx);	/* Note: we used the (possibly) page-flipped values */	rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET]	    = ((drb->flippedOffset + rmesa->r200Screen->fbLocation)	       & R200_COLOROFFSET_MASK);	rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = drb->flippedPitch;	if (rmesa->sarea->tiling_enabled) {		rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |=		    R200_COLOR_TILE_ENABLE;	}#endif}static voidr300FetchStateParameter(GLcontext * ctx,			const gl_state_index state[STATE_LENGTH],			GLfloat * value){	r300ContextPtr r300 = R300_CONTEXT(ctx);	switch (state[0]) {	case STATE_INTERNAL:		switch (state[1]) {		case STATE_R300_WINDOW_DIMENSION:			value[0] = r300->radeon.dri.drawable->w * 0.5f;	/* width*0.5 */			value[1] = r300->radeon.dri.drawable->h * 0.5f;	/* height*0.5 */			value[2] = 0.5F;	/* for moving range [-1 1] -> [0 1] */			value[3] = 1.0F;	/* not used */			break;		case STATE_R300_TEXRECT_FACTOR:{				struct gl_texture_object *t =				    ctx->Texture.Unit[state[2]].CurrentRect;				if (t && t->Image[0][t->BaseLevel]) {					struct gl_texture_image *image =					    t->Image[0][t->BaseLevel];					value[0] = 1.0 / image->Width2;					value[1] = 1.0 / image->Height2;				} else {					value[0] = 1.0;					value[1] = 1.0;				}				value[2] = 1.0;				value[3] = 1.0;				break;			}		default:			break;		}		break;	default:		break;	}}/** * Update R300's own internal state parameters. * For now just STATE_R300_WINDOW_DIMENSION */void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state){	struct r300_fragment_program *fp;	struct gl_program_parameter_list *paramList;	GLuint i;	if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM)))		return;	fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;	if (!fp)		return;	paramList = fp->mesa_program.Base.Parameters;	if (!paramList)		return;	for (i = 0; i < paramList->NumParameters; i++) {		if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {			r300FetchStateParameter(ctx,						paramList->Parameters[i].						StateIndexes,						paramList->ParameterValues[i]);		}	}}/* ============================================================= * Polygon state */static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units){	r300ContextPtr rmesa = R300_CONTEXT(ctx);	GLfloat constant = units;	switch (ctx->Visual.depthBits) {	case 16:		constant *= 4.0;		break;	case 24:		constant *= 2.0;		break;	}	factor *= 12.0;/*    fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */	R300_STATECHANGE(rmesa, zbs);	rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor);	rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant);	rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor);	rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant);}/* Routing and texture-related *//* r300 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST. * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead. * We need to recalculate wrap modes whenever filter mode is changed because someone might do: * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); * Since r300 completely ignores R300_TX_CLAMP when either min or mag is nearest it cant handle * combinations where only one of them is nearest. */static unsigned long gen_fixed_filter(unsigned long f){	unsigned long mag, min, needs_fixing = 0;	//return f;	/* We ignore MIRROR bit so we dont have to do everything twice */	if ((f & ((7 - 1) << R300_TX_WRAP_S_SHIFT)) ==	    (R300_TX_CLAMP << R300_TX_WRAP_S_SHIFT)) {		needs_fixing |= 1;	}	if ((f & ((7 - 1) << R300_TX_WRAP_T_SHIFT)) ==	    (R300_TX_CLAMP << R300_TX_WRAP_T_SHIFT)) {		needs_fixing |= 2;	}	if ((f & ((7 - 1) << R300_TX_WRAP_R_SHIFT)) ==	    (R300_TX_CLAMP << R300_TX_WRAP_R_SHIFT)) {		needs_fixing |= 4;	}	if (!needs_fixing)		return f;	mag = f & R300_TX_MAG_FILTER_MASK;	min = f & (R300_TX_MIN_FILTER_MASK|R300_TX_MIN_FILTER_MIP_MASK);	/* TODO: Check for anisto filters too */	if ((mag != R300_TX_MAG_FILTER_NEAREST)	    && (min != R300_TX_MIN_FILTER_NEAREST))		return f;	/* r300 cant handle these modes hence we force nearest to linear */	if ((mag == R300_TX_MAG_FILTER_NEAREST)	    && (min != R300_TX_MIN_FILTER_NEAREST)) {		f &= ~R300_TX_MAG_FILTER_NEAREST;		f |= R300_TX_MAG_FILTER_LINEAR;		return f;	}	if ((min == R300_TX_MIN_FILTER_NEAREST)	    && (mag != R300_TX_MAG_FILTER_NEAREST)) {		f &= ~R300_TX_MIN_FILTER_NEAREST;		f |= R300_TX_MIN_FILTER_LINEAR;		return f;	}	/* Both are nearest */	if (needs_fixing & 1) {		f &= ~((7 - 1) << R300_TX_WRAP_S_SHIFT);		f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_S_SHIFT;	}	if (needs_fixing & 2) {		f &= ~((7 - 1) << R300_TX_WRAP_T_SHIFT);		f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_T_SHIFT;	}	if (needs_fixing & 4) {		f &= ~((7 - 1) << R300_TX_WRAP_R_SHIFT);		f |= R300_TX_CLAMP_TO_EDGE << R300_TX_WRAP_R_SHIFT;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -