12bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin/************************************************************************** 22bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * 32bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * Copyright 2011 The Chromium OS authors. 42bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * All Rights Reserved. 52bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * 62bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * Permission is hereby granted, free of charge, to any person obtaining a 72bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * copy of this software and associated documentation files (the 82bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * "Software"), to deal in the Software without restriction, including 92bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * without limitation the rights to use, copy, modify, merge, publish, 102bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * distribute, sub license, and/or sell copies of the Software, and to 112bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * permit persons to whom the Software is furnished to do so, subject to 122bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * the following conditions: 132bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * 142bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * The above copyright notice and this permission notice (including the 152bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * next paragraph) shall be included in all copies or substantial portions 162bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * of the Software. 172bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * 182bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 192bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 202bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 212bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * IN NO EVENT SHALL GOOGLE AND/OR ITS SUPPLIERS BE LIABLE FOR 222bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 232bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 242bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 252bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * 262bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin **************************************************************************/ 272bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 282bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "i915_reg.h" 292bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "i915_context.h" 302bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "i915_fpc.h" 312bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 322bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "pipe/p_shader_tokens.h" 332bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "util/u_math.h" 342bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "util/u_memory.h" 352bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "util/u_string.h" 362bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "tgsi/tgsi_parse.h" 372bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin#include "tgsi/tgsi_dump.h" 382bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3951f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesinstatic boolean same_src_dst_reg(struct i915_full_src_register* s1, struct i915_full_dst_register* d1) 4051f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin{ 4151f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin return (s1->Register.File == d1->Register.File && 4251f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin s1->Register.Indirect == d1->Register.Indirect && 4351f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin s1->Register.Dimension == d1->Register.Dimension && 4451f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin s1->Register.Index == d1->Register.Index); 4551f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin} 4651f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin 472bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesinstatic boolean same_dst_reg(struct i915_full_dst_register* d1, struct i915_full_dst_register* d2) 482bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin{ 492bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin return (d1->Register.File == d2->Register.File && 502bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Indirect == d2->Register.Indirect && 512bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Dimension == d2->Register.Dimension && 522bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Index == d2->Register.Index); 532bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin} 542bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 552bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesinstatic boolean same_src_reg(struct i915_full_src_register* d1, struct i915_full_src_register* d2) 562bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin{ 572bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin return (d1->Register.File == d2->Register.File && 582bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Indirect == d2->Register.Indirect && 592bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Dimension == d2->Register.Dimension && 602bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Index == d2->Register.Index && 612bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Absolute == d2->Register.Absolute && 622bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin d1->Register.Negate == d2->Register.Negate); 632bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin} 642bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 65687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesinstatic boolean has_destination(unsigned opcode) 66687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin{ 67687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin return (opcode != TGSI_OPCODE_NOP && 68687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin opcode != TGSI_OPCODE_KIL && 693235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin opcode != TGSI_OPCODE_KILP && 703235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin opcode != TGSI_OPCODE_END && 71687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin opcode != TGSI_OPCODE_RET); 72687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin} 73687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin 74053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesinstatic boolean is_unswizzled(struct i915_full_src_register* r, 759baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin unsigned write_mask) 76053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin{ 779baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_X && r->Register.SwizzleX != TGSI_SWIZZLE_X) 78053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin return FALSE; 799baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_Y && r->Register.SwizzleY != TGSI_SWIZZLE_Y) 80053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin return FALSE; 819baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_Z && r->Register.SwizzleZ != TGSI_SWIZZLE_Z) 82053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin return FALSE; 839baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_W && r->Register.SwizzleW != TGSI_SWIZZLE_W) 84053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin return FALSE; 8531484b068d4d2842593498c75ec831dfa75af14eStéphane Marchesin return TRUE; 86053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin} 872bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 88f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesinstatic boolean op_commutes(unsigned opcode) 89f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin{ 90841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin switch(opcode) 91841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin { 92841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_ADD: 93841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_MUL: 94841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP2: 95841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP3: 96841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP4: 97841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin return TRUE; 98841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin } 99f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin return FALSE; 100f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin} 101f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin 102f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesinstatic unsigned op_neutral_element(unsigned opcode) 103f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin{ 104841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin switch(opcode) 105841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin { 106841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_ADD: 107841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin return TGSI_SWIZZLE_ZERO; 108841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_MUL: 109841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP2: 110841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP3: 111841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin case TGSI_OPCODE_DP4: 112841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin return TGSI_SWIZZLE_ONE; 113841eee5d44b222a5819804726187683033eb71dbStéphane Marchesin } 114f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin 115f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin debug_printf("Unknown opcode %d\n",opcode); 116f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin return TGSI_SWIZZLE_ZERO; 117f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin} 118f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin 1192bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin/* 1209baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin * Sets the swizzle to the neutral element for the operation for the bits 1219baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin * of writemask which are set, swizzle to identity otherwise. 1229baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin */ 1239baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesinstatic void set_neutral_element_swizzle(struct i915_full_src_register* r, 1249baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin unsigned write_mask, 1259baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin unsigned neutral) 1269baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin{ 1279baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_X ) 1289baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleX = neutral; 1299baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin else 1309baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleX = TGSI_SWIZZLE_X; 1319baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 1329baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_Y ) 1339baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleY = neutral; 1349baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin else 1359baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleY = TGSI_SWIZZLE_Y; 1369baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 1379baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_Z ) 1389baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleZ = neutral; 1399baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin else 1409baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleZ = TGSI_SWIZZLE_Z; 1419baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 1429baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin if ( write_mask & TGSI_WRITEMASK_W ) 1439baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleW = neutral; 1449baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin else 1459baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin r->Register.SwizzleW = TGSI_SWIZZLE_W; 1469baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin} 1479baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 1483235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic void copy_src_reg(struct i915_src_register* o, const struct tgsi_src_register* i) 1493235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin{ 1503235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->File = i->File; 1513235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Indirect = i->Indirect; 1523235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Dimension = i->Dimension; 1533235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Index = i->Index; 1543235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->SwizzleX = i->SwizzleX; 1553235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->SwizzleY = i->SwizzleY; 1563235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->SwizzleZ = i->SwizzleZ; 1573235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->SwizzleW = i->SwizzleW; 1583235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Absolute = i->Absolute; 1593235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Negate = i->Negate; 1603235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin} 1613235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1623235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic void copy_dst_reg(struct i915_dst_register* o, const struct tgsi_dst_register* i) 1633235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin{ 1643235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->File = i->File; 1653235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->WriteMask = i->WriteMask; 1663235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Indirect = i->Indirect; 1673235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Dimension = i->Dimension; 1683235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin o->Index = i->Index; 1693235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin} 1703235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1713235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic void copy_instruction(struct i915_full_instruction* o, const struct tgsi_full_instruction* i) 1723235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin{ 1733235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin memcpy(&o->Instruction, &i->Instruction, sizeof(o->Instruction)); 1743235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin memcpy(&o->Texture, &i->Texture, sizeof(o->Texture)); 1753235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1763235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_dst_reg(&o->Dst[0].Register, &i->Dst[0].Register); 1773235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1783235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_src_reg(&o->Src[0].Register, &i->Src[0].Register); 1793235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_src_reg(&o->Src[1].Register, &i->Src[1].Register); 1803235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_src_reg(&o->Src[2].Register, &i->Src[2].Register); 1813235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin} 1823235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1833235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic void copy_token(union i915_full_token* o, union tgsi_full_token* i) 1843235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin{ 1853235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin if (i->Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) 1863235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin memcpy(o, i, sizeof(*o)); 1873235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin else 1883235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_instruction(&o->FullInstruction, &i->FullInstruction); 1893235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1903235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin} 1913235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 1929baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin/* 1932bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * Optimize away things like: 1942bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * MUL OUT[0].xyz, TEMP[1], TEMP[2] 1952bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * MOV OUT[0].w, TEMP[2] 19651f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * into: 1972bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * MUL OUT[0].xyzw, TEMP[1].xyz1, TEMP[2] 1982bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin * This is useful for optimizing texenv. 1992bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin */ 200f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesinstatic void i915_fpc_optimize_mov_after_alu(union i915_full_token* current, union i915_full_token* next) 2012bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin{ 2022bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 2032bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 204f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin op_commutes(current->FullInstruction.Instruction.Opcode) && 2059baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate && 2062bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && 2079a15b1eb95da138231994b6d05cf09c60ba1d842Stéphane Marchesin same_dst_reg(&next->FullInstruction.Dst[0], ¤t->FullInstruction.Dst[0]) && 208053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin same_src_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[1]) && 2093235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin !same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) && 2109baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) && 2119baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(¤t->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) && 2129baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) ) 2132bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin { 2142bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; 2159baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 2169baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin set_neutral_element_swizzle(¤t->FullInstruction.Src[1], 0, 0); 2179baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin set_neutral_element_swizzle(¤t->FullInstruction.Src[0], 2189baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin next->FullInstruction.Dst[0].Register.WriteMask, 2199baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin op_neutral_element(current->FullInstruction.Instruction.Opcode)); 2209baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 2219baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask | 2229baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin next->FullInstruction.Dst[0].Register.WriteMask; 2232bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin return; 2242bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin } 2252bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 2262bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 2272bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 228f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin op_commutes(current->FullInstruction.Instruction.Opcode) && 2299baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate && 2302bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && 2319a15b1eb95da138231994b6d05cf09c60ba1d842Stéphane Marchesin same_dst_reg(&next->FullInstruction.Dst[0], ¤t->FullInstruction.Dst[0]) && 232053af6ac8cda226a62844fc014ed9f133557c111Stéphane Marchesin same_src_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[0]) && 2333235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin !same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) && 2349baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) && 2359baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(¤t->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) && 2369baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) ) 2372bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin { 2382bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; 2399baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 2409baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin set_neutral_element_swizzle(¤t->FullInstruction.Src[0], 0, 0); 2419baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin set_neutral_element_swizzle(¤t->FullInstruction.Src[1], 2429baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin next->FullInstruction.Dst[0].Register.WriteMask, 2439baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin op_neutral_element(current->FullInstruction.Instruction.Opcode)); 2449baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin 2459baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask | 2469baad926602547e14d4fdc6a66ec629dfa6acbb2Stéphane Marchesin next->FullInstruction.Dst[0].Register.WriteMask; 2472bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin return; 2482bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin } 2492bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin} 2502bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 25151f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin/* 25251f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * Optimize away things like: 2533235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin * MOV TEMP[0].xyz TEMP[0].xyzx 2543235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin * into: 2553235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin * NOP 2563235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin */ 2573235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic boolean i915_fpc_useless_mov(union tgsi_full_token* tgsi_current) 2583235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin{ 2593235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin union i915_full_token current; 2603235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin copy_token(¤t , tgsi_current); 2613235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin if ( current.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 2623235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin current.FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && 2633235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin has_destination(current.FullInstruction.Instruction.Opcode) && 2643235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin current.FullInstruction.Instruction.Saturate == TGSI_SAT_NONE && 2653235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin current.FullInstruction.Src[0].Register.Absolute == 0 && 2663235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin current.FullInstruction.Src[0].Register.Negate == 0 && 2673235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin is_unswizzled(¤t.FullInstruction.Src[0], current.FullInstruction.Dst[0].Register.WriteMask) && 2683235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin same_src_dst_reg(¤t.FullInstruction.Src[0], ¤t.FullInstruction.Dst[0]) ) 2693235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin { 2703235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin return TRUE; 2713235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin } 2723235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin return FALSE; 2733235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin} 2743235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 2753235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin/* 2763235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin * Optimize away things like: 27751f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * *** TEMP[0], TEMP[1], TEMP[2] 27851f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * MOV OUT[0] TEMP[0] 27951f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * into: 28051f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin * *** OUT[0], TEMP[1], TEMP[2] 28151f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin */ 2823235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesinstatic void i915_fpc_optimize_useless_mov_after_inst(union i915_full_token* current, union i915_full_token* next) 28351f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin{ 28451f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 28551f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && 28651f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && 287687e62a5d76e2e4cbbc6268e5b0e3f148b681185Stéphane Marchesin has_destination(current->FullInstruction.Instruction.Opcode) && 28851f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->FullInstruction.Instruction.Saturate == TGSI_SAT_NONE && 28951f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->FullInstruction.Src[0].Register.Absolute == 0 && 29051f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->FullInstruction.Src[0].Register.Negate == 0 && 291b50d250e02457f367c195ee1808b061e0dfe2d00Stéphane Marchesin next->FullInstruction.Dst[0].Register.File == TGSI_FILE_OUTPUT && 29251f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) && 29351f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin current->FullInstruction.Dst[0].Register.WriteMask == next->FullInstruction.Dst[0].Register.WriteMask && 29451f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) ) 29551f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin { 29651f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; 29751f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin 29851f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin current->FullInstruction.Dst[0] = next->FullInstruction.Dst[0]; 29951f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin return; 30051f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin } 30151f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin} 30251f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin 3032bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesinstruct i915_token_list* i915_optimize(const struct tgsi_token *tokens) 3042bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin{ 3052bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin struct i915_token_list *out_tokens = MALLOC(sizeof(struct i915_token_list)); 3062bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin struct tgsi_parse_context parse; 3072bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin int i = 0; 3082bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3097a10976adb65010bec7952a80d1b43d62b3f8bb3Brian Paul out_tokens->NumTokens = 0; 3107a10976adb65010bec7952a80d1b43d62b3f8bb3Brian Paul 3112bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin /* Count the tokens */ 3122bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_init( &parse, tokens ); 3132bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin while( !tgsi_parse_end_of_tokens( &parse ) ) { 3142bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_token( &parse ); 3152bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin out_tokens->NumTokens++; 3162bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin } 3172bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_free (&parse); 3182bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3192bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin /* Allocate our tokens */ 3202bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin out_tokens->Tokens = MALLOC(sizeof(union i915_full_token) * out_tokens->NumTokens); 3212bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3222bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_init( &parse, tokens ); 3232bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin while( !tgsi_parse_end_of_tokens( &parse ) ) { 3242bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_token( &parse ); 3253235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 3263235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin if (i915_fpc_useless_mov(&parse.FullToken)) { 3273235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin out_tokens->NumTokens--; 3283235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin continue; 3293235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin } 3303235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin 3312bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin copy_token(&out_tokens->Tokens[i] , &parse.FullToken); 3322bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 33351f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin if (i > 0) { 3343235435e801122fb6d28c0bcc232ddaeb6b9c568Stéphane Marchesin i915_fpc_optimize_useless_mov_after_inst(&out_tokens->Tokens[i-1], &out_tokens->Tokens[i]); 335f934c80faf0d1fb559cee0a903daba321098320dStéphane Marchesin i915_fpc_optimize_mov_after_alu(&out_tokens->Tokens[i-1], &out_tokens->Tokens[i]); 33651f641291d19d05acf04f08dd51215c2702a1695Stéphane Marchesin } 3372bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin i++; 3382bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin } 3392bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin tgsi_parse_free (&parse); 3402bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3412bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin return out_tokens; 3422bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin} 3432bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3442bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesinvoid i915_optimize_free(struct i915_token_list* tokens) 3452bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin{ 3462bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin free(tokens->Tokens); 3472bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin free(tokens); 3482bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin} 3492bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 3502bc5e0e97ba7b6c32f6ff90cb90448173d74b89bStéphane Marchesin 351