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

📄 r300_vertprog.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************Copyright (C) 2005  Aapo Tahkola <aet@rasterburn.org>Copyright (C) 2008  Oliver McFadden <z3ro.geek@gmail.com>All Rights Reserved.Permission is hereby granted, free of charge, to any person obtaining acopy of this software and associated documentation files (the "Software"),to deal in the Software without restriction, including without limitationon the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whomthe Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice (including the nextparagraph) shall be included in all copies or substantial portions of theSoftware.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALLTHE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OROTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THEUSE OR OTHER DEALINGS IN THE SOFTWARE.**************************************************************************//* Radeon R5xx Acceleration, Revision 1.2 */#include "main/glheader.h"#include "main/macros.h"#include "main/enums.h"#include "shader/program.h"#include "shader/prog_instruction.h"#include "shader/prog_parameter.h"#include "shader/prog_statevars.h"#include "tnl/tnl.h"#include "r300_context.h"/* TODO: Get rid of t_src_class call */#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \		       ((t_src_class(a.File) == PVS_SRC_REG_CONSTANT && \			 t_src_class(b.File) == PVS_SRC_REG_CONSTANT) || \			(t_src_class(a.File) == PVS_SRC_REG_INPUT && \			 t_src_class(b.File) == PVS_SRC_REG_INPUT)))) \/* * Take an already-setup and valid source then swizzle it appropriately to * obtain a constant ZERO or ONE source. */#define __CONST(x, y)	\	(PVS_SRC_OPERAND(t_src_index(vp, &src[x]),	\			   t_swizzle(y),	\			   t_swizzle(y),	\			   t_swizzle(y),	\			   t_swizzle(y),	\			   t_src_class(src[x].File), \			   VSF_FLAG_NONE) | (src[x].RelAddr << 4))#define FREE_TEMPS() \	do { \		int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i; \		if((vp->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) { \			WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_used); \			vp->native = GL_FALSE; \		} \		u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \	} while (0)int r300VertexProgUpdateParams(GLcontext * ctx,			       struct r300_vertex_program_cont *vp, float *dst){	int pi;	struct gl_vertex_program *mesa_vp = &vp->mesa_program;	float *dst_o = dst;	struct gl_program_parameter_list *paramList;	if (mesa_vp->IsNVProgram) {		_mesa_load_tracked_matrices(ctx);		for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) {			*dst++ = ctx->VertexProgram.Parameters[pi][0];			*dst++ = ctx->VertexProgram.Parameters[pi][1];			*dst++ = ctx->VertexProgram.Parameters[pi][2];			*dst++ = ctx->VertexProgram.Parameters[pi][3];		}		return dst - dst_o;	}	assert(mesa_vp->Base.Parameters);	_mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters);	if (mesa_vp->Base.Parameters->NumParameters * 4 >	    VSF_MAX_FRAGMENT_LENGTH) {		fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__);		_mesa_exit(-1);	}	paramList = mesa_vp->Base.Parameters;	for (pi = 0; pi < paramList->NumParameters; pi++) {		switch (paramList->Parameters[pi].Type) {		case PROGRAM_STATE_VAR:		case PROGRAM_NAMED_PARAM:			//fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);		case PROGRAM_CONSTANT:			*dst++ = paramList->ParameterValues[pi][0];			*dst++ = paramList->ParameterValues[pi][1];			*dst++ = paramList->ParameterValues[pi][2];			*dst++ = paramList->ParameterValues[pi][3];			break;		default:			_mesa_problem(NULL, "Bad param type in %s",				      __FUNCTION__);		}	}	return dst - dst_o;}static unsigned long t_dst_mask(GLuint mask){	/* WRITEMASK_* is equivalent to VSF_FLAG_* */	return mask & VSF_FLAG_ALL;}static unsigned long t_dst_class(enum register_file file){	switch (file) {	case PROGRAM_TEMPORARY:		return PVS_DST_REG_TEMPORARY;	case PROGRAM_OUTPUT:		return PVS_DST_REG_OUT;	case PROGRAM_ADDRESS:		return PVS_DST_REG_A0;		/*		   case PROGRAM_INPUT:		   case PROGRAM_LOCAL_PARAM:		   case PROGRAM_ENV_PARAM:		   case PROGRAM_NAMED_PARAM:		   case PROGRAM_STATE_VAR:		   case PROGRAM_WRITE_ONLY:		   case PROGRAM_ADDRESS:		 */	default:		fprintf(stderr, "problem in %s", __FUNCTION__);		_mesa_exit(-1);		return -1;	}}static unsigned long t_dst_index(struct r300_vertex_program *vp,				 struct prog_dst_register *dst){	if (dst->File == PROGRAM_OUTPUT)		return vp->outputs[dst->Index];	return dst->Index;}static unsigned long t_src_class(enum register_file file){	switch (file) {	case PROGRAM_TEMPORARY:		return PVS_SRC_REG_TEMPORARY;	case PROGRAM_INPUT:		return PVS_SRC_REG_INPUT;	case PROGRAM_LOCAL_PARAM:	case PROGRAM_ENV_PARAM:	case PROGRAM_NAMED_PARAM:	case PROGRAM_CONSTANT:	case PROGRAM_STATE_VAR:		return PVS_SRC_REG_CONSTANT;		/*		   case PROGRAM_OUTPUT:		   case PROGRAM_WRITE_ONLY:		   case PROGRAM_ADDRESS:		 */	default:		fprintf(stderr, "problem in %s", __FUNCTION__);		_mesa_exit(-1);		return -1;	}}static INLINE unsigned long t_swizzle(GLubyte swizzle){/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */	return swizzle;}#if 0static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller){	int i;	if (vp == NULL) {		fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__,			caller);		return;	}	fprintf(stderr, "%s:<", caller);	for (i = 0; i < VERT_ATTRIB_MAX; i++)		fprintf(stderr, "%d ", vp->inputs[i]);	fprintf(stderr, ">\n");}#endifstatic unsigned long t_src_index(struct r300_vertex_program *vp,				 struct prog_src_register *src){	int i;	int max_reg = -1;	if (src->File == PROGRAM_INPUT) {		if (vp->inputs[src->Index] != -1)			return vp->inputs[src->Index];		for (i = 0; i < VERT_ATTRIB_MAX; i++)			if (vp->inputs[i] > max_reg)				max_reg = vp->inputs[i];		vp->inputs[src->Index] = max_reg + 1;		//vp_dump_inputs(vp, __FUNCTION__);		return vp->inputs[src->Index];	} else {		if (src->Index < 0) {			fprintf(stderr,				"negative offsets for indirect addressing do not work.\n");			return 0;		}		return src->Index;	}}/* these two functions should probably be merged... */static unsigned long t_src(struct r300_vertex_program *vp,			   struct prog_src_register *src){	/* src->NegateBase uses the NEGATE_ flags from program_instruction.h,	 * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.	 */	return PVS_SRC_OPERAND(t_src_index(vp, src),			       t_swizzle(GET_SWZ(src->Swizzle, 0)),			       t_swizzle(GET_SWZ(src->Swizzle, 1)),			       t_swizzle(GET_SWZ(src->Swizzle, 2)),			       t_swizzle(GET_SWZ(src->Swizzle, 3)),			       t_src_class(src->File),			       src->NegateBase) | (src->RelAddr << 4);}static unsigned long t_src_scalar(struct r300_vertex_program *vp,				  struct prog_src_register *src){	/* src->NegateBase uses the NEGATE_ flags from program_instruction.h,	 * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.	 */	return PVS_SRC_OPERAND(t_src_index(vp, src),			       t_swizzle(GET_SWZ(src->Swizzle, 0)),			       t_swizzle(GET_SWZ(src->Swizzle, 0)),			       t_swizzle(GET_SWZ(src->Swizzle, 0)),			       t_swizzle(GET_SWZ(src->Swizzle, 0)),			       t_src_class(src->File),			       src->			       NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) |	    (src->RelAddr << 4);}static GLboolean valid_dst(struct r300_vertex_program *vp,			   struct prog_dst_register *dst){	if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {		return GL_FALSE;	} else if (dst->File == PROGRAM_ADDRESS) {		assert(dst->Index == 0);	}	return GL_TRUE;}static GLuint *r300TranslateOpcodeABS(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	//MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W	inst[0] = PVS_OP_DST_OPERAND(VE_MAXIMUM,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src(vp, &src[0]);	inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),				  t_swizzle(GET_SWZ(src[0].Swizzle, 0)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 1)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 2)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 3)),				  t_src_class(src[0].File),				  (!src[0].				   NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |	    (src[0].RelAddr << 4);	inst[3] = 0;	return inst;}static GLuint *r300TranslateOpcodeADD(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(VE_ADD,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src(vp, &src[0]);	inst[2] = t_src(vp, &src[1]);	inst[3] = __CONST(1, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeARL(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(VE_FLT2FIX_DX,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src(vp, &src[0]);	inst[2] = __CONST(0, SWIZZLE_ZERO);	inst[3] = __CONST(0, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	//DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}	inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),				  t_swizzle(GET_SWZ(src[0].Swizzle, 0)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 1)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 2)),				  SWIZZLE_ZERO,				  t_src_class(src[0].File),				  src[0].				  NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |	    (src[0].RelAddr << 4);	inst[2] =	    PVS_SRC_OPERAND(t_src_index(vp, &src[1]),			    t_swizzle(GET_SWZ(src[1].Swizzle, 0)),			    t_swizzle(GET_SWZ(src[1].Swizzle, 1)),			    t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO,			    t_src_class(src[1].File),			    src[1].			    NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |	    (src[1].RelAddr << 4);	inst[3] = __CONST(1, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeDP4(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src(vp, &src[0]);	inst[2] = t_src(vp, &src[1]);	inst[3] = __CONST(1, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeDPH(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	//DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}	inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),				  t_swizzle(GET_SWZ(src[0].Swizzle, 0)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 1)),				  t_swizzle(GET_SWZ(src[0].Swizzle, 2)),				  PVS_SRC_SELECT_FORCE_1,				  t_src_class(src[0].File),				  src[0].				  NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |	    (src[0].RelAddr << 4);	inst[2] = t_src(vp, &src[1]);	inst[3] = __CONST(1, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeDST(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(VE_DISTANCE_VECTOR,				     GL_FALSE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src(vp, &src[0]);	inst[2] = t_src(vp, &src[1]);	inst[3] = __CONST(1, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeEX2(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_FULL_DX,				     GL_TRUE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src_scalar(vp, &src[0]);	inst[2] = __CONST(0, SWIZZLE_ZERO);	inst[3] = __CONST(0, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeEXP(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3]){	inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_DX,				     GL_TRUE,				     GL_FALSE,				     t_dst_index(vp, &vpi->DstReg),				     t_dst_mask(vpi->DstReg.WriteMask),				     t_dst_class(vpi->DstReg.File));	inst[1] = t_src_scalar(vp, &src[0]);	inst[2] = __CONST(0, SWIZZLE_ZERO);	inst[3] = __CONST(0, SWIZZLE_ZERO);	return inst;}static GLuint *r300TranslateOpcodeFLR(struct r300_vertex_program *vp,				      struct prog_instruction *vpi,				      GLuint * inst,				      struct prog_src_register src[3],				      int *u_temp_i){	/* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}

⌨️ 快捷键说明

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