r200_vertprog.c revision 4637235183b80963536f2364e4d50fcb894886dd
19597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath/************************************************************************** 29597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 39597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathCopyright (C) 2005 Aapo Tahkola. 49597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 59597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathAll Rights Reserved. 69597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 79597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathPermission is hereby granted, free of charge, to any person obtaining a 89597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathcopy of this software and associated documentation files (the "Software"), 99597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathto deal in the Software without restriction, including without limitation 109597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathon the rights to use, copy, modify, merge, publish, distribute, sub 119597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathlicense, and/or sell copies of the Software, and to permit persons to whom 129597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGraththe Software is furnished to do so, subject to the following conditions: 139597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 149597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathThe above copyright notice and this permission notice (including the next 159597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathparagraph) shall be included in all copies or substantial portions of the 169597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathSoftware. 179597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 189597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 199597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 209597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 219597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathTHE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 229597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 239597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 249597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathUSE OR OTHER DEALINGS IN THE SOFTWARE. 259597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 269597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath**************************************************************************/ 279597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 289597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath/* 299597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath * Authors: 309597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath * Aapo Tahkola <aet@rasterburn.org> 3179dcd7aa9cdb1784a4e799fbb4fc37374d6424f1Roland McGrath * Roland Scheidegger <rscheidegger_lists@hispeed.ch> 324582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath */ 339597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "main/glheader.h" 349597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "main/macros.h" 359597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "main/enums.h" 369597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "shader/program.h" 379597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "shader/prog_instruction.h" 389597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "shader/prog_parameter.h" 399597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "shader/prog_statevars.h" 409597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "shader/programopt.h" 419597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "tnl/tnl.h" 429597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 439597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "r200_context.h" 449597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "r200_vertprog.h" 459597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "r200_ioctl.h" 469597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#include "r200_tcl.h" 479597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 489597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#if SWIZZLE_X != VSF_IN_COMPONENT_X || \ 499597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath SWIZZLE_Y != VSF_IN_COMPONENT_Y || \ 509597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath SWIZZLE_Z != VSF_IN_COMPONENT_Z || \ 519597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath SWIZZLE_W != VSF_IN_COMPONENT_W || \ 529597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath SWIZZLE_ZERO != VSF_IN_COMPONENT_ZERO || \ 539597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath SWIZZLE_ONE != VSF_IN_COMPONENT_ONE || \ 549597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath WRITEMASK_X != VSF_FLAG_X || \ 5550a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin WRITEMASK_Y != VSF_FLAG_Y || \ 569597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath WRITEMASK_Z != VSF_FLAG_Z || \ 579597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath WRITEMASK_W != VSF_FLAG_W 589597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#error Cannot change these! 599597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#endif 609597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 619597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#define SCALAR_FLAG (1<<31) 629597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#define FLAG_MASK (1<<31) 639597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#define OP_MASK (0xf) /* we are unlikely to have more than 15 */ 649597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#define OPN(operator, ip) {#operator, OPCODE_##operator, ip} 659597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 669597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic struct{ 679597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath char *name; 689597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath int opcode; 699597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath unsigned long ip; /* number of input operands and flags */ 709597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath}op_names[]={ 719597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(ABS, 1), 729597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(ADD, 2), 739597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(ARL, 1|SCALAR_FLAG), 749597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(DP3, 2), 759597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(DP4, 2), 769597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(DPH, 2), 779597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(DST, 2), 7850a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin OPN(EX2, 1|SCALAR_FLAG), 799597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(EXP, 1|SCALAR_FLAG), 8050a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin OPN(FLR, 1), 8150a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin OPN(FRC, 1), 829597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(LG2, 1|SCALAR_FLAG), 839597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(LIT, 1), 849597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(LOG, 1|SCALAR_FLAG), 859597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(MAD, 3), 869597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(MAX, 2), 879597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(MIN, 2), 889597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(MOV, 1), 899597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(MUL, 2), 909597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(POW, 2|SCALAR_FLAG), 919597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(RCP, 1|SCALAR_FLAG), 929597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(RSQ, 1|SCALAR_FLAG), 939597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(SGE, 2), 949597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(SLT, 2), 959597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(SUB, 2), 969597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(SWZ, 1), 979597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(XPD, 2), 989597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(PRINT, 0), 999597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath OPN(END, 0), 1009597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath}; 1019597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#undef OPN 1029597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1039597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic GLboolean r200VertexProgUpdateParams(GLcontext *ctx, struct r200_vertex_program *vp) 1049597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 1059597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath r200ContextPtr rmesa = R200_CONTEXT( ctx ); 1069597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath GLfloat *fcmd = (GLfloat *)&rmesa->hw.vpp[0].cmd[VPP_CMD_0 + 1]; 1079597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath int pi; 1089597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath struct gl_vertex_program *mesa_vp = &vp->mesa_program; 1099597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath struct gl_program_parameter_list *paramList; 1109597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath drm_radeon_cmd_header_t tmp; 1119597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1129597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath R200_STATECHANGE( rmesa, vpp[0] ); 1139597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath R200_STATECHANGE( rmesa, vpp[1] ); 1149597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath assert(mesa_vp->Base.Parameters); 1159597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters); 1169597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath paramList = mesa_vp->Base.Parameters; 1179597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1189597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath if(paramList->NumParameters > R200_VSF_MAX_PARAM){ 1199597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__); 1209597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return GL_FALSE; 121bde8033605d0d7c83b4d7c4d4c2461775edcd0ccDmitry V. Levin } 1229597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1239597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath for(pi = 0; pi < paramList->NumParameters; pi++) { 1249597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath switch(paramList->Parameters[pi].Type) { 1259597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_STATE_VAR: 1269597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_NAMED_PARAM: 1279597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name); 1289597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_CONSTANT: 1299597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath *fcmd++ = paramList->ParameterValues[pi][0]; 1309597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath *fcmd++ = paramList->ParameterValues[pi][1]; 1319597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath *fcmd++ = paramList->ParameterValues[pi][2]; 1329597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath *fcmd++ = paramList->ParameterValues[pi][3]; 1339597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath break; 1349597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath default: 1359597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__); 1369597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath break; 1379597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 1389597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath if (pi == 95) { 1399597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fcmd = (GLfloat *)&rmesa->hw.vpp[1].cmd[VPP_CMD_0 + 1]; 1409597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 1419597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 1429597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath /* hack up the cmd_size so not the whole state atom is emitted always. */ 1439597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath rmesa->hw.vpp[0].cmd_size = 144985e8fd9bda8c6a786ae37155303c673d4f1bd42Roland McGrath 1 + 4 * ((paramList->NumParameters > 96) ? 96 : paramList->NumParameters); 1459597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath tmp.i = rmesa->hw.vpp[0].cmd[VPP_CMD_0]; 146612e0920c5feece7859860a3c8271b82b631788fDmitry V. Levin tmp.veclinear.count = (paramList->NumParameters > 96) ? 96 : paramList->NumParameters; 1479597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath rmesa->hw.vpp[0].cmd[VPP_CMD_0] = tmp.i; 1489597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath if (paramList->NumParameters > 96) { 1499597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath rmesa->hw.vpp[1].cmd_size = 1 + 4 * (paramList->NumParameters - 96); 1509597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath tmp.i = rmesa->hw.vpp[1].cmd[VPP_CMD_0]; 1519597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath tmp.veclinear.count = paramList->NumParameters - 96; 1529597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath rmesa->hw.vpp[1].cmd[VPP_CMD_0] = tmp.i; 1539597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 1549597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return GL_TRUE; 1559597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath} 1569597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1579597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic INLINE unsigned long t_dst_mask(GLuint mask) 1589597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 15964434f847dd6e26573969b196034edbcde72a30dRoland McGrath /* WRITEMASK_* is equivalent to VSF_FLAG_* */ 1606e2612785d30e876d74ba592a008941caf8ba116Roland McGrath return mask & VSF_FLAG_ALL; 1619597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath} 1629597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 1639597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic unsigned long t_dst(struct prog_dst_register *dst) 1649597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 1659597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath switch(dst->File) { 1669597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_TEMPORARY: 1679597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return ((dst->Index << R200_VPI_OUT_REG_INDEX_SHIFT) 1689597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath | R200_VSF_OUT_CLASS_TMP); 16950a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin case PROGRAM_OUTPUT: 17050a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin switch (dst->Index) { 1719597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_HPOS: 1729597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return R200_VSF_OUT_CLASS_RESULT_POS; 1739597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_COL0: 1749597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return R200_VSF_OUT_CLASS_RESULT_COLOR; 1759597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_COL1: 1769597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return ((1 << R200_VPI_OUT_REG_INDEX_SHIFT) 1779597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath | R200_VSF_OUT_CLASS_RESULT_COLOR); 1789597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_FOGC: 1799597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return R200_VSF_OUT_CLASS_RESULT_FOGC; 1809597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX0: 1819597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX1: 1829597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX2: 1839597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX3: 1849597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX4: 1859597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_TEX5: 1869597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return (((dst->Index - VERT_RESULT_TEX0) << R200_VPI_OUT_REG_INDEX_SHIFT) 1879597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath | R200_VSF_OUT_CLASS_RESULT_TEXC); 1889597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case VERT_RESULT_PSIZ: 1899597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return R200_VSF_OUT_CLASS_RESULT_POINTSIZE; 1909597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath default: 1919597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, "problem in %s, unknown dst output reg %d\n", __FUNCTION__, dst->Index); 1929597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath exit(0); 1939597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return 0; 194fdc45590eb96c43cf8f8e8db5f598fd3d7b9a385Dmitry V. Levin } 1959597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_ADDRESS: 1969597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath assert (dst->Index == 0); 1979597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return R200_VSF_OUT_CLASS_ADDR; 1989597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath default: 1999597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, "problem in %s, unknown register type %d\n", __FUNCTION__, dst->File); 2009597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath exit(0); 2019597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return 0; 2029597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 20386c26be3c88f382273222358fb2f7d537d022712Dmitry V. Levin} 2049597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 205b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenkostatic unsigned long t_src_class(enum register_file file) 2069597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 2079597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2089597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath switch(file){ 2099597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_TEMPORARY: 2109597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return VSF_IN_CLASS_TMP; 2119597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2127a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin case PROGRAM_INPUT: 2137a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin return VSF_IN_CLASS_ATTR; 2149597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2159597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_LOCAL_PARAM: 2169597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_ENV_PARAM: 2179597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_NAMED_PARAM: 2189597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_CONSTANT: 21924f0dcea027058050643659851c3fa7ddb1828dcDenys Vlasenko case PROGRAM_STATE_VAR: 2209597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return VSF_IN_CLASS_PARAM; 2219597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath /* 2229597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_OUTPUT: 2239597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath case PROGRAM_WRITE_ONLY: 224bde8033605d0d7c83b4d7c4d4c2461775edcd0ccDmitry V. Levin case PROGRAM_ADDRESS: 2257a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin */ 2267a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin default: 2279597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, "problem in %s", __FUNCTION__); 2289597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath exit(0); 2299597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 2309597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath} 23150a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin 2329597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic INLINE unsigned long t_swizzle(GLubyte swizzle) 23350a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin{ 23450a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */ 23550a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin return swizzle; 2369597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath} 2379597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2389597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#if 0 2399597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrathstatic void vp_dump_inputs(struct r200_vertex_program *vp, char *caller) 2409597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 2419597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath int i; 2429597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2439597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath if(vp == NULL){ 2449597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__, caller); 2459597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return ; 2469597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } 2479597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 24850a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin fprintf(stderr, "%s:<", caller); 24950a218d4ac83e6adf6f44785037dd25bd8037921Dmitry V. Levin for(i=0; i < VERT_ATTRIB_MAX; i++) 250b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko fprintf(stderr, "%d ", vp->inputs[i]); 2519597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath fprintf(stderr, ">\n"); 2529597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2539597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath} 2549597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath#endif 2554582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 2564582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrathstatic unsigned long t_src_index(struct r200_vertex_program *vp, struct prog_src_register *src) 2579597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath{ 2587a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin/* 2599597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath int i; 2609597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath int max_reg = -1; 2619597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath*/ 2629597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath if(src->File == PROGRAM_INPUT){ 2639597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath/* if(vp->inputs[src->Index] != -1) 2641e43961de5c9196aeef0d94cc3f291680879da88Dmitry V. Levin return vp->inputs[src->Index]; 2659597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2669597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath for(i=0; i < VERT_ATTRIB_MAX; i++) 2671e43961de5c9196aeef0d94cc3f291680879da88Dmitry V. Levin if(vp->inputs[i] > max_reg) 2689597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath max_reg = vp->inputs[i]; 2699597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 2701e43961de5c9196aeef0d94cc3f291680879da88Dmitry V. Levin vp->inputs[src->Index] = max_reg+1;*/ 2719597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 27224f0dcea027058050643659851c3fa7ddb1828dcDenys Vlasenko //vp_dump_inputs(vp, __FUNCTION__); 273334baa8cf336966ad6397922358bf2757ecad059Roland McGrath assert(vp->inputs[src->Index] != -1); 2749597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath return vp->inputs[src->Index]; 2759597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath } else { 2764582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath if (src->Index < 0) { 2774582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath fprintf(stderr, "WARNING negative offsets for indirect addressing do not work\n"); 2784582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath return 0; 2794582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath } 2804582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath return src->Index; 2814582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath } 2824582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath} 283b9839ef1295cd6d2ee56500226f8be080c63804fDmitry V. Levin 2844582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrathstatic unsigned long t_src(struct r200_vertex_program *vp, struct prog_src_register *src) 2854582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath{ 2864582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 2874582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath return MAKE_VSF_SOURCE(t_src_index(vp, src), 2884582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 0)), 2894582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 1)), 2904582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 2)), 2914582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 3)), 2924582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_src_class(src->File), 2934582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath src->NegateBase) | (src->RelAddr << 4); 2944582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath} 2954582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 2964582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrathstatic unsigned long t_src_scalar(struct r200_vertex_program *vp, struct prog_src_register *src) 2974582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath{ 2984582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 2994582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath return MAKE_VSF_SOURCE(t_src_index(vp, src), 3004582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 0)), 3014582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 0)), 3024582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_swizzle(GET_SWZ(src->Swizzle, 0)), 303fdbe3c513a521a075a5688df85056200c846776dDmitry V. Levin t_swizzle(GET_SWZ(src->Swizzle, 0)), 3044582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath t_src_class(src->File), 3054582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath src->NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src->RelAddr << 4); 3064582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath} 3074582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 3084582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrathstatic unsigned long t_opcode(enum prog_opcode opcode) 3094582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath{ 3104582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath 3114582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath switch(opcode){ 3124582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath case OPCODE_ADD: return R200_VPI_OUT_OP_ADD; 3134582127fea84ea0a9bcf72367e5bea30deb07715Roland McGrath /* FIXME: ARL works fine, but negative offsets won't work - fglrx just 3145670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath * seems to ignore neg offsets which isn't quite correct... 3155670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath */ 3165670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_ARL: return R200_VPI_OUT_OP_ARL; 3175670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_DP4: return R200_VPI_OUT_OP_DOT; 3185670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_DST: return R200_VPI_OUT_OP_DST; 3195670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_EX2: return R200_VPI_OUT_OP_EX2; 3205670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_EXP: return R200_VPI_OUT_OP_EXP; 3215670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_FRC: return R200_VPI_OUT_OP_FRC; 3225670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_LG2: return R200_VPI_OUT_OP_LG2; 3235670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_LIT: return R200_VPI_OUT_OP_LIT; 3245670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_LOG: return R200_VPI_OUT_OP_LOG; 3255670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_MAX: return R200_VPI_OUT_OP_MAX; 3265670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_MIN: return R200_VPI_OUT_OP_MIN; 3275670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_MUL: return R200_VPI_OUT_OP_MUL; 3285670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_RCP: return R200_VPI_OUT_OP_RCP; 3295670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_RSQ: return R200_VPI_OUT_OP_RSQ; 3305670331bf1ffb36fa815ddb817064e7f08dd2d97Roland McGrath case OPCODE_SGE: return R200_VPI_OUT_OP_SGE; 33106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin case OPCODE_SLT: return R200_VPI_OUT_OP_SLT; 33206bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 33306bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin default: 33406bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin fprintf(stderr, "%s: Should not be called with opcode %d!", __FUNCTION__, opcode); 33506bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin } 33606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin exit(-1); 33706bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin return 0; 33806bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin} 33906bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 34006bfe26236330044e553d1681083e82f39b76145Dmitry V. Levinstatic unsigned long op_operands(enum prog_opcode opcode) 34106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin{ 34206bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin int i; 34306bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 34406bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin /* Can we trust mesas opcodes to be in order ? */ 34506bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++) 34606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin if(op_names[i].opcode == opcode) 34706bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin return op_names[i].ip; 34806bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 34906bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin fprintf(stderr, "op %d not found in op_names\n", opcode); 35006bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin exit(-1); 35106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin return 0; 35206bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin} 35306bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 35406bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin/* TODO: Get rid of t_src_class call */ 35506bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin#define CMP_SRCS(a, b) (((a.RelAddr != b.RelAddr) || (a.Index != b.Index)) && \ 35606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \ 35706bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin t_src_class(b.File) == VSF_IN_CLASS_PARAM) || \ 35806bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin (t_src_class(a.File) == VSF_IN_CLASS_ATTR && \ 35906bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin t_src_class(b.File) == VSF_IN_CLASS_ATTR))) \ 36062d0428cf599ba0a6f2f73c83e174fada31ff7e7Dmitry V. Levin 36106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin/* fglrx on rv250 codes up unused sources as follows: 36206bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin unused but necessary sources are same as previous source, zero-ed out. 36306bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin unnecessary sources are same as previous source but with VSF_IN_CLASS_NONE set. 36406bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin i.e. an add (2 args) has its 2nd arg (if you use it as mov) zero-ed out, and 3rd arg 36506bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin set to VSF_IN_CLASS_NONE. Not sure if strictly necessary. */ 36606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 36706bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin/* use these simpler definitions. Must obviously not be used with not yet set up regs. 368623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin Those are NOT semantically equivalent to the r300 ones, requires code changes */ 369623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin#define ZERO_SRC_0 (((o_inst->src0 & ~(0xfff << R200_VPI_IN_X_SHIFT)) \ 37006bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin | ((R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_X_SHIFT) \ 37106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Y_SHIFT) \ 37206bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Z_SHIFT) \ 37306bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_W_SHIFT)))) 374feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 37506bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin#define ZERO_SRC_1 (((o_inst->src1 & ~(0xfff << R200_VPI_IN_X_SHIFT)) \ 37606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin | ((R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_X_SHIFT) \ 3770e091a1a3d5f931100ce10390053aed43068a68fRoland McGrath | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Y_SHIFT) \ 378245745cf07fb910e5e4e1e6cebb10fd5e7684adaRoland McGrath | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Z_SHIFT) \ 379623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_W_SHIFT)))) 38006bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 38106bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin#define ZERO_SRC_2 (((o_inst->src2 & ~(0xfff << R200_VPI_IN_X_SHIFT)) \ 3826f91dcfa337e68fb3290b1130d0f17095c6262d1Roland McGrath | ((R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_X_SHIFT) \ 383827461aeede2841226e69201f625d956cc6bdbcdRoland McGrath | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Y_SHIFT) \ 384e6a00aff77144c2331cbb1c94e8547398180ce8cRoland McGrath | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_Z_SHIFT) \ 3852bc744d7c737f025e970d3e708a81779c45a8b06Dmitry V. Levin | (R200_VPI_IN_SELECT_ZERO << R200_VPI_IN_W_SHIFT)))) 38606bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin 38706bfe26236330044e553d1681083e82f39b76145Dmitry V. Levin#define UNUSED_SRC_0 ((o_inst->src0 & ~15) | 9) 388623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin 389623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin#define UNUSED_SRC_1 ((o_inst->src1 & ~15) | 9) 390b9839ef1295cd6d2ee56500226f8be080c63804fDmitry V. Levin 391623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin#define UNUSED_SRC_2 ((o_inst->src2 & ~15) | 9) 392623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin 393623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin 3947a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin/** 3957a5b08fb26dcfb343e2c89567bf139af252a95fdDmitry V. Levin * Generate an R200 vertex program from Mesa's internal representation. 396623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin * 397623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin * \return GL_TRUE for success, GL_FALSE for failure. 398623003918a2d35d71bb7f44917b78c41a9ac169bDmitry V. Levin */ 399e9e3d70fa10022d1d642d723cd448b049dcff229Dmitry V. Levinstatic GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_vertex_program *vp) 4007bab9fcc44d72c375306c81648239fba21d492bdDmitry V. Levin{ 4017bab9fcc44d72c375306c81648239fba21d492bdDmitry V. Levin struct gl_vertex_program *mesa_vp = &vp->mesa_program; 402e9e3d70fa10022d1d642d723cd448b049dcff229Dmitry V. Levin struct prog_instruction *vpi; 403feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int i; 404feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath VERTEX_SHADER_INSTRUCTION *o_inst; 405feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath unsigned long operands; 406feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int are_srcs_scalar; 407feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath unsigned long hw_op; 408feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int dofogfix = 0; 409feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int fog_temp_i = 0; 410feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int free_inputs; 411feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int array_count = 0; 412feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int u_temp_used; 413feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 414feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath vp->native = GL_FALSE; 415feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath vp->translated = GL_TRUE; 416feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath vp->fogmode = ctx->Fog.Mode; 417feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 418feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if (mesa_vp->Base.NumInstructions == 0) 419feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath return GL_FALSE; 420feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 421feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath#if 0 422feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if ((mesa_vp->Base.InputsRead & 423feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 | 424feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 | 425feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) != 0) { 426feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if (R200_DEBUG & DEBUG_FALLBACKS) { 427feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath fprintf(stderr, "can't handle vert prog inputs 0x%x\n", 428feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath mesa_vp->Base.InputsRead); 429feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath } 430feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath return GL_FALSE; 431feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath } 432feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath#endif 4339597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath 434465acd2b322f19e9599f73248a00345f76d16c9fDmitry V. Levin if ((mesa_vp->Base.OutputsWritten & 435feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath ~((1 << VERT_RESULT_HPOS) | (1 << VERT_RESULT_COL0) | (1 << VERT_RESULT_COL1) | 4369597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath (1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) | 4379597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath (1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) | 438feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath (1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) { 439feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if (R200_DEBUG & DEBUG_FALLBACKS) { 440feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath fprintf(stderr, "can't handle vert prog outputs 0x%x\n", 441feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath mesa_vp->Base.OutputsWritten); 442feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath } 443feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath return GL_FALSE; 444feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath } 445feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 446feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if (mesa_vp->IsNVProgram) { 447feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath /* subtle differences in spec like guaranteed initialized regs could cause 448feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath headaches. Might want to remove the driconf option to enable it completely */ 449feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath return GL_FALSE; 450feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath } 451feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath /* Initial value should be last tmp reg that hw supports. 452feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath Strangely enough r300 doesnt mind even though these would be out of range. 453feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath Smart enough to realize that it doesnt need it? */ 454feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath int u_temp_i = R200_VSF_MAX_TEMPS - 1; 455feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath struct prog_src_register src[3]; 4568a56b8a8e77e095b6152253dc99fc5f4c226d02fPaolo Bonzini struct prog_dst_register dst; 4570873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab 4589597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath/* FIXME: is changing the prog safe to do here? */ 4590873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab if (mesa_vp->IsPositionInvariant && 4609597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath /* make sure we only do this once */ 4619597e6dc2cd220e8a6acbaa96ab4fcdb37c0def9Roland McGrath !(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { 4620873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab _mesa_insert_mvp_code(ctx, mesa_vp); 4630873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab } 4640873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab 4650873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with 4660873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab base e isn't directly available neither. */ 467feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) { 468feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath struct gl_program_parameter_list *paramList; 469feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 }; 470feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath paramList = mesa_vp->Base.Parameters; 4718a56b8a8e77e095b6152253dc99fc5f4c226d02fPaolo Bonzini vp->fogpidx = _mesa_add_state_reference(paramList, tokens); 4720873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab } 4730873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab 4740873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab vp->pos_end = 0; 4750873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab mesa_vp->Base.NumNativeInstructions = 0; 4760873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab if (mesa_vp->Base.Parameters) 477feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters; 478feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath else 479feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath mesa_vp->Base.NumNativeParameters = 0; 480feb838139028d6e063d10a6033269870a5c25b5cRoland McGrath 4818a56b8a8e77e095b6152253dc99fc5f4c226d02fPaolo Bonzini for(i = 0; i < VERT_ATTRIB_MAX; i++) 4820873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab vp->inputs[i] = -1; 4830873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab for(i = 0; i < 15; i++) 4840873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab vp->inputmap_rev[i] = 255; 4850873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab free_inputs = 0x2ffd; 4860873f29af4c1b2357e4f13338731665dd1ee2893Andreas Schwab 487465acd2b322f19e9599f73248a00345f76d16c9fDmitry V. Levin/* fglrx uses fixed inputs as follows for conventional attribs. 488 generic attribs use non-fixed assignment, fglrx will always use the 489 lowest attrib values available. We'll just do the same. 490 There are 12 generic attribs possible, corresponding to attrib 0, 2-11 491 and 13 in a hw vertex prog. 492 attr 1 and 12 aren't used for generic attribs as those cannot be made vec4 493 (correspond to vertex normal/weight - maybe weight actually could be made vec4). 494 Additionally, not more than 12 arrays in total are possible I think. 495 attr 0 is pos, R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0 496 attr 2-5 use colors 0-3 (R200_VTX_FP_RGBA << R200_VTX_COLOR_0/1/2/3_SHIFT in R200_SE_VTX_FMT_0) 497 attr 6-11 use tex 0-5 (4 << R200_VTX_TEX0/1/2/3/4/5_COMP_CNT_SHIFT in R200_SE_VTX_FMT_1) 498 attr 13 uses vtx1 pos (R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0) 499*/ 500 501/* attr 4,5 and 13 are only used with generic attribs. 502 Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is 503 not possibe to use with vertex progs as it is lacking in vert prog specification) */ 504/* may look different when using idx buf / input_route instead of se_vtx_fmt? */ 505 if (mesa_vp->Base.InputsRead & VERT_BIT_POS) { 506 vp->inputs[VERT_ATTRIB_POS] = 0; 507 vp->inputmap_rev[0] = VERT_ATTRIB_POS; 508 free_inputs &= ~(1 << 0); 509 array_count++; 510 } 511 if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { 512 vp->inputs[VERT_ATTRIB_WEIGHT] = 12; 513 vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT; 514 array_count++; 515 } 516 if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) { 517 vp->inputs[VERT_ATTRIB_NORMAL] = 1; 518 vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL; 519 array_count++; 520 } 521 if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) { 522 vp->inputs[VERT_ATTRIB_COLOR0] = 2; 523 vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0; 524 free_inputs &= ~(1 << 2); 525 array_count++; 526 } 527 if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) { 528 vp->inputs[VERT_ATTRIB_COLOR1] = 3; 529 vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1; 530 free_inputs &= ~(1 << 3); 531 array_count++; 532 } 533 if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) { 534 vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++; 535 vp->inputmap_rev[3] = VERT_ATTRIB_FOG; 536 array_count++; 537 } 538 for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) { 539 if (mesa_vp->Base.InputsRead & (1 << i)) { 540 vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6; 541 vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i; 542 free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6)); 543 array_count++; 544 } 545 } 546 /* using VERT_ATTRIB_TEX6/7 would be illegal */ 547 /* completely ignore aliasing? */ 548 for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { 549 int j; 550 /* completely ignore aliasing? */ 551 if (mesa_vp->Base.InputsRead & (1 << i)) { 552 array_count++; 553 if (array_count > 12) { 554 if (R200_DEBUG & DEBUG_FALLBACKS) { 555 fprintf(stderr, "more than 12 attribs used in vert prog\n"); 556 } 557 return GL_FALSE; 558 } 559 for (j = 0; j < 14; j++) { 560 /* will always find one due to limited array_count */ 561 if (free_inputs & (1 << j)) { 562 free_inputs &= ~(1 << j); 563 vp->inputs[i] = j; 564 if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */ 565 else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */ 566 else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */ 567 break; 568 } 569 } 570 } 571 } 572 573 if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { 574 if (R200_DEBUG & DEBUG_FALLBACKS) { 575 fprintf(stderr, "can't handle vert prog without position output\n"); 576 } 577 return GL_FALSE; 578 } 579 if (free_inputs & 1) { 580 if (R200_DEBUG & DEBUG_FALLBACKS) { 581 fprintf(stderr, "can't handle vert prog without position input\n"); 582 } 583 return GL_FALSE; 584 } 585 586 o_inst = vp->instr; 587 for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){ 588 operands = op_operands(vpi->Opcode); 589 are_srcs_scalar = operands & SCALAR_FLAG; 590 operands &= OP_MASK; 591 592 for(i = 0; i < operands; i++) { 593 src[i] = vpi->SrcReg[i]; 594 /* hack up default attrib values as per spec as swizzling. 595 normal, fog, secondary color. Crazy? 596 May need more if we don't submit vec4 elements? */ 597 if (src[i].File == PROGRAM_INPUT) { 598 if (src[i].Index == VERT_ATTRIB_NORMAL) { 599 int j; 600 for (j = 0; j < 4; j++) { 601 if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) { 602 src[i].Swizzle &= ~(SWIZZLE_W << (j*3)); 603 src[i].Swizzle |= SWIZZLE_ONE << (j*3); 604 } 605 } 606 } 607 else if (src[i].Index == VERT_ATTRIB_COLOR1) { 608 int j; 609 for (j = 0; j < 4; j++) { 610 if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) { 611 src[i].Swizzle &= ~(SWIZZLE_W << (j*3)); 612 src[i].Swizzle |= SWIZZLE_ZERO << (j*3); 613 } 614 } 615 } 616 else if (src[i].Index == VERT_ATTRIB_FOG) { 617 int j; 618 for (j = 0; j < 4; j++) { 619 if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) { 620 src[i].Swizzle &= ~(SWIZZLE_W << (j*3)); 621 src[i].Swizzle |= SWIZZLE_ONE << (j*3); 622 } 623 else if ((GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Y) || 624 GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Z) { 625 src[i].Swizzle &= ~(SWIZZLE_W << (j*3)); 626 src[i].Swizzle |= SWIZZLE_ZERO << (j*3); 627 } 628 } 629 } 630 } 631 } 632 633 if(operands == 3){ 634 if( CMP_SRCS(src[1], src[2]) || CMP_SRCS(src[0], src[2]) ){ 635 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, 636 (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 637 VSF_FLAG_ALL); 638 639 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[2]), 640 SWIZZLE_X, SWIZZLE_Y, 641 SWIZZLE_Z, SWIZZLE_W, 642 t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4); 643 644 o_inst->src1 = ZERO_SRC_0; 645 o_inst->src2 = UNUSED_SRC_1; 646 o_inst++; 647 648 src[2].File = PROGRAM_TEMPORARY; 649 src[2].Index = u_temp_i; 650 src[2].RelAddr = 0; 651 u_temp_i--; 652 } 653 } 654 655 if(operands >= 2){ 656 if( CMP_SRCS(src[1], src[0]) ){ 657 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, 658 (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 659 VSF_FLAG_ALL); 660 661 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 662 SWIZZLE_X, SWIZZLE_Y, 663 SWIZZLE_Z, SWIZZLE_W, 664 t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4); 665 666 o_inst->src1 = ZERO_SRC_0; 667 o_inst->src2 = UNUSED_SRC_1; 668 o_inst++; 669 670 src[0].File = PROGRAM_TEMPORARY; 671 src[0].Index = u_temp_i; 672 src[0].RelAddr = 0; 673 u_temp_i--; 674 } 675 } 676 677 dst = vpi->DstReg; 678 if (dst.File == PROGRAM_OUTPUT && 679 dst.Index == VERT_RESULT_FOGC && 680 dst.WriteMask & WRITEMASK_X) { 681 fog_temp_i = u_temp_i; 682 dst.File = PROGRAM_TEMPORARY; 683 dst.Index = fog_temp_i; 684 dofogfix = 1; 685 u_temp_i--; 686 } 687 688 /* These ops need special handling. */ 689 switch(vpi->Opcode){ 690 case OPCODE_POW: 691/* pow takes only one argument, first scalar is in slot x, 2nd in slot z (other slots don't matter). 692 So may need to insert additional instruction */ 693 if ((src[0].File == src[1].File) && 694 (src[0].Index == src[1].Index)) { 695 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst), 696 t_dst_mask(dst.WriteMask)); 697 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 698 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), 699 SWIZZLE_ZERO, 700 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), 701 SWIZZLE_ZERO, 702 t_src_class(src[0].File), 703 src[0].NegateBase) | (src[0].RelAddr << 4); 704 o_inst->src1 = UNUSED_SRC_0; 705 o_inst->src2 = UNUSED_SRC_0; 706 } 707 else { 708 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, 709 (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 710 VSF_FLAG_ALL); 711 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 712 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), 713 SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, 714 t_src_class(src[0].File), 715 src[0].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); 716 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 717 SWIZZLE_ZERO, SWIZZLE_ZERO, 718 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), SWIZZLE_ZERO, 719 t_src_class(src[1].File), 720 src[1].NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); 721 o_inst->src2 = UNUSED_SRC_1; 722 o_inst++; 723 724 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst), 725 t_dst_mask(dst.WriteMask)); 726 o_inst->src0 = MAKE_VSF_SOURCE(u_temp_i, 727 VSF_IN_COMPONENT_X, 728 VSF_IN_COMPONENT_Y, 729 VSF_IN_COMPONENT_Z, 730 VSF_IN_COMPONENT_W, 731 VSF_IN_CLASS_TMP, 732 VSF_FLAG_NONE); 733 o_inst->src1 = UNUSED_SRC_0; 734 o_inst->src2 = UNUSED_SRC_0; 735 u_temp_i--; 736 } 737 goto next; 738 739 case OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} 740 case OPCODE_SWZ: 741 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst), 742 t_dst_mask(dst.WriteMask)); 743 o_inst->src0 = t_src(vp, &src[0]); 744 o_inst->src1 = ZERO_SRC_0; 745 o_inst->src2 = UNUSED_SRC_1; 746 goto next; 747 748 case OPCODE_MAD: 749 /* only 2 read ports into temp memory thus may need the macro op MAD_2 750 instead (requiring 2 clocks) if all inputs are in temp memory 751 (and, only if they actually reference 3 distinct temps) */ 752 hw_op=(src[0].File == PROGRAM_TEMPORARY && 753 src[1].File == PROGRAM_TEMPORARY && 754 src[2].File == PROGRAM_TEMPORARY && 755 (((src[0].RelAddr << 8) | src[0].Index) != ((src[1].RelAddr << 8) | src[1].Index)) && 756 (((src[0].RelAddr << 8) | src[0].Index) != ((src[2].RelAddr << 8) | src[2].Index)) && 757 (((src[1].RelAddr << 8) | src[1].Index) != ((src[2].RelAddr << 8) | src[2].Index))) ? 758 R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD; 759 760 o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst), 761 t_dst_mask(dst.WriteMask)); 762 o_inst->src0 = t_src(vp, &src[0]); 763#if 0 764if ((o_inst - vp->instr) == 31) { 765/* fix up the broken vertex program of quake4 demo... */ 766o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 767 SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, 768 t_src_class(src[1].File), 769 src[1].NegateBase) | (src[1].RelAddr << 4); 770o_inst->src2 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 771 SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, 772 t_src_class(src[1].File), 773 src[1].NegateBase) | (src[1].RelAddr << 4); 774} 775else { 776 o_inst->src1 = t_src(vp, &src[1]); 777 o_inst->src2 = t_src(vp, &src[2]); 778} 779#else 780 o_inst->src1 = t_src(vp, &src[1]); 781 o_inst->src2 = t_src(vp, &src[2]); 782#endif 783 goto next; 784 785 case OPCODE_DP3://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} 786 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst), 787 t_dst_mask(dst.WriteMask)); 788 789 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 790 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), 791 t_swizzle(GET_SWZ(src[0].Swizzle, 1)), 792 t_swizzle(GET_SWZ(src[0].Swizzle, 2)), 793 SWIZZLE_ZERO, 794 t_src_class(src[0].File), 795 src[0].NegateBase) | (src[0].RelAddr << 4); 796 797 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 798 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), 799 t_swizzle(GET_SWZ(src[1].Swizzle, 1)), 800 t_swizzle(GET_SWZ(src[1].Swizzle, 2)), 801 SWIZZLE_ZERO, 802 t_src_class(src[1].File), 803 src[1].NegateBase) | (src[1].RelAddr << 4); 804 805 o_inst->src2 = UNUSED_SRC_1; 806 goto next; 807 808 case OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} 809 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst), 810 t_dst_mask(dst.WriteMask)); 811 812 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 813 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), 814 t_swizzle(GET_SWZ(src[0].Swizzle, 1)), 815 t_swizzle(GET_SWZ(src[0].Swizzle, 2)), 816 VSF_IN_COMPONENT_ONE, 817 t_src_class(src[0].File), 818 src[0].NegateBase) | (src[0].RelAddr << 4); 819 o_inst->src1 = t_src(vp, &src[1]); 820 o_inst->src2 = UNUSED_SRC_1; 821 goto next; 822 823 case OPCODE_SUB://ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W 824 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst), 825 t_dst_mask(dst.WriteMask)); 826 827 o_inst->src0 = t_src(vp, &src[0]); 828 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 829 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), 830 t_swizzle(GET_SWZ(src[1].Swizzle, 1)), 831 t_swizzle(GET_SWZ(src[1].Swizzle, 2)), 832 t_swizzle(GET_SWZ(src[1].Swizzle, 3)), 833 t_src_class(src[1].File), 834 (!src[1].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); 835 o_inst->src2 = UNUSED_SRC_1; 836 goto next; 837 838 case OPCODE_ABS://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 839 o_inst->op=MAKE_VSF_OP(R200_VPI_OUT_OP_MAX, t_dst(&dst), 840 t_dst_mask(dst.WriteMask)); 841 842 o_inst->src0=t_src(vp, &src[0]); 843 o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 844 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), 845 t_swizzle(GET_SWZ(src[0].Swizzle, 1)), 846 t_swizzle(GET_SWZ(src[0].Swizzle, 2)), 847 t_swizzle(GET_SWZ(src[0].Swizzle, 3)), 848 t_src_class(src[0].File), 849 (!src[0].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4); 850 o_inst->src2 = UNUSED_SRC_1; 851 goto next; 852 853 case OPCODE_FLR: 854 /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W} 855 ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */ 856 857 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_FRC, 858 (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 859 t_dst_mask(dst.WriteMask)); 860 861 o_inst->src0 = t_src(vp, &src[0]); 862 o_inst->src1 = UNUSED_SRC_0; 863 o_inst->src2 = UNUSED_SRC_1; 864 o_inst++; 865 866 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst), 867 t_dst_mask(dst.WriteMask)); 868 869 o_inst->src0 = t_src(vp, &src[0]); 870 o_inst->src1 = MAKE_VSF_SOURCE(u_temp_i, 871 VSF_IN_COMPONENT_X, 872 VSF_IN_COMPONENT_Y, 873 VSF_IN_COMPONENT_Z, 874 VSF_IN_COMPONENT_W, 875 VSF_IN_CLASS_TMP, 876 /* Not 100% sure about this */ 877 (!src[0].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE/*VSF_FLAG_ALL*/); 878 879 o_inst->src2 = UNUSED_SRC_0; 880 u_temp_i--; 881 goto next; 882 883 case OPCODE_XPD: 884 /* mul r0, r1.yzxw, r2.zxyw 885 mad r0, -r2.yzxw, r1.zxyw, r0 886 */ 887 hw_op=(src[0].File == PROGRAM_TEMPORARY && 888 src[1].File == PROGRAM_TEMPORARY && 889 (((src[0].RelAddr << 8) | src[0].Index) != ((src[1].RelAddr << 8) | src[1].Index))) ? 890 R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD; 891 892 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL, 893 (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 894 t_dst_mask(dst.WriteMask)); 895 896 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 897 t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y 898 t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z 899 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x 900 t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w 901 t_src_class(src[0].File), 902 src[0].NegateBase) | (src[0].RelAddr << 4); 903 904 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 905 t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z 906 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x 907 t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y 908 t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w 909 t_src_class(src[1].File), 910 src[1].NegateBase) | (src[1].RelAddr << 4); 911 912 o_inst->src2 = UNUSED_SRC_1; 913 o_inst++; 914 u_temp_i--; 915 916 o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst), 917 t_dst_mask(dst.WriteMask)); 918 919 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]), 920 t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y 921 t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z 922 t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x 923 t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w 924 t_src_class(src[1].File), 925 (!src[1].NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4); 926 927 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]), 928 t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z 929 t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x 930 t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y 931 t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w 932 t_src_class(src[0].File), 933 src[0].NegateBase) | (src[0].RelAddr << 4); 934 935 o_inst->src2 = MAKE_VSF_SOURCE(u_temp_i+1, 936 VSF_IN_COMPONENT_X, 937 VSF_IN_COMPONENT_Y, 938 VSF_IN_COMPONENT_Z, 939 VSF_IN_COMPONENT_W, 940 VSF_IN_CLASS_TMP, 941 VSF_FLAG_NONE); 942 goto next; 943 944 case OPCODE_END: 945 assert(0); 946 default: 947 break; 948 } 949 950 o_inst->op = MAKE_VSF_OP(t_opcode(vpi->Opcode), t_dst(&dst), 951 t_dst_mask(dst.WriteMask)); 952 953 if(are_srcs_scalar){ 954 switch(operands){ 955 case 1: 956 o_inst->src0 = t_src_scalar(vp, &src[0]); 957 o_inst->src1 = UNUSED_SRC_0; 958 o_inst->src2 = UNUSED_SRC_1; 959 break; 960 961 case 2: 962 o_inst->src0 = t_src_scalar(vp, &src[0]); 963 o_inst->src1 = t_src_scalar(vp, &src[1]); 964 o_inst->src2 = UNUSED_SRC_1; 965 break; 966 967 case 3: 968 o_inst->src0 = t_src_scalar(vp, &src[0]); 969 o_inst->src1 = t_src_scalar(vp, &src[1]); 970 o_inst->src2 = t_src_scalar(vp, &src[2]); 971 break; 972 973 default: 974 fprintf(stderr, "illegal number of operands %lu\n", operands); 975 exit(-1); 976 break; 977 } 978 } else { 979 switch(operands){ 980 case 1: 981 o_inst->src0 = t_src(vp, &src[0]); 982 o_inst->src1 = UNUSED_SRC_0; 983 o_inst->src2 = UNUSED_SRC_1; 984 break; 985 986 case 2: 987 o_inst->src0 = t_src(vp, &src[0]); 988 o_inst->src1 = t_src(vp, &src[1]); 989 o_inst->src2 = UNUSED_SRC_1; 990 break; 991 992 case 3: 993 o_inst->src0 = t_src(vp, &src[0]); 994 o_inst->src1 = t_src(vp, &src[1]); 995 o_inst->src2 = t_src(vp, &src[2]); 996 break; 997 998 default: 999 fprintf(stderr, "illegal number of operands %lu\n", operands); 1000 exit(-1); 1001 break; 1002 } 1003 } 1004 next: 1005 1006 if (dofogfix) { 1007 o_inst++; 1008 if (vp->fogmode == GL_EXP) { 1009 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL, 1010 (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 1011 VSF_FLAG_X); 1012 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE); 1013 o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE); 1014 o_inst->src2 = UNUSED_SRC_1; 1015 o_inst++; 1016 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E, 1017 R200_VSF_OUT_CLASS_RESULT_FOGC, 1018 VSF_FLAG_X); 1019 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL); 1020 o_inst->src1 = UNUSED_SRC_0; 1021 o_inst->src2 = UNUSED_SRC_1; 1022 } 1023 else if (vp->fogmode == GL_EXP2) { 1024 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL, 1025 (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 1026 VSF_FLAG_X); 1027 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE); 1028 o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE); 1029 o_inst->src2 = UNUSED_SRC_1; 1030 o_inst++; 1031 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL, 1032 (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 1033 VSF_FLAG_X); 1034 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE); 1035 o_inst->src1 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE); 1036 o_inst->src2 = UNUSED_SRC_1; 1037 o_inst++; 1038 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E, 1039 R200_VSF_OUT_CLASS_RESULT_FOGC, 1040 VSF_FLAG_X); 1041 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL); 1042 o_inst->src1 = UNUSED_SRC_0; 1043 o_inst->src2 = UNUSED_SRC_1; 1044 } 1045 else { /* fogmode == GL_LINEAR */ 1046 /* could do that with single op (dot) if using params like 1047 with fixed function pipeline fog */ 1048 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, 1049 (fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP, 1050 VSF_FLAG_X); 1051 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL); 1052 o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, Z, Z, Z, Z, PARAM, NONE); 1053 o_inst->src2 = UNUSED_SRC_1; 1054 o_inst++; 1055 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL, 1056 R200_VSF_OUT_CLASS_RESULT_FOGC, 1057 VSF_FLAG_X); 1058 o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE); 1059 o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, W, W, W, W, PARAM, NONE); 1060 o_inst->src2 = UNUSED_SRC_1; 1061 1062 } 1063 dofogfix = 0; 1064 } 1065 1066 u_temp_used = (R200_VSF_MAX_TEMPS - 1) - u_temp_i; 1067 if (mesa_vp->Base.NumNativeTemporaries < 1068 (mesa_vp->Base.NumTemporaries + u_temp_used)) { 1069 mesa_vp->Base.NumNativeTemporaries = 1070 mesa_vp->Base.NumTemporaries + u_temp_used; 1071 } 1072 if ((mesa_vp->Base.NumTemporaries + u_temp_used) > R200_VSF_MAX_TEMPS) { 1073 if (R200_DEBUG & DEBUG_FALLBACKS) { 1074 fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_used); 1075 } 1076 return GL_FALSE; 1077 } 1078 u_temp_i = R200_VSF_MAX_TEMPS - 1; 1079 if(o_inst - vp->instr >= R200_VSF_MAX_INST) { 1080 mesa_vp->Base.NumNativeInstructions = 129; 1081 if (R200_DEBUG & DEBUG_FALLBACKS) { 1082 fprintf(stderr, "more than 128 native instructions\n"); 1083 } 1084 return GL_FALSE; 1085 } 1086 if ((o_inst->op & R200_VSF_OUT_CLASS_MASK) == R200_VSF_OUT_CLASS_RESULT_POS) { 1087 vp->pos_end = (o_inst - vp->instr); 1088 } 1089 } 1090 1091 vp->native = GL_TRUE; 1092 mesa_vp->Base.NumNativeInstructions = (o_inst - vp->instr); 1093#if 0 1094 fprintf(stderr, "hw program:\n"); 1095 for(i=0; i < vp->program.length; i++) 1096 fprintf(stderr, "%08x\n", vp->instr[i]); 1097#endif 1098 return GL_TRUE; 1099} 1100 1101void r200SetupVertexProg( GLcontext *ctx ) { 1102 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1103 struct r200_vertex_program *vp = (struct r200_vertex_program *)ctx->VertexProgram.Current; 1104 GLboolean fallback; 1105 GLint i; 1106 1107 if (!vp->translated || (ctx->Fog.Enabled && ctx->Fog.Mode != vp->fogmode)) { 1108 rmesa->curr_vp_hw = NULL; 1109 r200_translate_vertex_program(ctx, vp); 1110 } 1111 /* could optimize setting up vertex progs away for non-tcl hw */ 1112 fallback = !(vp->native && r200VertexProgUpdateParams(ctx, vp) && 1113 rmesa->radeon.radeonScreen->drmSupportsVertexProgram); 1114 TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, fallback); 1115 if (rmesa->radeon.TclFallback) return; 1116 1117 R200_STATECHANGE( rmesa, vap ); 1118 /* FIXME: fglrx sets R200_VAP_SINGLE_BUF_STATE_ENABLE too. Do we need it? 1119 maybe only when using more than 64 inst / 96 param? */ 1120 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE /*| R200_VAP_SINGLE_BUF_STATE_ENABLE*/; 1121 1122 R200_STATECHANGE( rmesa, pvs ); 1123 1124 rmesa->hw.pvs.cmd[PVS_CNTL_1] = (0 << R200_PVS_CNTL_1_PROGRAM_START_SHIFT) | 1125 ((vp->mesa_program.Base.NumNativeInstructions - 1) << R200_PVS_CNTL_1_PROGRAM_END_SHIFT) | 1126 (vp->pos_end << R200_PVS_CNTL_1_POS_END_SHIFT); 1127 rmesa->hw.pvs.cmd[PVS_CNTL_2] = (0 << R200_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | 1128 (vp->mesa_program.Base.NumNativeParameters << R200_PVS_CNTL_2_PARAM_COUNT_SHIFT); 1129 1130 /* maybe user clip planes just work with vertex progs... untested */ 1131 if (ctx->Transform.ClipPlanesEnabled) { 1132 R200_STATECHANGE( rmesa, tcl ); 1133 if (vp->mesa_program.IsPositionInvariant) { 1134 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (ctx->Transform.ClipPlanesEnabled << 2); 1135 } 1136 else { 1137 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(0xfc); 1138 } 1139 } 1140 1141 if (vp != rmesa->curr_vp_hw) { 1142 GLuint count = vp->mesa_program.Base.NumNativeInstructions; 1143 drm_radeon_cmd_header_t tmp; 1144 1145 R200_STATECHANGE( rmesa, vpi[0] ); 1146 R200_STATECHANGE( rmesa, vpi[1] ); 1147 1148 /* FIXME: what about using a memcopy... */ 1149 for (i = 0; (i < 64) && i < count; i++) { 1150 rmesa->hw.vpi[0].cmd[VPI_OPDST_0 + 4 * i] = vp->instr[i].op; 1151 rmesa->hw.vpi[0].cmd[VPI_SRC0_0 + 4 * i] = vp->instr[i].src0; 1152 rmesa->hw.vpi[0].cmd[VPI_SRC1_0 + 4 * i] = vp->instr[i].src1; 1153 rmesa->hw.vpi[0].cmd[VPI_SRC2_0 + 4 * i] = vp->instr[i].src2; 1154 } 1155 /* hack up the cmd_size so not the whole state atom is emitted always. 1156 This may require some more thought, we may emit half progs on lost state, but 1157 hopefully it won't matter? 1158 WARNING: must not use R200_DB_STATECHANGE, this will produce bogus (and rejected) 1159 packet emits (due to the mismatched cmd_size and count in cmd/last_cmd) */ 1160 rmesa->hw.vpi[0].cmd_size = 1 + 4 * ((count > 64) ? 64 : count); 1161 tmp.i = rmesa->hw.vpi[0].cmd[VPI_CMD_0]; 1162 tmp.veclinear.count = (count > 64) ? 64 : count; 1163 rmesa->hw.vpi[0].cmd[VPI_CMD_0] = tmp.i; 1164 if (count > 64) { 1165 for (i = 0; i < (count - 64); i++) { 1166 rmesa->hw.vpi[1].cmd[VPI_OPDST_0 + 4 * i] = vp->instr[i + 64].op; 1167 rmesa->hw.vpi[1].cmd[VPI_SRC0_0 + 4 * i] = vp->instr[i + 64].src0; 1168 rmesa->hw.vpi[1].cmd[VPI_SRC1_0 + 4 * i] = vp->instr[i + 64].src1; 1169 rmesa->hw.vpi[1].cmd[VPI_SRC2_0 + 4 * i] = vp->instr[i + 64].src2; 1170 } 1171 rmesa->hw.vpi[1].cmd_size = 1 + 4 * (count - 64); 1172 tmp.i = rmesa->hw.vpi[1].cmd[VPI_CMD_0]; 1173 tmp.veclinear.count = count - 64; 1174 rmesa->hw.vpi[1].cmd[VPI_CMD_0] = tmp.i; 1175 } 1176 rmesa->curr_vp_hw = vp; 1177 } 1178} 1179 1180 1181static void 1182r200BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog) 1183{ 1184 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1185 1186 switch(target){ 1187 case GL_VERTEX_PROGRAM_ARB: 1188 rmesa->curr_vp_hw = NULL; 1189 break; 1190 default: 1191 _mesa_problem(ctx, "Target not supported yet!"); 1192 break; 1193 } 1194} 1195 1196static struct gl_program * 1197r200NewProgram(GLcontext *ctx, GLenum target, GLuint id) 1198{ 1199 struct r200_vertex_program *vp; 1200 1201 switch(target){ 1202 case GL_VERTEX_PROGRAM_ARB: 1203 vp = CALLOC_STRUCT(r200_vertex_program); 1204 return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); 1205 case GL_FRAGMENT_PROGRAM_ARB: 1206 case GL_FRAGMENT_PROGRAM_NV: 1207 return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(gl_fragment_program), target, id ); 1208 default: 1209 _mesa_problem(ctx, "Bad target in r200NewProgram"); 1210 } 1211 return NULL; 1212} 1213 1214 1215static void 1216r200DeleteProgram(GLcontext *ctx, struct gl_program *prog) 1217{ 1218 _mesa_delete_program(ctx, prog); 1219} 1220 1221static void 1222r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) 1223{ 1224 struct r200_vertex_program *vp = (void *)prog; 1225 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1226 1227 switch(target) { 1228 case GL_VERTEX_PROGRAM_ARB: 1229 vp->translated = GL_FALSE; 1230 vp->fogpidx = 0; 1231/* memset(&vp->translated, 0, sizeof(struct r200_vertex_program) - sizeof(struct gl_vertex_program));*/ 1232 r200_translate_vertex_program(ctx, vp); 1233 rmesa->curr_vp_hw = NULL; 1234 break; 1235 case GL_FRAGMENT_SHADER_ATI: 1236 rmesa->afs_loaded = NULL; 1237 break; 1238 } 1239 /* need this for tcl fallbacks */ 1240 _tnl_program_string(ctx, target, prog); 1241} 1242 1243static GLboolean 1244r200IsProgramNative(GLcontext *ctx, GLenum target, struct gl_program *prog) 1245{ 1246 struct r200_vertex_program *vp = (void *)prog; 1247 1248 switch(target){ 1249 case GL_VERTEX_STATE_PROGRAM_NV: 1250 case GL_VERTEX_PROGRAM_ARB: 1251 if (!vp->translated) { 1252 r200_translate_vertex_program(ctx, vp); 1253 } 1254 /* does not take parameters etc. into account */ 1255 return vp->native; 1256 default: 1257 _mesa_problem(ctx, "Bad target in r200NewProgram"); 1258 } 1259 return 0; 1260} 1261 1262void r200InitShaderFuncs(struct dd_function_table *functions) 1263{ 1264 functions->NewProgram = r200NewProgram; 1265 functions->BindProgram = r200BindProgram; 1266 functions->DeleteProgram = r200DeleteProgram; 1267 functions->ProgramStringNotify = r200ProgramStringNotify; 1268 functions->IsProgramNative = r200IsProgramNative; 1269} 1270