svga_tgsi_insn.c revision 1ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3
13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**********************************************************
23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2008-2009 VMware, Inc.  All rights reserved.
33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person
53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation
63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without
73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy,
83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies
93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is
103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions:
113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be
133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software.
143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE.
233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/
253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_shader_tokens.h"
289bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul#include "tgsi/tgsi_dump.h"
293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "tgsi/tgsi_parse.h"
303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h"
312f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul#include "util/u_math.h"
323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_tgsi_emit.h"
343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_context.h"
353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_vs_postamble( struct svga_shader_emitter *emit );
383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ps_postamble( struct svga_shader_emitter *emit );
393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic unsigned
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_opcode(
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint opcode )
463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (opcode) {
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS;
493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD;
503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC;
513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP2A:       return SVGA3DOP_DP2ADD;
523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3;
533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4;
543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_FRC:        return SVGA3DOP_FRC;
553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MAD:        return SVGA3DOP_MAD;
563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MAX:        return SVGA3DOP_MAX;
573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MIN:        return SVGA3DOP_MIN;
583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MOV:        return SVGA3DOP_MOV;
593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MUL:        return SVGA3DOP_MUL;
603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NOP:        return SVGA3DOP_NOP;
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NRM4:       return SVGA3DOP_NRM;
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      debug_printf("Unkown opcode %u\n", opcode);
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert( 0 );
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return SVGA3DOP_LAST_INST;
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic unsigned translate_file( unsigned file )
713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (file) {
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_TEMPORARY: return SVGA3DREG_TEMP;
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_INPUT:     return SVGA3DREG_INPUT;
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_OUTPUT:    return SVGA3DREG_OUTPUT; /* VS3.0+ only */
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_IMMEDIATE: return SVGA3DREG_CONST;
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_CONSTANT:  return SVGA3DREG_CONST;
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_SAMPLER:   return SVGA3DREG_SAMPLER;
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_ADDRESS:   return SVGA3DREG_ADDR;
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert( 0 );
823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return SVGA3DREG_TEMP;
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic SVGA3dShaderDestToken
923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_dst_register( struct svga_shader_emitter *emit,
933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn,
943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        unsigned idx )
953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
967d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dest;
983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
995b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch (reg->Register.File) {
1003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_OUTPUT:
1013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Output registers encode semantic information in their name.
1023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Need to lookup a table built at decl time:
1033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
1045b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      dest = emit->output_map[reg->Register.Index];
1053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
1084516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul      {
1094516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         unsigned index = reg->Register.Index;
1104516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         assert(index < SVGA3D_TEMPREG_MAX);
1114516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         index = MIN2(index, SVGA3D_TEMPREG_MAX - 1);
1124516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         dest = dst_register(translate_file(reg->Register.File), index);
1134516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul      }
1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1175b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   dest.mask = reg->Register.WriteMask;
1187384cdf651dc69098f4d988dd3b217879ec63336José Fonseca   assert(dest.mask);
1193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (insn->Instruction.Saturate)
1213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      dest.dstMod = SVGA3DDSTMOD_SATURATE;
1223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return dest;
1243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic struct src_register
1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzswizzle( struct src_register src,
1293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int x,
1303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int y,
1313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int z,
1323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int w )
1333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   x = (src.base.swizzle >> (x * 2)) & 0x3;
1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   y = (src.base.swizzle >> (y * 2)) & 0x3;
1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   z = (src.base.swizzle >> (z * 2)) & 0x3;
1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   w = (src.base.swizzle >> (w * 2)) & 0x3;
1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src.base.swizzle = TRANSLATE_SWIZZLE(x,y,z,w);
1403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src;
1423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic struct src_register
1453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzscalar( struct src_register src,
1463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz        int comp )
1473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return swizzle( src, comp, comp, comp, comp );
1493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
1523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_arl_needs_adjustment( const struct svga_shader_emitter *emit )
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl)
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return FALSE;
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE int
1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_arl_adjustment( const struct svga_shader_emitter *emit )
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl)
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return emit->arl_consts[i].number;
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic struct src_register
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_src_register( const struct svga_shader_emitter *emit,
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_src_register *reg )
1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src;
1803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   switch (reg->Register.File) {
1823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_INPUT:
1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Input registers are referred to by their semantic name rather
1843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * than by index.  Use the mapping build up from the decls:
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
18691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = emit->input_map[reg->Register.Index];
1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_IMMEDIATE:
1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Immediates are appended after TGSI constants in the D3D
1913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * constant buffer.
1923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
19391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = src_register( translate_file( reg->Register.File ),
19491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                          reg->Register.Index +
1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          emit->imm_start );
1963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
19991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = src_register( translate_file( reg->Register.File ),
20091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                          reg->Register.Index );
2013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
2033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2050742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   /* Indirect addressing.
2063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
2070742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   if (reg->Register.Indirect) {
2080742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      if (emit->unit == PIPE_SHADER_FRAGMENT) {
2090742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         /* Pixel shaders have only loop registers for relative
2100742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          * addressing into inputs. Ignore the redundant address
2110742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          * register, the contents of aL should be in sync with it.
2120742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          */
2130742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         if (reg->Register.File == TGSI_FILE_INPUT) {
2140742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.base.relAddr = 1;
2150742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect = src_token(SVGA3DREG_LOOP, 0);
2160742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         }
2170742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      }
2180742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      else {
2190742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         /* Constant buffers only.
2200742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          */
2210742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         if (reg->Register.File == TGSI_FILE_CONSTANT) {
2220742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            /* we shift the offset towards the minimum */
2230742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            if (svga_arl_needs_adjustment( emit )) {
2240742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol               src.base.num -= svga_arl_adjustment( emit );
2250742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            }
2260742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.base.relAddr = 1;
2270742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol
2280742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            /* Not really sure what should go in the second token:
2290742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol             */
2300742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect = src_token( SVGA3DREG_ADDR,
2310742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol                                      reg->Indirect.Index );
2320742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol
2330742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect.swizzle = SWIZZLE_XXXX;
2340742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         }
2353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
2363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src = swizzle( src,
23991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleX,
24091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleY,
24191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleZ,
24291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleW );
2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* src.mod isn't a bitfield, unfortunately:
2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * See tgsi_util_get_full_src_register_sign_mode for implementation details.
2463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
24791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (reg->Register.Absolute) {
24891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Negate)
2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_ABS;
2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
25491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Negate)
2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_NEG;
2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
2573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_NONE;
2583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src;
2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
2654516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * Get a temporary register.
2664516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * Note: if we exceed the temporary register limit we just use
2674516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * register SVGA3D_TEMPREG_MAX - 1.
2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE SVGA3dShaderDestToken
2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_temp( struct svga_shader_emitter *emit )
2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i = emit->nr_hw_temp + emit->internal_temp_count++;
2734516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul   assert(i < SVGA3D_TEMPREG_MAX);
2744516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul   i = MIN2(i, SVGA3D_TEMPREG_MAX - 1);
2753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return dst_register( SVGA3DREG_TEMP, i );
2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Release a single temp.  Currently only effective if it was the last
2793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * allocated temp, otherwise release will be delayed until the next
2803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * call to reset_temp_regs().
2813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
2823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE void
2833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzrelease_temp( struct svga_shader_emitter *emit,
2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              SVGA3dShaderDestToken temp )
2853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (temp.num == emit->internal_temp_count - 1)
2873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->internal_temp_count--;
2883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void reset_temp_regs( struct svga_shader_emitter *emit )
2913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->internal_temp_count = 0;
2933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
296965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca/* Replace the src with the temporary specified in the dst, but copying
297965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * only the necessary channels, and preserving the original swizzle (which is
298965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * important given that several opcodes have constraints in the allowed
299965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * swizzles).
300965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca */
301965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonsecastatic boolean emit_repl( struct svga_shader_emitter *emit,
302965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca                          SVGA3dShaderDestToken dst,
303965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca                          struct src_register *src0)
304965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca{
305965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   unsigned src0_swizzle;
306965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   unsigned chan;
307965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
308965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   assert(SVGA3dShaderGetRegType(dst.value) == SVGA3DREG_TEMP);
309965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
310965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0_swizzle = src0->base.swizzle;
311965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
312965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   dst.mask = 0;
313965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   for (chan = 0; chan < 4; ++chan) {
314965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      unsigned swizzle = (src0_swizzle >> (chan *2)) & 0x3;
315965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      dst.mask |= 1 << swizzle;
316965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   }
317965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   assert(dst.mask);
318965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
319965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0->base.swizzle = SVGA3DSWIZZLE_NONE;
320965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
321965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, *src0 ))
322965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      return FALSE;
323965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
324965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   *src0 = src( dst );
325965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0->base.swizzle = src0_swizzle;
326965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
327965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   return TRUE;
328965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca}
329965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
330965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
3313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op0( struct svga_shader_emitter *emit,
3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest )
3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, inst ) &&
3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_dst( emit, dest ));
3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op1( struct svga_shader_emitter *emit,
3403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0 )
3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_op1( emit, inst, dest, src0 );
3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* SVGA shaders may not refer to >1 constant register in a single
3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * instruction.  This function checks for that usage and inserts a
3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * move to temporary if detected.
3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The same applies to input registers -- at most a single input
3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * register may be read by any instruction.
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op2( struct svga_shader_emitter *emit,
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0,
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src1 )
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderRegType type0, type1;
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp = FALSE;
3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp.value = 0;
3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type0 = SVGA3dShaderGetRegType( src0.base.value );
3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type1 = SVGA3dShaderGetRegType( src1.base.value );
3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_CONST &&
3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       type1 == SVGA3DREG_CONST &&
3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.num != src1.base.num)
3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp = TRUE;
3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_INPUT &&
3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       type1 == SVGA3DREG_INPUT &&
3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.num != src1.base.num)
3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp = TRUE;
3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
379965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp) {
3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp = get_temp( emit );
3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
382965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp, &src0 ))
3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_op2( emit, inst, dest, src0, src1 ))
3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp)
3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp );
3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* SVGA shaders may not refer to >1 constant register in a single
3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * instruction.  This function checks for that usage and inserts a
3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * move to temporary if detected.
3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
4003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op3( struct svga_shader_emitter *emit,
4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0,
4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src1,
4053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src2 )
4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp0;
4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp1;
4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp0 = FALSE;
4103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp1 = FALSE;
4113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderRegType type0, type1, type2;
4123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp0.value = 0;
4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp1.value = 0;
4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type0 = SVGA3dShaderGetRegType( src0.base.value );
4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type1 = SVGA3dShaderGetRegType( src1.base.value );
4173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type2 = SVGA3dShaderGetRegType( src2.base.value );
4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (inst.op != SVGA3DOP_SINCOS) {
4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (type0 == SVGA3DREG_CONST &&
4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          ((type1 == SVGA3DREG_CONST && src0.base.num != src1.base.num) ||
4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_temp0 = TRUE;
4243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (type1 == SVGA3DREG_CONST &&
4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          (type2 == SVGA3DREG_CONST && src1.base.num != src2.base.num))
4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_temp1 = TRUE;
4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_INPUT &&
4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       ((type1 == SVGA3DREG_INPUT && src0.base.num != src1.base.num) ||
4323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp0 = TRUE;
4343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type1 == SVGA3DREG_INPUT &&
4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       (type2 == SVGA3DREG_INPUT && src1.base.num != src2.base.num))
4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp1 = TRUE;
4383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
439965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp0) {
4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp0 = get_temp( emit );
4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
442965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp0, &src0 ))
4433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
4443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
446965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp1) {
4473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp1 = get_temp( emit );
4483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
449965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp1, &src1 ))
4503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
4513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_op3( emit, inst, dest, src0, src1, src2 ))
4543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
4553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp1)
4573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp1 );
4583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp0)
4593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp0 );
4603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
4613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
46484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
46584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
46684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell/* SVGA shaders may not refer to >1 constant register in a single
46784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell * instruction.  This function checks for that usage and inserts a
46884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell * move to temporary if detected.
46984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell */
47084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwellstatic boolean submit_op4( struct svga_shader_emitter *emit,
47184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           SVGA3dShaderInstToken inst,
47284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           SVGA3dShaderDestToken dest,
47384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src0,
47484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src1,
47584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src2,
47684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src3)
47784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell{
47884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderDestToken temp0;
47984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderDestToken temp3;
48084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   boolean need_temp0 = FALSE;
48184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   boolean need_temp3 = FALSE;
48284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderRegType type0, type1, type2, type3;
48384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
48484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   temp0.value = 0;
48584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   temp3.value = 0;
48684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type0 = SVGA3dShaderGetRegType( src0.base.value );
48784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type1 = SVGA3dShaderGetRegType( src1.base.value );
48884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type2 = SVGA3dShaderGetRegType( src2.base.value );
48984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type3 = SVGA3dShaderGetRegType( src2.base.value );
49084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
49184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   /* Make life a little easier - this is only used by the TXD
49284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    * instruction which is guaranteed not to have a constant/input reg
49384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    * in one slot at least:
49484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    */
49584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   assert(type1 == SVGA3DREG_SAMPLER);
49684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
49784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type0 == SVGA3DREG_CONST &&
49884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
49984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell        (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
50084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp0 = TRUE;
50184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
50284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type3 == SVGA3DREG_CONST &&
50384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
50484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp3 = TRUE;
50584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
50684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type0 == SVGA3DREG_INPUT &&
50784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
50884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
50984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp0 = TRUE;
51084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
51184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type3 == SVGA3DREG_INPUT &&
51284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
51384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp3 = TRUE;
51484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
515965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp0) {
51684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      temp0 = get_temp( emit );
51784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
518965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp0, &src0 ))
51984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell         return FALSE;
52084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   }
52184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
522965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp3) {
52384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      temp3 = get_temp( emit );
52484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
525965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp3, &src3 ))
52684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell         return FALSE;
52784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   }
52884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
52984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
53084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      return FALSE;
53184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
53284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (need_temp3)
53384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      release_temp( emit, temp3 );
53484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (need_temp0)
53584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      release_temp( emit, temp0 );
53684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   return TRUE;
53784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell}
53884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
53984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
54015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonsecastatic boolean alias_src_dst( struct src_register src,
54115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                              SVGA3dShaderDestToken dst )
54215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca{
54315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (src.base.num != dst.num)
54415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
54515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
54615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (SVGA3dShaderGetRegType(dst.value) !=
54715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       SVGA3dShaderGetRegType(src.base.value))
54815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
54915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
55015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return TRUE;
55115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca}
55215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
55315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
55415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonsecastatic boolean submit_lrp(struct svga_shader_emitter *emit,
55515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          SVGA3dShaderDestToken dst,
55615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src0,
55715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src1,
55815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src2)
55915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca{
56015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   SVGA3dShaderDestToken tmp;
56115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   boolean need_dst_tmp = FALSE;
56215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
56315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   /* The dst reg must be a temporary, and not be the same as src0 or src2 */
56415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
56515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       alias_src_dst(src0, dst) ||
56615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       alias_src_dst(src2, dst))
56715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      need_dst_tmp = TRUE;
56815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
56915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (need_dst_tmp) {
57015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp = get_temp( emit );
57115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp.mask = dst.mask;
57215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
57315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   else {
57415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp = dst;
57515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
57615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
57715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (!submit_op3(emit, inst_token( SVGA3DOP_LRP ), tmp, src0, src1, src2))
57815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
57915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
58015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (need_dst_tmp) {
58115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
58215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca         return FALSE;
58315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
58415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
58515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return TRUE;
58615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca}
58715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
58815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
5893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_def_const( struct svga_shader_emitter *emit,
5903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               SVGA3dShaderConstType type,
5913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               unsigned idx,
5923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float a,
5933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float b,
5943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float c,
5953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float d )
5963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3DOpDefArgs def;
5983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken opcode;
5993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (type) {
6013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case SVGA3D_CONST_TYPE_FLOAT:
6023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      opcode = inst_token( SVGA3DOP_DEF );
6033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.dst = dst_register( SVGA3DREG_CONST, idx );
6043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[0] = a;
6053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[1] = b;
6063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[2] = c;
6073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[3] = d;
6083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case SVGA3D_CONST_TYPE_INT:
6103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      opcode = inst_token( SVGA3DOP_DEFI );
6113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.dst = dst_register( SVGA3DREG_CONSTINT, idx );
6123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[0] = (int)a;
6133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[1] = (int)b;
6143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[2] = (int)c;
6153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[3] = (int)d;
6163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
6183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
6197e64701263f8158fb4138610ba63df41eefe6594Vinson Lee      opcode = inst_token( SVGA3DOP_NOP );
6203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
6223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_instruction(emit, opcode) ||
6243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       !svga_shader_emit_dwords( emit, def.values, Elements(def.values)))
6253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_zero_immediate( struct svga_shader_emitter *emit )
6323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
633279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_float_const++;
6343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6351ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   /* Emit the constant (0, 0.5, -1, 1) and use swizzling to generate
6362f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul    * other useful vectors.
6372f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul    */
6383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
6391ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                        idx, 0, 0.5, -1, 1 ))
6403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->zero_immediate_idx = idx;
6433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->created_zero_immediate = TRUE;
6443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_loop_const( struct svga_shader_emitter *emit )
6503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
651279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_int_const++;
6523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_INT, idx,
6543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        255, /* iteration count */
6553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        0, /* initial value */
6563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        1, /* step size */
6573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        0 /* not used, must be 0 */))
6583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->loop_const_idx = idx;
6613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->created_loop_const = TRUE;
6623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_arl_consts( struct svga_shader_emitter *emit )
6683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
6693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
6703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; i += 4) {
6723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      int j;
673279492386ffe741c2f5b91919b37068562b6a282Michal Krol      unsigned idx = emit->nr_hw_float_const++;
6743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float vals[4];
6753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      for (j = 0; j < 4 && (j + i) < emit->num_arl_consts; ++j) {
6763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         vals[j] = emit->arl_consts[i + j].number;
6773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit->arl_consts[i + j].idx = idx;
6783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         switch (j) {
6793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 0:
6803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_X;
6813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 1:
6833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Y;
6843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 2:
6863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Z;
6873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 3:
6893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_W;
6903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
6923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
6933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      while (j < 4)
6943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         vals[j++] = 0;
6953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
6973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vals[0], vals[1],
6983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vals[2], vals[3]))
6993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
7003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
7013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
7033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_vface( struct svga_shader_emitter *emit )
7073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->emitted_vface);
7093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src_register(SVGA3DREG_MISCTYPE,
7103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       SVGA3DMISCREG_FACE);
7113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* returns {0, 0, 0, 1} immediate */
7143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_zero_immediate( struct svga_shader_emitter *emit )
7163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->created_zero_immediate);
7183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->zero_immediate_idx >= 0);
7192f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return swizzle(src_register( SVGA3DREG_CONST,
7202f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                                emit->zero_immediate_idx),
7212f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                  0, 0, 0, 3);
7222f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul}
7232f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
7242f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul/* returns {1, 1, 1, -1} immediate */
7252f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulstatic INLINE struct src_register
7262f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulget_pos_neg_one_immediate( struct svga_shader_emitter *emit )
7272f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul{
7282f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   assert(emit->created_zero_immediate);
7292f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   assert(emit->zero_immediate_idx >= 0);
7302f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return swizzle(src_register( SVGA3DREG_CONST,
7312f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                                emit->zero_immediate_idx),
7322f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                  3, 3, 3, 2);
7333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7351ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul/* returns {0.5, 0.5, 0.5, 0.5} immediate */
7361ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulstatic INLINE struct src_register
7371ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulget_half_immediate( struct svga_shader_emitter *emit )
7381ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul{
7391ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   assert(emit->created_zero_immediate);
7401ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   assert(emit->zero_immediate_idx >= 0);
7411ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   return swizzle(src_register(SVGA3DREG_CONST, emit->zero_immediate_idx),
7421ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                  1, 1, 1, 1);
7431ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul}
7441ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
7453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* returns the loop const */
7463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_loop_const( struct svga_shader_emitter *emit )
7483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->created_loop_const);
7503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->loop_const_idx >= 0);
7513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src_register( SVGA3DREG_CONSTINT,
7523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        emit->loop_const_idx );
7533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_fake_arl_const( struct svga_shader_emitter *emit )
7573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register reg;
7593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int idx = 0, swizzle = 0, i;
7603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++ i) {
7623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl) {
7633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         idx = emit->arl_consts[i].idx;
7643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         swizzle = emit->arl_consts[i].swizzle;
7653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
7663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
7673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   reg = src_register( SVGA3DREG_CONST, idx );
7693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return scalar(reg, swizzle);
7703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_tex_dimensions( struct svga_shader_emitter *emit, int sampler_num )
7743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int idx;
7763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register reg;
7773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* the width/height indexes start right after constants */
7793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   idx = emit->key.fkey.tex[sampler_num].width_height_idx +
7803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
7813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   reg = src_register( SVGA3DREG_CONST, idx );
7833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return reg;
7843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_fake_arl(struct svga_shader_emitter *emit,
7873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn)
7883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
7907d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
7913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = get_fake_arl_const( emit );
7923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
7933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken tmp = get_temp( emit );
7943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
7963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
7973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), tmp, src( tmp ),
7993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src1))
8003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
8013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* replicate the original swizzle */
8033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = src(tmp);
8043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1.base.swizzle = src0.base.swizzle;
8053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst_token( SVGA3DOP_MOVA ),
8073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      dst, src1 );
8083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_if(struct svga_shader_emitter *emit,
8113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn)
8123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8130adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   struct src_register src0 = translate_src_register(
8147d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
8153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
8163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
8173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if_token.control = SVGA3DOPCOMPC_NE;
8193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = scalar(zero, TGSI_SWIZZLE_X);
8203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8210adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   if (SVGA3dShaderGetRegType(src0.base.value) == SVGA3DREG_CONST) {
8220adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      /*
8230adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca       * Max different constant registers readable per IFC instruction is 1.
8240adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca       */
8250adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
8260adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      SVGA3dShaderDestToken tmp = get_temp( emit );
8270adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
8280adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
8290adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca         return FALSE;
8300adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
8310adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      src0 = scalar(src( tmp ), TGSI_SWIZZLE_X);
8320adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   }
8330adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
834a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level++;
835a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
8363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, if_token ) &&
8370adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca           emit_src( emit, src0 ) &&
8383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, zero ) );
8393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_endif(struct svga_shader_emitter *emit,
8423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn)
8433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
844a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level--;
845a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
8463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit,
8473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             inst_token( SVGA3DOP_ENDIF )));
8483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_else(struct svga_shader_emitter *emit,
8513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn)
8523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit,
8543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             inst_token( SVGA3DOP_ELSE )));
8553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI FLR instruction.
8583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    FLR  DST, SRC
8593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
8603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    FRC  TMP, SRC
8613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    SUB  DST, SRC, TMP
8623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
8633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_floor(struct svga_shader_emitter *emit,
8643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          const struct tgsi_full_instruction *insn )
8653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
8673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
8687d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
8693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
8703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* FRC  TMP, SRC */
8723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ), temp, src0 ))
8733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
8743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SUB  DST, SRC, TMP */
8763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src0,
8773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    negate( src( temp ) ) ))
8783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
8793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
8813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
884a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul/* Translate the following TGSI CEIL instruction.
885a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    CEIL  DST, SRC
886a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul * To the following SVGA3D instruction sequence.
887a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    FRC  TMP, -SRC
888a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    ADD  DST, SRC, TMP
889a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul */
890a1c5513c175a2c13594dde7110822b205cabfc14Brian Paulstatic boolean emit_ceil(struct svga_shader_emitter *emit,
891a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul                         const struct tgsi_full_instruction *insn)
892a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul{
893a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
894a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   const struct src_register src0 = translate_src_register(emit, &insn->Src[0]);
895a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   SVGA3dShaderDestToken temp = get_temp(emit);
896a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
897a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   /* FRC  TMP, -SRC */
898a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), temp, negate(src0)))
899a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return FALSE;
900a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
901a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   /* ADD DST, SRC, TMP */
902a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), dst, src0, src(temp)))
903a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return FALSE;
904a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
905a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   return TRUE;
906a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul}
907a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
908a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
9093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DIV instruction.
9103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DIV  DST.xy, SRC0, SRC1
9113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RCP  TMP.x, SRC1.xxxx
9133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RCP  TMP.y, SRC1.yyyy
9143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  DST.xy, SRC0, TMP
9153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_div(struct svga_shader_emitter *emit,
9173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9217d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
9237d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
9253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
9263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* For each enabled element, perform a RCP instruction.  Note that
9283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * RCP is scalar in SVGA3D:
9293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
9303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < 4; i++) {
9313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned channel = 1 << i;
9323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & channel) {
9333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* RCP  TMP.?, SRC1.???? */
9343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
9353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(temp, channel),
9363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar(src1, i) ))
9373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
9383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
9393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
9403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Then multiply them out with a single mul:
9423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    *
9433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * MUL  DST, SRC0, TMP
9443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
9453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst, src0,
9463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( temp ) ))
9473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
9503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
9513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DP2 instruction.
9533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP2  DST, SRC1, SRC2
9543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  TMP, SRC1, SRC2
9563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    ADD  DST, TMP.xxxx, TMP.yyyy
9573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dp2(struct svga_shader_emitter *emit,
9593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9637d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
9657d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
9673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register temp_src0, temp_src1;
9683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MUL  TMP, SRC1, SRC2 */
9703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), temp, src0, src1 ))
9713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp_src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
9743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp_src1 = scalar(src( temp ), TGSI_SWIZZLE_Y);
9753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* ADD  DST, TMP.xxxx, TMP.yyyy */
9773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
9783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    temp_src0, temp_src1 ))
9793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
9823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
9833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DPH instruction.
9863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DPH  DST, SRC1, SRC2
9873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP3  TMP, SRC1, SRC2
9893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    ADD  DST, TMP, SRC2.wwww
9903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dph(struct svga_shader_emitter *emit,
9923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9967d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
9987d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* DP3  TMP, SRC1, SRC2 */
10023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src1 ))
10033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = scalar(src1, TGSI_SWIZZLE_W);
10063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* ADD  DST, TMP, SRC2.wwww */
10083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
10093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( temp ), src1 ))
10103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DST instruction.
10163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    NRM  DST, SRC
10173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
10183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP3  TMP, SRC, SRC
10193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RSQ  TMP, TMP
10203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  DST, SRC, TMP
10213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
10223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_nrm(struct svga_shader_emitter *emit,
10233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
10243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
10277d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* DP3  TMP, SRC, SRC */
10313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src0 ))
10323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* RSQ  TMP, TMP */
10353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_RSQ ), temp, src( temp )))
10363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MUL  DST, SRC, TMP */
10393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst,
10403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src( temp )))
10413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean do_emit_sincos(struct svga_shader_emitter *emit,
10483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              SVGA3dShaderDestToken dst,
10493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              struct src_register src0)
10503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src0, TGSI_SWIZZLE_X);
10523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
105394b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul   return submit_op1( emit, inst_token( SVGA3DOP_SINCOS ),
105494b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul                      dst, src0 );
10553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sincos(struct svga_shader_emitter *emit,
10583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn)
10593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
10627d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
10663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_XY), src0 ))
10673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP */
10703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src( temp ) ))
10713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
10773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SCS TMP SRC
10783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV DST TMP.yyyy
10793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
10803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sin(struct svga_shader_emitter *emit,
10813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
10823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
10857d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
10893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_Y), src0))
10903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src( temp ), TGSI_SWIZZLE_Y);
10933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP.yyyy */
10953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
10963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
11003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
11023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SCS TMP SRC
11033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV DST TMP.xxxx
11043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
11053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_cos(struct svga_shader_emitter *emit,
11063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
11073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
11083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
11093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
11107d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
11113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
11123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
11143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos( emit, writemask(temp, TGSI_WRITEMASK_X), src0 ))
11153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
11183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP.xxxx */
11203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
11213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
11243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
11253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11265a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzerstatic boolean emit_ssg(struct svga_shader_emitter *emit,
11275a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                        const struct tgsi_full_instruction *insn )
11285a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer{
11295a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
11305a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   struct src_register src0 = translate_src_register(
11315a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      emit, &insn->Src[0] );
11325a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken temp0 = get_temp( emit );
11335a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken temp1 = get_temp( emit );
11345a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   struct src_register zero, one;
11355a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11365a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (emit->unit == PIPE_SHADER_VERTEX) {
11375a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      /* SGN  DST, SRC0, TMP0, TMP1 */
11385a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return submit_op3( emit, inst_token( SVGA3DOP_SGN ), dst, src0,
11395a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                         src( temp0 ), src( temp1 ) );
11405a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   }
11415a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11425a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   zero = get_zero_immediate( emit );
11435a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   one = scalar( zero, TGSI_SWIZZLE_W );
11445a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   zero = scalar( zero, TGSI_SWIZZLE_X );
11455a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11465a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* CMP  TMP0, SRC0, one, zero */
11475a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
11485a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    writemask( temp0, dst.mask ), src0, one, zero ))
11495a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return FALSE;
11505a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11515a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* CMP  TMP1, negate(SRC0), negate(one), zero */
11525a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
11535a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    writemask( temp1, dst.mask ), negate( src0 ), negate( one ),
11545a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    zero ))
11555a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return FALSE;
11565a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11575a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* ADD  DST, TMP0, TMP1 */
11585a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   return submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src( temp0 ),
11595a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                      src( temp1 ) );
11605a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer}
11613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
11633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ADD DST SRC0, negate(SRC0)
11643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
11653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sub(struct svga_shader_emitter *emit,
11663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
11673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
11683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
11693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
11707d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
11713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
11727d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
11733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = negate(src1);
11753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
11773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src1 ))
11783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
11813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
11823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_kil(struct svga_shader_emitter *emit,
11853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
11863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
11877d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &insn->Src[0];
11882b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   struct src_register src0, srcIn;
11892b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   /* is the W component tested in another position? */
11902b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   const boolean w_tested = (reg->Register.SwizzleW == reg->Register.SwizzleX ||
11912b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                             reg->Register.SwizzleW == reg->Register.SwizzleY ||
11922b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                             reg->Register.SwizzleW == reg->Register.SwizzleZ);
11932b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   const boolean special = (reg->Register.Absolute ||
11942b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.Negate ||
11952b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.Indirect ||
11962b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleX != 0 ||
11972b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleY != 1 ||
11982b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleZ != 2 ||
11992b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.File != TGSI_FILE_TEMPORARY);
12002b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   SVGA3dShaderDestToken temp;
12012b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12022b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   src0 = srcIn = translate_src_register( emit, reg );
12032b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12042b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (special || !w_tested) {
12052b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* need a temp reg */
12062b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      temp = get_temp( emit );
12072b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   }
12082b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12092b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (special) {
12102b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* move the source into a temp register */
12112b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      submit_op1( emit, inst_token( SVGA3DOP_MOV ),
12122b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                  writemask( temp, TGSI_WRITEMASK_XYZ ),
12132b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                  src0 );
12143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      src0 = src( temp );
12163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
12173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12182b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   /* do the texkill (on the xyz components) */
12192b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), dst(src0) ))
12202b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      return FALSE;
12212b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12222b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (!w_tested) {
12232b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* need to emit a second texkill to test the W component */
12242b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* put src.wwww into temp register */
12252b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      if (!submit_op1(emit,
12262b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      inst_token( SVGA3DOP_MOV ),
12272b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      writemask( temp, TGSI_WRITEMASK_XYZ ),
12282b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      scalar(srcIn, TGSI_SWIZZLE_W)))
12292b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul         return FALSE;
12302b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12312b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* second texkill */
12322b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), temp ))
12332b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul         return FALSE;
12342b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   }
12352b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12362b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   return TRUE;
12373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
12383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* mesa state tracker always emits kilp as an unconditional
12413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * kil */
12423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_kilp(struct svga_shader_emitter *emit,
12433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
12443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
12453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
12463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
1247fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell   struct src_register one = scalar( get_zero_immediate( emit ),
1248fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                                     TGSI_SWIZZLE_W );
12493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( SVGA3DOP_TEXKILL );
12513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* texkill doesn't allow negation on the operand so lets move
12533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * negation of {1} to a temp register */
12543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp = get_temp( emit );
12553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp,
12563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    negate( one ) ))
12573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
12583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op0( emit, inst, temp );
12603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
12613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12620bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12630bd3a75de9002e73214cde883691da558db7bc70Brian Paul/**
12640bd3a75de9002e73214cde883691da558db7bc70Brian Paul * Test if r1 and r2 are the same register.
12650bd3a75de9002e73214cde883691da558db7bc70Brian Paul */
12660bd3a75de9002e73214cde883691da558db7bc70Brian Paulstatic boolean
12670bd3a75de9002e73214cde883691da558db7bc70Brian Paulsame_register(struct src_register r1, struct src_register r2)
12680bd3a75de9002e73214cde883691da558db7bc70Brian Paul{
12690bd3a75de9002e73214cde883691da558db7bc70Brian Paul   return (r1.base.num == r2.base.num &&
12700bd3a75de9002e73214cde883691da558db7bc70Brian Paul           r1.base.type_upper == r2.base.type_upper &&
12710bd3a75de9002e73214cde883691da558db7bc70Brian Paul           r1.base.type_lower == r2.base.type_lower);
12720bd3a75de9002e73214cde883691da558db7bc70Brian Paul}
12730bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12740bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12750bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Implement conditionals by initializing destination reg to 'fail',
12773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * then set predicate reg with UFOP_SETP, then move 'pass' to dest
12783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * based on predicate reg.
12793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
12803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SETP src0, cmp, src1  -- do this first to avoid aliasing problems.
12813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV dst, fail
12823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV dst, pass, p0
12833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
12843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
12853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzemit_conditional(struct svga_shader_emitter *emit,
12863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 unsigned compare_func,
12873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 SVGA3dShaderDestToken dst,
12883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register src0,
12893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register src1,
12903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register pass,
12913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register fail)
12923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
12933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
12943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken setp_token, mov_token;
12953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   setp_token = inst_token( SVGA3DOP_SETP );
12963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (compare_func) {
12983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_NEVER:
12993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
13003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst, fail );
13013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_LESS:
13033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_LT;
13043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_EQUAL:
13063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_EQ;
13073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_LEQUAL:
13093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_LE;
13103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_GREATER:
13123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_GT;
13133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_NOTEQUAL:
13153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMPC_NE;
13163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_GEQUAL:
13183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_GE;
13193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_ALWAYS:
13213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
13223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst, pass );
13233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
13250bd3a75de9002e73214cde883691da558db7bc70Brian Paul
13260bd3a75de9002e73214cde883691da558db7bc70Brian Paul   if (same_register(src(dst), pass)) {
13270bd3a75de9002e73214cde883691da558db7bc70Brian Paul      /* We'll get bad results if the dst and pass registers are the same
13280bd3a75de9002e73214cde883691da558db7bc70Brian Paul       * so use a temp register containing pass.
13290bd3a75de9002e73214cde883691da558db7bc70Brian Paul       */
13300bd3a75de9002e73214cde883691da558db7bc70Brian Paul      SVGA3dShaderDestToken temp = get_temp(emit);
13310bd3a75de9002e73214cde883691da558db7bc70Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass))
13320bd3a75de9002e73214cde883691da558db7bc70Brian Paul         return FALSE;
13330bd3a75de9002e73214cde883691da558db7bc70Brian Paul      pass = src(temp);
13340bd3a75de9002e73214cde883691da558db7bc70Brian Paul   }
13353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SETP src0, COMPOP, src1 */
13373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, setp_token, pred_reg,
13383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src1 ))
13393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   mov_token = inst_token( SVGA3DOP_MOV );
13423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV dst, fail */
13443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, mov_token, dst,
13453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    fail ))
13463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV dst, pass (predicated)
13493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    *
13503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * Note that the predicate reg (and possible modifiers) is passed
13513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * as the first source argument.
13523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   mov_token.predicated = 1;
13543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, mov_token, dst,
13553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( pred_reg ), pass ))
13563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
13593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
13603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
13633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzemit_select(struct svga_shader_emitter *emit,
13643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            unsigned compare_func,
13653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            SVGA3dShaderDestToken dst,
13663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            struct src_register src0,
13673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            struct src_register src1 )
13683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
13693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* There are some SVGA instructions which implement some selects
13703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * directly, but they are only available in the vertex shader.
13713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
13733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (compare_func) {
13743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_GEQUAL:
13753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src0, src1 );
13763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_LEQUAL:
13773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src1, src0 );
13783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_GREATER:
13793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src1, src0 );
13803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_LESS:
13813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src0, src1 );
13823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
13833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
13843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
13853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
13863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Otherwise, need to use the setp approach:
13893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   {
13913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register one, zero;
13923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* zero immediate is 0,0,0,1 */
13933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      zero = get_zero_immediate( emit );
13943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      one  = scalar( zero, TGSI_SWIZZLE_W );
13953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      zero = scalar( zero, TGSI_SWIZZLE_X );
13963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_conditional(
13983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit,
13993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         compare_func,
14003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         dst,
14013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src0,
14023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src1,
14033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         one, zero);
14043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
14053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
14063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_select_op(struct svga_shader_emitter *emit,
14093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              unsigned compare,
14103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn)
14113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
14123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
14133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
14147d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
14153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
14167d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
14173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_select( emit, compare, dst, src0, src1 );
14193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
14203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1422d594f72e1615cda47b838046df4590316da3d1a9Brian Paul/**
1423d594f72e1615cda47b838046df4590316da3d1a9Brian Paul * Translate TGSI CMP instruction.
1424d594f72e1615cda47b838046df4590316da3d1a9Brian Paul */
1425d594f72e1615cda47b838046df4590316da3d1a9Brian Paulstatic boolean
1426d594f72e1615cda47b838046df4590316da3d1a9Brian Paulemit_cmp(struct svga_shader_emitter *emit,
1427d594f72e1615cda47b838046df4590316da3d1a9Brian Paul         const struct tgsi_full_instruction *insn)
1428d594f72e1615cda47b838046df4590316da3d1a9Brian Paul{
1429d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1430d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src0 =
1431d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[0] );
1432d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src1 =
1433d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[1] );
1434d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src2 =
1435d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[2] );
1436d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1437d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
1438d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      struct src_register zero =
1439d594f72e1615cda47b838046df4590316da3d1a9Brian Paul         scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X);
1440d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      /* We used to simulate CMP with SLT+LRP.  But that didn't work when
1441d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * src1 or src2 was Inf/NaN.  In particular, GLSL sqrt(0) failed
1442d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * because it involves a CMP to handle the 0 case.
1443d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * Use a conditional expression instead.
1444d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       */
1445d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      return emit_conditional(emit, PIPE_FUNC_LESS, dst,
1446d594f72e1615cda47b838046df4590316da3d1a9Brian Paul                              src0, zero, src1, src2);
1447d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   }
1448d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   else {
1449d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      assert(emit->unit == PIPE_SHADER_FRAGMENT);
1450d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1451d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      /* CMP  DST, SRC0, SRC2, SRC1 */
1452d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst,
1453d594f72e1615cda47b838046df4590316da3d1a9Brian Paul                         src0, src2, src1);
1454d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   }
1455d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1456d594f72e1615cda47b838046df4590316da3d1a9Brian Paul}
1457d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1458d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
14593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate texture instructions to SVGA3D representation.
14603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
14613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_tex2(struct svga_shader_emitter *emit,
14623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn,
14633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         SVGA3dShaderDestToken dst )
14643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
14653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
1466a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   struct src_register texcoord;
1467a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   struct src_register sampler;
1468a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   SVGA3dShaderDestToken tmp;
1469a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
14703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst.value = 0;
14713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
14733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
147484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
14763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
147784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      inst.control = SVGA3DOPCONT_PROJECT;
14793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
14803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
148184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      inst.control = SVGA3DOPCONT_BIAS;
14833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
148484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   case TGSI_OPCODE_TXL:
148584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEXLDL;
148684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      break;
14873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
14883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
14893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
14903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
14913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1492a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   texcoord = translate_src_register( emit, &insn->Src[0] );
1493a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   sampler = translate_src_register( emit, &insn->Src[1] );
14943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1495a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
1496a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell       emit->dynamic_branching_level > 0)
1497a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      tmp = get_temp( emit );
1498a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1499a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   /* Can't do mipmapping inside dynamic branch constructs.  Force LOD
1500a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    * zero in that case.
1501a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    */
15020748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   if (emit->dynamic_branching_level > 0 &&
150384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       inst.op == SVGA3DOP_TEX &&
15040748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
1505a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      struct src_register zero = get_zero_immediate( emit );
1506a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1507a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      /* MOV  tmp, texcoord */
1508a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      if (!submit_op1( emit,
1509a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       inst_token( SVGA3DOP_MOV ),
1510a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       tmp,
1511a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       texcoord ))
1512a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell         return FALSE;
1513a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1514a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      /* MOV  tmp.w, zero */
1515a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      if (!submit_op1( emit,
1516a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       inst_token( SVGA3DOP_MOV ),
1517a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       writemask( tmp, TGSI_WRITEMASK_W ),
1518a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       scalar( zero, TGSI_SWIZZLE_X )))
1519a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell         return FALSE;
1520a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1521a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      texcoord = src( tmp );
1522a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      inst.op = SVGA3DOP_TEXLDL;
1523a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   }
1524a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1525a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   /* Explicit normalization of texcoords:
1526a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    */
1527a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
1528a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
15293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* MUL  tmp, SRC0, WH */
15313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
1532a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       tmp, texcoord, wh ))
15333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
1534a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1535a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      texcoord = src( tmp );
15363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
15373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1538a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   return submit_op2( emit, inst, dst, texcoord, sampler );
15393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
15403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate texture instructions to SVGA3D representation.
15453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
154684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwellstatic boolean emit_tex4(struct svga_shader_emitter *emit,
15473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn,
15483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         SVGA3dShaderDestToken dst )
15493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
15503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
155184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register texcoord;
155284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register ddx;
155384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register ddy;
155484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register sampler;
155584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
155684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   texcoord = translate_src_register( emit, &insn->Src[0] );
155784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   ddx      = translate_src_register( emit, &insn->Src[1] );
155884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   ddy      = translate_src_register( emit, &insn->Src[2] );
155984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   sampler  = translate_src_register( emit, &insn->Src[3] );
15603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst.value = 0;
15623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
15643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXD:
1565a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
15663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
156784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   default:
156884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      assert(0);
156984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      return FALSE;
15703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
15713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
157284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
15733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
15743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15769bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul/**
15779bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul * Emit texture swizzle code.
15789bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul */
15799bd15aef865352b9234fedae76617fc51c71e6d5Brian Paulstatic boolean emit_tex_swizzle( struct svga_shader_emitter *emit,
15809bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 SVGA3dShaderDestToken dst,
15819bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 struct src_register src,
15829bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_x,
15839bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_y,
15849bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_z,
15859bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_w)
15869bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul{
15879bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   const unsigned swizzleIn[4] = {swizzle_x, swizzle_y, swizzle_z, swizzle_w};
15889bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   unsigned srcSwizzle[4];
15899bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   unsigned srcWritemask = 0x0, zeroWritemask = 0x0, oneWritemask = 0x0;
15909bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   int i;
15919bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
15929bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* build writemasks and srcSwizzle terms */
15939bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   for (i = 0; i < 4; i++) {
15949bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      if (swizzleIn[i] == PIPE_SWIZZLE_ZERO) {
15959bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
15969bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         zeroWritemask |= (1 << i);
15979bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
15989bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else if (swizzleIn[i] == PIPE_SWIZZLE_ONE) {
15999bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
16009bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         oneWritemask |= (1 << i);
16019bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
16029bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else {
16039bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = swizzleIn[i];
16049bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcWritemask |= (1 << i);
16059bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
16069bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16079bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16089bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write x/y/z/w comps */
16099bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & srcWritemask) {
16109bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      if (!submit_op1(emit,
16119bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      inst_token(SVGA3DOP_MOV),
16129bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      writemask(dst, srcWritemask),
16139bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      swizzle(src,
16149bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[0],
16159bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[1],
16169bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[2],
16179bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[3])))
16189bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16199bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16209bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16219bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write 0 comps */
16229bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & zeroWritemask) {
16239bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      if (!submit_op1(emit,
16249bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      inst_token(SVGA3DOP_MOV),
16259bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      writemask(dst, zeroWritemask),
16269bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X)))
16279bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16289bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16299bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16309bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write 1 comps */
16319bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & oneWritemask) {
16329bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      if (!submit_op1(emit,
16339bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      inst_token(SVGA3DOP_MOV),
16349bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      writemask(dst, oneWritemask),
16359bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_W)))
16369bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16379bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16389bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16399bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   return TRUE;
16409bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul}
16419bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16429bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_tex(struct svga_shader_emitter *emit,
16443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
16453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
16463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst =
16473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      translate_dst_register( emit, insn, 0 );
16483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
16497d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
16503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 =
16517d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[1] );
16523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken tex_result;
16549bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   const unsigned unit = src1.base.num;
16553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* check for shadow samplers */
16579bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   boolean compare = (emit->key.fkey.tex[unit].compare_mode ==
16583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      PIPE_TEX_COMPARE_R_TO_TEXTURE);
16593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16609bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* texture swizzle */
16619bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   boolean swizzle = (emit->key.fkey.tex[unit].swizzle_r != PIPE_SWIZZLE_RED ||
16629bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_g != PIPE_SWIZZLE_GREEN ||
16639bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_b != PIPE_SWIZZLE_BLUE ||
16649bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_a != PIPE_SWIZZLE_ALPHA);
16653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16668009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   boolean saturate = insn->Instruction.Saturate != TGSI_SAT_NONE;
16678009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul
16688009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   /* If doing compare processing or tex swizzle or saturation, we need to put
16698009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul    * the fetched color into a temporary so it can be used as a source later on.
16703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
16718009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   if (compare || swizzle || saturate) {
16723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tex_result = get_temp( emit );
16733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
16753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tex_result = dst;
16763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch(insn->Instruction.Opcode) {
16793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
16803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
16813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
168284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   case TGSI_OPCODE_TXL:
16833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_tex2( emit, insn, tex_result ))
16843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
16853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
16863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXD:
168784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      if (!emit_tex4( emit, insn, tex_result ))
16883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
16893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
16903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
16913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
16923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (compare) {
16969bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      SVGA3dShaderDestToken dst2;
16979bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16988009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      if (swizzle || saturate)
16999bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         dst2 = tex_result;
17009bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else
17019bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         dst2 = dst;
17029bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
17037384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      if (dst.mask & TGSI_WRITEMASK_XYZ) {
17047384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
17059bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         /* When sampling a depth texture, the result of the comparison is in
17069bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul          * the Y component.
17079bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul          */
17087384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
17097d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         struct src_register r_coord;
17107d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
17117d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         if (insn->Instruction.Opcode == TGSI_OPCODE_TXP) {
17127d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            /* Divide texcoord R by Q */
17137d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
17147d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
17157d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src0, TGSI_SWIZZLE_W) ))
17167d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul               return FALSE;
17177d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
17187d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
17197d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
17207d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src0, TGSI_SWIZZLE_Z),
17217d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
17227d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul               return FALSE;
17237d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
17247d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            r_coord = scalar(src(src0_zdivw), TGSI_SWIZZLE_X);
17257d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         }
17267d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         else {
17277d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            r_coord = scalar(src0, TGSI_SWIZZLE_Z);
17287d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         }
17297384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17307d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         /* Compare texture sample value against R component of texcoord */
17317d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         if (!emit_select(emit,
17327d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          emit->key.fkey.tex[unit].compare_func,
17337d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          writemask( dst2, TGSI_WRITEMASK_XYZ ),
17347d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          r_coord,
17357d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          tex_src_x))
17367384cdf651dc69098f4d988dd3b217879ec63336José Fonseca            return FALSE;
17377384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      }
17383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17397384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      if (dst.mask & TGSI_WRITEMASK_W) {
17407384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         struct src_register one =
17417384cdf651dc69098f4d988dd3b217879ec63336José Fonseca            scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
17427384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17437384cdf651dc69098f4d988dd3b217879ec63336José Fonseca        if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
17449bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                         writemask( dst2, TGSI_WRITEMASK_W ),
17457384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                         one ))
17467384cdf651dc69098f4d988dd3b217879ec63336José Fonseca           return FALSE;
17477384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      }
17489bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
17497384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17508009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   if (saturate && !swizzle) {
17518009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      /* MOV_SAT real_dst, dst */
17528009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src(tex_result) ))
17538009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul         return FALSE;
17548009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   }
17558009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   else if (swizzle) {
17568009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      /* swizzle from tex_result to dst (handles saturation too, if any) */
17579bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      emit_tex_swizzle(emit,
17589bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       dst, src(tex_result),
17599bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_r,
17609bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_g,
17619bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_b,
17629bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_a);
17633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
17649bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
17653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
17663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_bgnloop2( struct svga_shader_emitter *emit,
17693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn )
17703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_LOOP );
17723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
17733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register const_int = get_loop_const( emit );
17743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1775a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level++;
1776a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
17773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, inst ) &&
17783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, loop_reg ) &&
17793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, const_int ) );
17803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_endloop2( struct svga_shader_emitter *emit,
17833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn )
17843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
1786a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1787a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level--;
1788a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
17893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_instruction( emit, inst );
17903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_brk( struct svga_shader_emitter *emit,
17933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn )
17943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_BREAK );
17963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_instruction( emit, inst );
17973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_scalar_op1( struct svga_shader_emitter *emit,
18003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                unsigned opcode,
18013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                const struct tgsi_full_instruction *insn )
18023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
18033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
18043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
18053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src;
18063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( opcode );
18083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
18097d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   src = translate_src_register( emit, &insn->Src[0] );
18103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src = scalar( src, TGSI_SWIZZLE_X );
18113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst, dst, src );
18133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
18143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_simple_instruction(struct svga_shader_emitter *emit,
18173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       unsigned opcode,
18183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       const struct tgsi_full_instruction *insn )
18193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
18207d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *src = insn->Src;
18213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
18223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
18233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( opcode );
18253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
18263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.NumSrcRegs) {
18283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 0:
18293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op0( emit, inst, dst );
18303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 1:
18313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst, dst,
18323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ));
18333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 2:
18343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op2( emit, inst, dst,
18353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ),
18363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[1] ) );
18373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 3:
18383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op3( emit, inst, dst,
18393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ),
18403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[1] ),
18413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[2] ) );
18423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
18433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
18443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
18453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
18463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
18473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18480748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18490748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwellstatic boolean emit_deriv(struct svga_shader_emitter *emit,
18500748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                          const struct tgsi_full_instruction *insn )
18510748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell{
18520748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   if (emit->dynamic_branching_level > 0 &&
18530748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       insn->Src[0].Register.File == TGSI_FILE_TEMPORARY)
18540748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   {
18550748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      struct src_register zero = get_zero_immediate( emit );
18560748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      SVGA3dShaderDestToken dst =
18570748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         translate_dst_register( emit, insn, 0 );
18580748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18590748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      /* Deriv opcodes not valid inside dynamic branching, workaround
18600748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       * by zeroing out the destination.
18610748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       */
18620748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      if (!submit_op1(emit,
18630748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                      inst_token( SVGA3DOP_MOV ),
18640748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                      dst,
18650748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                      scalar(zero, TGSI_SWIZZLE_X)))
18660748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         return FALSE;
18670748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18680748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      return TRUE;
18690748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   }
18700748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   else {
18710748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      unsigned opcode;
1872f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      const struct tgsi_full_src_register *reg = &insn->Src[0];
1873f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      SVGA3dShaderInstToken inst;
1874f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      SVGA3dShaderDestToken dst;
1875f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      struct src_register src0;
18760748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18770748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      switch (insn->Instruction.Opcode) {
18780748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      case TGSI_OPCODE_DDX:
18790748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         opcode = SVGA3DOP_DSX;
18800748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         break;
18810748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      case TGSI_OPCODE_DDY:
18820748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         opcode = SVGA3DOP_DSY;
18830748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         break;
18840748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      default:
18850748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         return FALSE;
18860748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      }
18870748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
1888f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      inst = inst_token( opcode );
1889f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      dst = translate_dst_register( emit, insn, 0 );
1890f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      src0 = translate_src_register( emit, reg );
1891f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1892f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      /* We cannot use negate or abs on source to dsx/dsy instruction.
1893f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca       */
1894f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      if (reg->Register.Absolute ||
1895f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca          reg->Register.Negate) {
1896f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca         SVGA3dShaderDestToken temp = get_temp( emit );
1897f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1898f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca         if (!emit_repl( emit, temp, &src0 ))
1899f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca            return FALSE;
1900f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      }
1901f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1902f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      return submit_op1( emit, inst, dst, src0 );
19030748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   }
19040748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell}
19050748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
19063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_arl(struct svga_shader_emitter *emit,
19073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
19083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
19093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ++emit->current_arl;
19100742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   if (emit->unit == PIPE_SHADER_FRAGMENT) {
19110742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      /* MOVA not present in pixel shader instruction set.
19120742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * Ignore this instruction altogether since it is
19130742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * only used for loop counters -- and for that
19140742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * we reference aL directly.
19150742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       */
19160742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      return TRUE;
19170742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   }
19183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga_arl_needs_adjustment( emit )) {
19193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_fake_arl( emit, insn );
19203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } else {
19213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* no need to adjust, just emit straight arl */
19223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_MOVA, insn);
19233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
19253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_pow(struct svga_shader_emitter *emit,
19273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
19283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
19293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
19303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
19317d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
19323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
19337d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
19343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_tmp = FALSE;
19353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* POW can only output to a temporary */
19375b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
19383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_tmp = TRUE;
19393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* POW src1 must not be the same register as dst */
19413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (alias_src_dst( src1, dst ))
19423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_tmp = TRUE;
19433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* it's a scalar op */
19453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar( src0, TGSI_SWIZZLE_X );
19463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = scalar( src1, TGSI_SWIZZLE_X );
19473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_tmp) {
19493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = writemask(get_temp( emit ), TGSI_WRITEMASK_X );
19503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_POW ), tmp, src0, src1))
19523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, scalar(src(tmp), 0) );
19553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
19573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op2(emit, inst_token( SVGA3DOP_POW ), dst, src0, src1);
19583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
19603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_xpd(struct svga_shader_emitter *emit,
19623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
19633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
19643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
19653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
19667d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
19673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
19687d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
19693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_dst_tmp = FALSE;
19703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* XPD can only output to a temporary */
19723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP)
19733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_dst_tmp = TRUE;
19743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* The dst reg must not be the same as src0 or src1*/
19763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (alias_src_dst(src0, dst) ||
19773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       alias_src_dst(src1, dst))
19783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_dst_tmp = TRUE;
19793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_dst_tmp) {
19813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
19823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Obey DX9 restrictions on mask:
19843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
19853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tmp.mask = dst.mask & TGSI_WRITEMASK_XYZ;
19863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), tmp, src0, src1))
19883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
19913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
19943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), dst, src0, src1))
19953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to emit 1.0 to dst.w?
19993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
20003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
20013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
20023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1(emit,
20043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      inst_token( SVGA3DOP_MOV ),
20053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      writemask(dst, TGSI_WRITEMASK_W),
20063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      zero))
20073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
20083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
20093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
20113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
20123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_lrp(struct svga_shader_emitter *emit,
20153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
20163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
20173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
20183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
20197d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
20203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
20217d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
20223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src2 = translate_src_register(
20237d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[2] );
20243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
202515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return submit_lrp(emit, dst, src0, src1, src2);
20263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
20273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dst_insn(struct svga_shader_emitter *emit,
20303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn )
20313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
20323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
20333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* SVGA/DX9 has a DST instruction, but only for vertex shaders:
20343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_DST, insn);
20363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
20373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
20383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* result[0] = 1    * 1;
20403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[1] = a[1] * b[1];
20413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[2] = a[2] * 1;
20423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[3] = 1    * b[3];
20433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
20463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp;
20473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src0 = translate_src_register(
20487d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[0] );
20493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src1 = translate_src_register(
20507d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[1] );
20513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
20523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      boolean need_tmp = FALSE;
20533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
20553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          alias_src_dst(src0, dst) ||
20563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          alias_src_dst(src1, dst))
20573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_tmp = TRUE;
20583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (need_tmp) {
20603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         tmp = get_temp( emit );
20613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
20633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         tmp = dst;
20643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.xw = 1.0
20673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_XW) {
20693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_XW ),
20713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar( zero, 3 )))
20723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.yz = src0
20763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_YZ) {
20783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_YZ ),
20803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src0))
20813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.yw = tmp * src1
20853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_YW) {
20873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
20883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_YW ),
20893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src(tmp),
20903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src1))
20913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* dst = tmp
20953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (need_tmp) {
20973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          dst,
20993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src(tmp)))
21003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
21013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
21023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
21053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
21063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_exp(struct svga_shader_emitter *emit,
21093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
21103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
21113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
21123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
21137d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
21143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
21153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken fraction;
21163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Y)
21183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fraction = dst;
21193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else if (dst.mask & TGSI_WRITEMASK_X)
21203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fraction = get_temp( emit );
21213f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   else
21223f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee      fraction.value = 0;
21233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If y is being written, fill it with src0 - floor(src0).
21253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XY) {
21273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
21283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( fraction, TGSI_WRITEMASK_Y ),
21293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0 ))
21303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If x is being written, fill it with 2 ^ floor(src0).
21343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_X) {
21363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
21377384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_X ),
21383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0,
21393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
21403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
21437384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_X ),
21443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
21453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_Y))
21483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, fraction );
21493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If z is being written, fill it with 2 ^ src0 (partial precision).
21523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Z) {
21543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
21557384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_Z ),
21563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0 ) )
21573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If w is being written, fill it with one.
21613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
21633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
21643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(dst, TGSI_WRITEMASK_W),
21653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( zero, TGSI_SWIZZLE_W ) ))
21663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
21703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
21713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_lit(struct svga_shader_emitter *emit,
21733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn )
21743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
21753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
21763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* SVGA/DX9 has a LIT instruction, but only for vertex shaders:
21773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
21783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_LIT, insn);
21793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
21813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* D3D vs. GL semantics can be fairly easily accomodated by
21833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * variations on this sequence.
21843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * GL:
21863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.y = src.x
21873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.z = pow(src.y,src.w)
21883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   p0 = src0.xxxx > 0
21893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   result = zero.wxxw
21903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   (p0) result.yz = tmp
21913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * D3D:
21933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.y = src.x
21943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.z = pow(src.y,src.w)
21953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   p0 = src0.xxyy > 0
21963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   result = zero.wxxw
21973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   (p0) result.yz = tmp
21983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Will implement the GL version for now.
22003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
22033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
22043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src0 = translate_src_register(
22057d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[0] );
22063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
22073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp = pow(src.y, src.w)
22093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Z) {
22113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2(emit, inst_token( SVGA3DOP_POW ),
22123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         tmp,
22133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         scalar(src0, 1),
22143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         scalar(src0, 3)))
22153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
22163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
22173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.y = src.x
22193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Y) {
22213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
22223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_Y ),
22233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar(src0, 0)))
22243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
22253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
22263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Can't quite do this with emit conditional due to the extra
22283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * writemask on the predicated mov:
22293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      {
22313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
22323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         SVGA3dShaderInstToken setp_token, mov_token;
22333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         struct src_register predsrc;
22343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         setp_token = inst_token( SVGA3DOP_SETP );
22363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         mov_token = inst_token( SVGA3DOP_MOV );
22373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         setp_token.control = SVGA3DOPCOMP_GT;
22393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* D3D vs GL semantics:
22413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          */
22423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (0)
22433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            predsrc = swizzle(src0, 0, 0, 1, 1); /* D3D */
22443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         else
22453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            predsrc = swizzle(src0, 0, 0, 0, 0); /* GL */
22463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* SETP src0.xxyy, GT, {0}.x */
22483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2( emit, setp_token, pred_reg,
22493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          predsrc,
22503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          swizzle(zero, 0, 0, 0, 0) ))
22513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
22523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* MOV dst, fail */
22543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst,
22553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          swizzle(zero, 3, 0, 0, 3 )))
22563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz             return FALSE;
22573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* MOV dst.yz, tmp (predicated)
22593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          *
22603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          * Note that the predicate reg (and possible modifiers) is passed
22613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          * as the first source argument.
22623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          */
22633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (dst.mask & TGSI_WRITEMASK_YZ) {
22643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            mov_token.predicated = 1;
22653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            if (!submit_op2( emit, mov_token,
22663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             writemask(dst, TGSI_WRITEMASK_YZ),
22673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             src( pred_reg ), src( tmp ) ))
22683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               return FALSE;
22693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
22703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
22713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
22723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
22743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
22753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ex2( struct svga_shader_emitter *emit,
22803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn )
22813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
22823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
22833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
22843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0;
22853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( SVGA3DOP_EXP );
22873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
22887d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   src0 = translate_src_register( emit, &insn->Src[0] );
22893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar( src0, TGSI_SWIZZLE_X );
22903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask != TGSI_WRITEMASK_XYZW) {
22923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
22933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst, tmp, src0 ))
22953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
22963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
22983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst,
22993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         scalar( src( tmp ), TGSI_SWIZZLE_X ) );
23003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst, dst, src0 );
23033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
23043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_log(struct svga_shader_emitter *emit,
23073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
23083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
23093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
23103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
23117d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
23123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
23133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken abs_tmp;
23143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register abs_src0;
23153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken log2_abs;
23163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23173f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   abs_tmp.value = 0;
23183f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee
23193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Z)
23203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      log2_abs = dst;
23213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else if (dst.mask & TGSI_WRITEMASK_XY)
23223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      log2_abs = get_temp( emit );
23233f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   else
23243f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee      log2_abs.value = 0;
23253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If z is being written, fill it with log2( abs( src0 ) ).
23273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
23283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XYZ) {
23293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!src0.base.srcMod || src0.base.srcMod == SVGA3DSRCMOD_ABS)
23303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_src0 = src0;
23313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
23323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_tmp = get_temp( emit );
23333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
23353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          abs_tmp,
23363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src0 ) )
23373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_src0 = src( abs_tmp );
23403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
23413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      abs_src0 = absolute( scalar( abs_src0, TGSI_SWIZZLE_X ) );
23433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_LOG ),
23453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( log2_abs, TGSI_WRITEMASK_Z ),
23463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       abs_src0 ) )
23473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XY) {
23513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken floor_log2;
23523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_X)
23543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         floor_log2 = dst;
23553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
23563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         floor_log2 = get_temp( emit );
23573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* If x is being written, fill it with floor( log2( abs( src0 ) ) ).
23593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
23603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
23613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( floor_log2, TGSI_WRITEMASK_X ),
23623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ) ) )
23633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
23663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( floor_log2, TGSI_WRITEMASK_X ),
23673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ),
23683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       negate( src( floor_log2 ) ) ) )
23693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* If y is being written, fill it with
23723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * abs ( src0 ) / ( 2 ^ floor( log2( abs( src0 ) ) ) ).
23733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
23743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Y) {
23753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
23763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask( dst, TGSI_WRITEMASK_Y ),
23773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          negate( scalar( src( floor_log2 ),
23783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                          TGSI_SWIZZLE_X ) ) ) )
23793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
23823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask( dst, TGSI_WRITEMASK_Y ),
23833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src( dst ),
23843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          abs_src0 ) )
23853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
23873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_X))
23893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, floor_log2 );
23903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_Z))
23923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, log2_abs );
23933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XYZ && src0.base.srcMod &&
23963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.srcMod != SVGA3DSRCMOD_ABS)
23973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, abs_tmp );
23983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If w is being written, fill it with one.
24003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
24013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
24023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
24033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(dst, TGSI_WRITEMASK_W),
24043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( zero, TGSI_SWIZZLE_W ) ))
24053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
24063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
24073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
24093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
24103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
241230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul/**
24131ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul * Translate TGSI TRUNC or ROUND instruction.
241430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul * We need to truncate toward zero. Ex: trunc(-1.9) = -1
241530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul * Different approaches are needed for VS versus PS.
241630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul */
241730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paulstatic boolean
24181ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulemit_trunc_round(struct svga_shader_emitter *emit,
24191ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                 const struct tgsi_full_instruction *insn,
24201ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                 boolean round)
242130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul{
242230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
242330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   const struct src_register src0 =
242430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      translate_src_register(emit, &insn->Src[0] );
242530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   SVGA3dShaderDestToken t1 = get_temp(emit);
242630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24271ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   if (round) {
24281ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      SVGA3dShaderDestToken t0 = get_temp(emit);
24291ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      struct src_register half = get_half_immediate(emit);
243030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24311ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t0 = abs(src0) + 0.5 */
24321ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t0,
24331ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      absolute(src0), half))
24341ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24351ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24361ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = fract(t0) */
24371ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, src(t0)))
24381ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24391ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24401ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = t0 - t1 */
24411ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, src(t0),
24421ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      negate(src(t1))))
24431ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24441ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   }
24451ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   else {
24461ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* trunc */
24471ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24481ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = fract(abs(src0)) */
24491ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, absolute(src0)))
24501ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24511ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24521ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = abs(src0) - t1 */
24531ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, absolute(src0),
24541ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      negate(src(t1))))
24551ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24561ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   }
245730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
245830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   /*
245930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul    * Now we need to multiply t1 by the sign of the original value.
246030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   */
246130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
246230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* For VS: use SGN instruction */
24631ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* Need two extra/dummy registers: */
246430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      SVGA3dShaderDestToken t2 = get_temp(emit), t3 = get_temp(emit),
246530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         t4 = get_temp(emit);
246630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
246730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* t2 = sign(src0) */
246830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      if (!submit_op3(emit, inst_token(SVGA3DOP_SGN), t2, src0,
246930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul                      src(t3), src(t4)))
247030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         return FALSE;
247130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
247230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* dst = t1 * t2 */
247330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_MUL), dst, src(t1), src(t2)))
247430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         return FALSE;
247530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   }
247630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   else {
247730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* For FS: Use CMP instruction */
247830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      return submit_op3(emit, inst_token( SVGA3DOP_CMP ), dst,
247930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul                        src0, src(t1), negate(src(t1)));
248030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   }
248130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
248230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   return TRUE;
248330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul}
248430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
248530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_bgnsub( struct svga_shader_emitter *emit,
24873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           unsigned position,
24883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn )
24893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
24903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
24913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Note that we've finished the main function and are now emitting
24933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * subroutines.  This affects how we terminate the generated
24943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * shader.
24953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
24963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->in_main_func = FALSE;
24973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->nr_labels; i++) {
24993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->label[i] == position) {
25003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return (emit_instruction( emit, inst_token( SVGA3DOP_RET ) ) &&
25013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 emit_instruction( emit, inst_token( SVGA3DOP_LABEL ) ) &&
25023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
25033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
25043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(0);
25073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
25083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
25093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_call( struct svga_shader_emitter *emit,
25113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn )
25123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
25137d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   unsigned position = insn->Label.Label;
25143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
25153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->nr_labels; i++) {
25173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->label[i] == position)
25183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
25193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->nr_labels == Elements(emit->label))
25223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
25233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (i == emit->nr_labels) {
25253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->label[i] = position;
25263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->nr_labels++;
25273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, inst_token( SVGA3DOP_CALL ) ) &&
25303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
25313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
25323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_end( struct svga_shader_emitter *emit )
25353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
25363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
25373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_vs_postamble( emit );
25383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
25403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_ps_postamble( emit );
25413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
25433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_emit_instruction( struct svga_shader_emitter *emit,
25473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      unsigned position,
25483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      const struct tgsi_full_instruction *insn )
25493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
25503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
25513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ARL:
25533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_arl( emit, insn );
25543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
25563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
25573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
25583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXL:
25593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXD:
25603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_tex( emit, insn );
25613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25620748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   case TGSI_OPCODE_DDX:
25630748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   case TGSI_OPCODE_DDY:
25640748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      return emit_deriv( emit, insn );
25650748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
25663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BGNSUB:
25673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_bgnsub( emit, position, insn );
25683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDSUB:
25703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
25713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CAL:
25733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_call( emit, insn );
25743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_FLR:
25763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_floor( emit, insn );
25773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
257830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   case TGSI_OPCODE_TRUNC:
25791ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      return emit_trunc_round( emit, insn, FALSE );
25801ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
25811ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   case TGSI_OPCODE_ROUND:
25821ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      return emit_trunc_round( emit, insn, TRUE );
258330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
2584a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   case TGSI_OPCODE_CEIL:
2585a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return emit_ceil( emit, insn );
2586a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
25873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CMP:
25883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_cmp( emit, insn );
25893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DIV:
25913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_div( emit, insn );
25923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP2:
25943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dp2( emit, insn );
25953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DPH:
25973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dph( emit, insn );
25983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NRM:
26003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_nrm( emit, insn );
26013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_COS:
26033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_cos( emit, insn );
26043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SIN:
26063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sin( emit, insn );
26073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SCS:
26093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sincos( emit, insn );
26103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_END:
26123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* TGSI always finishes the main func with an END */
26133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_end( emit );
26143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_KIL:
26163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_kil( emit, insn );
26173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Selection opcodes.  The underlying language is fairly
26193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * non-orthogonal about these.
26203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SEQ:
26223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_EQUAL, insn );
26233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SNE:
26253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_NOTEQUAL, insn );
26263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SGT:
26283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_GREATER, insn );
26293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SGE:
26313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_GEQUAL, insn );
26323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SLT:
26343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_LESS, insn );
26353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SLE:
26373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_LEQUAL, insn );
26383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SUB:
26403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sub( emit, insn );
26413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_POW:
26433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_pow( emit, insn );
26443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_EX2:
26463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_ex2( emit, insn );
26473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_EXP:
26493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_exp( emit, insn );
26503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LOG:
26523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_log( emit, insn );
26533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LG2:
26553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_LOG, insn );
26563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RSQ:
26583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_RSQ, insn );
26593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RCP:
26613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_RCP, insn );
26623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CONT:
26643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RET:
26653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* This is a noop -- we tell mesa that we can't support RET
26663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * within a function (early return), so this will always be
26673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * followed by an ENDSUB.
26683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
26703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* These aren't actually used by any of the frontends we care
26723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * about:
26733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CLAMP:
26753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_AND:
26763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_OR:
26773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_I2F:
26783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NOT:
26793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SHL:
26802c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
26813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_XOR:
26823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
26833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_IF:
26853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_if( emit, insn );
26863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ELSE:
26873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_else( emit, insn );
26883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDIF:
26893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_endif( emit, insn );
26903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BGNLOOP:
26923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_bgnloop2( emit, insn );
26933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDLOOP:
26943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_endloop2( emit, insn );
26953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BRK:
26963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_brk( emit, insn );
26973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_XPD:
26993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_xpd( emit, insn );
27003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_KILP:
27023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_kilp( emit, insn );
27033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DST:
27053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dst_insn( emit, insn );
27063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LIT:
27083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_lit( emit, insn );
27093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LRP:
27113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_lrp( emit, insn );
27123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27135a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   case TGSI_OPCODE_SSG:
27145a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return emit_ssg( emit, insn );
27155a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
27163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default: {
27173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned opcode = translate_opcode(insn->Instruction.Opcode);
27183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (opcode == SVGA3DOP_LAST_INST)
27203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_simple_instruction( emit, opcode, insn ))
27233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_emit_immediate( struct svga_shader_emitter *emit,
27323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                    struct tgsi_full_immediate *imm)
27333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
27343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   static const float id[4] = {0,0,0,1};
27353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float value[4];
27363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
27373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(1 <= imm->Immediate.NrTokens && imm->Immediate.NrTokens <= 5);
27393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < imm->Immediate.NrTokens - 1; i++)
27403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      value[i] = imm->u[i].Float;
27413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for ( ; i < 4; i++ )
27433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      value[i] = id[i];
27443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
27463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          emit->imm_start + emit->internal_imm_count++,
27473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          value[0], value[1], value[2], value[3]);
27483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean make_immediate( struct svga_shader_emitter *emit,
27513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float a,
27523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float b,
27533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float c,
27543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float d,
27553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               struct src_register *out )
27563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2757279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_float_const++;
27583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
27603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        idx, a, b, c, d ))
27613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
27623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   *out = src_register( SVGA3DREG_CONST, idx );
27643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_vs_preamble( struct svga_shader_emitter *emit )
27693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
27703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit->key.vkey.need_prescale) {
27713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!make_immediate( emit, 0, 0, .5, .5,
27723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           &emit->imm_0055))
27733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ps_preamble( struct svga_shader_emitter *emit )
27803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
278194b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul   if (emit->ps_reads_pos && emit->info.reads_z) {
2782166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /*
2783166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * Assemble the position from various bits of inputs. Depth and W are
2784166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * passed in a texcoord this is due to D3D's vPos not hold Z or W.
2785166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * Also fixup the perspective interpolation.
2786166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       *
2787166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.xy = vPos.xy
2788166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.w = rcp(texcoord1.w);
2789166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.z = texcoord1.z * temp_pos.w;
2790166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       */
2791166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2792166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
2793166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_XY ),
2794166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       emit->ps_true_pos ))
2795166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2796166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2797166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2798166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_RCP),
2799166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_W ),
2800166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_W ) ))
2801166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2802166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2803166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op2( emit,
2804166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MUL),
2805166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_Z ),
2806166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_Z ),
2807166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( src(emit->ps_temp_pos), TGSI_SWIZZLE_W ) ))
2808166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
28093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28104f17830b3dda5a1727a3c87897e73b56b37613a6Jakob Bornecrantz
28113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
28123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
28133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ps_postamble( struct svga_shader_emitter *emit )
28153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
28163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
28173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* PS oDepth is incredibly fragile and it's very hard to catch the
28193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * types of usage that break it during shader emit.  Easier just to
28203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * redirect the main program to a temporary and then only touch
28213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * oDepth with a hand-crafted MOV below.
28223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (SVGA3dShaderGetRegType(emit->true_pos.value) != 0) {
28243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
28263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
28273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       emit->true_pos,
28283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar(src(emit->temp_pos), TGSI_SWIZZLE_Z) ))
28293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
28303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
28333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
28343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2835fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         /* Potentially override output colors with white for XOR
2836fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell          * logicop workaround.
2837fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell          */
2838fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         if (emit->unit == PIPE_SHADER_FRAGMENT &&
2839fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell             emit->key.fkey.white_fragments) {
2840fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
2841fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            struct src_register one = scalar( get_zero_immediate( emit ),
2842fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                                              TGSI_SWIZZLE_W );
2843fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
2844fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            if (!submit_op1( emit,
2845fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             inst_token(SVGA3DOP_MOV),
2846fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             emit->true_col[i],
2847fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             one ))
2848fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell               return FALSE;
2849fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         }
2850fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         else {
2851fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            if (!submit_op1( emit,
2852fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             inst_token(SVGA3DOP_MOV),
2853fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             emit->true_col[i],
2854fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             src(emit->temp_col[i]) ))
2855fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell               return FALSE;
2856fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         }
28573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
28583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
28613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
28623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_vs_postamble( struct svga_shader_emitter *emit )
28643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
28653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* PSIZ output is incredibly fragile and it's very hard to catch
28663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * the types of usage that break it during shader emit.  Easier
28673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * just to redirect the main program to a temporary and then only
28683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * touch PSIZ with a hand-crafted MOV below.
28693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (SVGA3dShaderGetRegType(emit->true_psiz.value) != 0) {
28713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
28733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
28743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       emit->true_psiz,
28753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar(src(emit->temp_psiz), TGSI_SWIZZLE_X) ))
28763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
28773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to perform various manipulations on vertex position to cope
28803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * with the different GL and D3D clip spaces.
28813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->key.vkey.need_prescale) {
28833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2884166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      SVGA3dShaderDestToken depth = emit->depth_pos;
28853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken pos = emit->true_pos;
28863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned offset = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
28873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register prescale_scale = src_register( SVGA3DREG_CONST,
28883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                                         offset + 0 );
28893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register prescale_trans = src_register( SVGA3DREG_CONST,
28903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                                         offset + 1 );
28913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2892166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2893166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
2894166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_W),
2895166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar(src(temp_pos), TGSI_SWIZZLE_W) ))
2896166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2897166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
28983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* MUL temp_pos.xyz,    temp_pos,      prescale.scale
28993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * MAD result.position, temp_pos.wwww, prescale.trans, temp_pos
29003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   --> Note that prescale.trans.w == 0
29013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
29023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit,
29033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MUL),
29043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(temp_pos, TGSI_WRITEMASK_XYZ),
29053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos),
29063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       prescale_scale ))
29073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
29083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op3( emit,
29103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MAD),
29113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       pos,
29123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       swizzle(src(temp_pos), 3, 3, 3, 3),
29133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       prescale_trans,
29143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos)))
29153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
2916166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2917166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /* Also write to depth value */
2918166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op3( emit,
2919166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MAD),
29208bf3fb4eca5594f8348de2f8fb67bc94127f8d5aJakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_Z),
2921166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       swizzle(src(temp_pos), 3, 3, 3, 3),
2922166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       prescale_trans,
2923166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       src(temp_pos) ))
2924166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
29253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
29263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
29273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2928166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      SVGA3dShaderDestToken depth = emit->depth_pos;
29293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken pos = emit->true_pos;
29303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register imm_0055 = emit->imm_0055;
29313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Adjust GL clipping coordinate space to hardware (D3D-style):
29333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
29343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * DP4 temp_pos.z, {0,0,.5,.5}, temp_pos
29353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * MOV result.position, temp_pos
29363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
29373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit,
29383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_DP4),
29393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(temp_pos, TGSI_WRITEMASK_Z),
29403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       imm_0055,
29413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos) ))
29423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
29433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
29453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
29463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       pos,
29473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos) ))
29483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
2949166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2950166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /* Move the manipulated depth into the extra texcoord reg */
2951166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2952166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
29538bf3fb4eca5594f8348de2f8fb67bc94127f8d5aJakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_ZW),
2954166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       src(temp_pos) ))
2955166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
29563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
29573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
29593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
29603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
29623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  0: IF VFACE :4
29633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  1:   COLOR = FrontColor;
29643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  2: ELSE
29653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  3:   COLOR = BackColor;
29663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  4: ENDIF
29673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
29683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_light_twoside( struct svga_shader_emitter *emit )
29693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
29703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register vface, zero;
29713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register front[2];
29723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register back[2];
29733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken color[2];
29743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int count =  emit->internal_color_count;
29753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
29763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken if_token;
29773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (count == 0)
29793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
29803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vface = get_vface( emit );
29823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = get_zero_immediate( emit );
29833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Can't use get_temp() to allocate the color reg as such
29853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * temporaries will be reclaimed after each instruction by the call
29863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * to reset_temp_regs().
29873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
29883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
29893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      color[i] = dst_register( SVGA3DREG_TEMP,
29903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               emit->nr_hw_temp++ );
29913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      front[i] = emit->input_map[emit->internal_color_idx[i]];
29933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Back is always the next input:
29953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
29963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      back[i] = front[i];
29973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      back[i].base.num = front[i].base.num + 1;
29983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Reassign the input_map to the actual front-face color:
30003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
30013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->input_map[emit->internal_color_idx[i]] = src(color[i]);
30023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if_token = inst_token( SVGA3DOP_IFC );
30053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30060bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (emit->key.fkey.front_ccw)
30073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if_token.control = SVGA3DOPCOMP_LT;
30080bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   else
30090bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if_token.control = SVGA3DOPCOMP_GT;
30103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = scalar(zero, TGSI_SWIZZLE_X);
30123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!(emit_instruction( emit, if_token ) &&
30143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit_src( emit, vface ) &&
30153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit_src( emit, zero ) ))
30163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
30193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], front[i] ))
30203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
30213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!(emit_instruction( emit, inst_token( SVGA3DOP_ELSE))))
30243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
30273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], back[i] ))
30283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
30293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_instruction( emit, inst_token( SVGA3DOP_ENDIF ) ))
30323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
30353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
30363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
30383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  0: SETP_GT TEMP, VFACE, 0
30393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  where TEMP is a fake frontface register
30403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
30413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_frontface( struct svga_shader_emitter *emit )
30423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
30433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register vface, zero;
30443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
30453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register pass, fail;
30463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vface = get_vface( emit );
30483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = get_zero_immediate( emit );
30493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Can't use get_temp() to allocate the fake frontface reg as such
30513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * temporaries will be reclaimed after each instruction by the call
30523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * to reset_temp_regs().
30533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
30543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp = dst_register( SVGA3DREG_TEMP,
30553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        emit->nr_hw_temp++ );
30563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30570bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (emit->key.fkey.front_ccw) {
30583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      pass = scalar( zero, TGSI_SWIZZLE_X );
30593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fail = scalar( zero, TGSI_SWIZZLE_W );
30600bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   } else {
30610bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      pass = scalar( zero, TGSI_SWIZZLE_W );
30620bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      fail = scalar( zero, TGSI_SWIZZLE_X );
30633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_conditional(emit, PIPE_FUNC_GREATER,
30663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         temp, vface, scalar( zero, TGSI_SWIZZLE_X ),
30673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         pass, fail))
30683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Reassign the input_map to the actual front-face color:
30713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
30723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->input_map[emit->internal_frontface_idx] = src(temp);
30733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
30753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
30763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30772f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30782f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul/**
30792f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * Emit code to invert the T component of the incoming texture coordinate.
30802f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * This is used for drawing point sprites when
30812f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * pipe_rasterizer_state::sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT.
30822f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul */
30832f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulstatic boolean emit_inverted_texcoords( struct svga_shader_emitter *emit )
30842f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul{
30852f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   struct src_register zero = get_zero_immediate(emit);
30862f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   struct src_register pos_neg_one = get_pos_neg_one_immediate( emit );
30872f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   unsigned inverted_texcoords = emit->inverted_texcoords;
30882f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30892f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   while (inverted_texcoords) {
30902f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      const unsigned unit = ffs(inverted_texcoords) - 1;
30912f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30922f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(emit->inverted_texcoords & (1 << unit));
30932f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30942f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(unit < Elements(emit->ps_true_texcoord));
30952f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30962f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(unit < Elements(emit->ps_inverted_texcoord_input));
30972f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30982f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(emit->ps_inverted_texcoord_input[unit]
30992f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul             < Elements(emit->input_map));
31002f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31012f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      /* inverted = coord * (1, -1, 1, 1) + (0, 1, 0, 0) */
31022f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      if (!submit_op3(emit,
31032f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      inst_token(SVGA3DOP_MAD),
31042f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      dst(emit->ps_inverted_texcoord[unit]),
31052f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      emit->ps_true_texcoord[unit],
31062f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      swizzle(pos_neg_one, 0, 3, 0, 0),  /* (1, -1, 1, 1) */
31072f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      swizzle(zero, 0, 3, 0, 0)))  /* (0, 1, 0, 0) */
31082f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         return FALSE;
31092f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31102f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      /* Reassign the input_map entry to the new texcoord register */
31112f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      emit->input_map[emit->ps_inverted_texcoord_input[unit]] =
31122f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         emit->ps_inverted_texcoord[unit];
31132f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31142f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      inverted_texcoords &= ~(1 << unit);
31152f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   }
31162f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31172f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return TRUE;
31182f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul}
31192f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31202f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_zero( struct svga_shader_emitter *emit )
31233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
31253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_FRAGMENT) {
31273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->key.fkey.light_twoside)
31283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3130fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell      if (emit->key.fkey.white_fragments)
3131fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         return TRUE;
3132fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
31333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->emit_frontface)
31343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->info.opcode_count[TGSI_OPCODE_DST] >= 1 ||
31375a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer          emit->info.opcode_count[TGSI_OPCODE_SSG] >= 1 ||
31383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          emit->info.opcode_count[TGSI_OPCODE_LIT] >= 1)
31393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31402f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31412f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      if (emit->inverted_texcoords)
31422f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         return TRUE;
31439bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
31449bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      /* look for any PIPE_SWIZZLE_ZERO/ONE terms */
31459bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      for (i = 0; i < emit->key.fkey.num_textures; i++) {
31469bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         if (emit->key.fkey.tex[i].swizzle_r > PIPE_SWIZZLE_ALPHA ||
31479bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_g > PIPE_SWIZZLE_ALPHA ||
31489bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_b > PIPE_SWIZZLE_ALPHA ||
31499bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_a > PIPE_SWIZZLE_ALPHA)
31509bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul            return TRUE;
31519bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
31523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
31533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31541bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol   if (emit->unit == PIPE_SHADER_VERTEX) {
31551bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol      if (emit->info.opcode_count[TGSI_OPCODE_CMP] >= 1)
31561bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol         return TRUE;
31571bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol   }
31581bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol
31593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
3160a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
31610748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
31620748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
31631ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul       emit->info.opcode_count[TGSI_OPCODE_ROUND] >= 1 ||
31643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
31653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
31663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
31673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SLT] >= 1 ||
31683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SNE] >= 1 ||
31693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SEQ] >= 1 ||
31703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_EXP] >= 1 ||
31713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_LOG] >= 1 ||
31723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_XPD] >= 1 ||
31733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_KILP] >= 1)
31743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
31753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->key.fkey.num_textures; i++) {
31773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->key.fkey.tex[i].compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
31783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
31803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return FALSE;
31823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_loop_const( struct svga_shader_emitter *emit )
31863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1);
31883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_arl_consts( struct svga_shader_emitter *emit )
31923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit->num_arl_consts > 0);
31943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_add_indirect( struct svga_shader_emitter *emit,
31983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        int num, int current_arl)
31993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
32013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(num < 0);
32023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
32043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == current_arl)
32053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* new entry */
32083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->num_arl_consts == i) {
32093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ++emit->num_arl_consts;
32103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->arl_consts[i].number = (emit->arl_consts[i].number > num) ?
32123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                num :
32133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                emit->arl_consts[i].number;
32143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->arl_consts[i].arl_num = current_arl;
32153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
32193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_instruction( struct svga_shader_emitter *emit,
32203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn,
32213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       int current_arl)
32223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
322391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[0].Register.Indirect &&
322491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[0].Indirect.File == TGSI_FILE_ADDRESS) {
32257d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[0];
322691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
322791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
323191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[1].Register.Indirect &&
323291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[1].Indirect.File == TGSI_FILE_ADDRESS) {
32337d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[1];
323491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
323591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
323991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[2].Register.Indirect &&
324091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[2].Indirect.File == TGSI_FILE_ADDRESS) {
32417d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[2];
324291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
324391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
32513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_tokens( struct svga_shader_emitter *emit,
32523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                  const struct tgsi_token *tokens )
32533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct tgsi_parse_context parse;
32553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int current_arl = 0;
32563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_init( &parse, tokens );
32583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   while (!tgsi_parse_end_of_tokens( &parse )) {
32603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tgsi_parse_token( &parse );
32613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (parse.FullToken.Token.Type) {
32623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_IMMEDIATE:
32633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_DECLARATION:
32643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_INSTRUCTION:
32663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (parse.FullToken.FullInstruction.Instruction.Opcode ==
32673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz             TGSI_OPCODE_ARL) {
32683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            ++current_arl;
32693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
32703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!pre_parse_instruction( emit, &parse.FullToken.FullInstruction,
32713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                     current_arl ))
32723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
32733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
32753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_shader_emit_helpers( struct svga_shader_emitter *emit )
32833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_zero( emit )) {
32863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_zero_immediate( emit );
32873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_loop_const( emit )) {
32893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_loop_const( emit );
32903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_arl_consts( emit )) {
32923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_arl_consts( emit );
32933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_FRAGMENT) {
32963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_ps_preamble( emit ))
32973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
32983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->key.fkey.light_twoside) {
33003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!emit_light_twoside( emit ))
33013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
33023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
33033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->emit_frontface) {
33043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!emit_frontface( emit ))
33053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
33063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
33072f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      if (emit->inverted_texcoords) {
33082f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         if (!emit_inverted_texcoords( emit ))
33092f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul            return FALSE;
33102f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      }
33113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
33143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
33153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
33173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       const struct tgsi_token *tokens )
33183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
33193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct tgsi_parse_context parse;
33203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean ret = TRUE;
33213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean helpers_emitted = FALSE;
33223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned line_nr = 0;
33233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_init( &parse, tokens );
33253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->internal_imm_count = 0;
33263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
33283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = emit_vs_preamble( emit );
33293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!ret)
33303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         goto done;
33313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   pre_parse_tokens(emit, tokens);
33343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   while (!tgsi_parse_end_of_tokens( &parse )) {
33363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tgsi_parse_token( &parse );
33373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (parse.FullToken.Token.Type) {
33393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_IMMEDIATE:
33403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = svga_emit_immediate( emit, &parse.FullToken.FullImmediate );
33413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_DECLARATION:
334694b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul         ret = svga_translate_decl_sm30( emit, &parse.FullToken.FullDeclaration );
33473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_INSTRUCTION:
33523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!helpers_emitted) {
33533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            if (!svga_shader_emit_helpers( emit ))
33543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               goto done;
33553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            helpers_emitted = TRUE;
33563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
33573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = svga_emit_instruction( emit,
33583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      line_nr++,
33593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      &parse.FullToken.FullInstruction );
33603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
33643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
33663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      reset_temp_regs( emit );
33683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to terminate the current subroutine.  Note that the
33713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * hardware doesn't tolerate shaders without sub-routines
33723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * terminating with RET+END.
33733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
33743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit->in_main_func) {
33753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = emit_instruction( emit, inst_token( SVGA3DOP_RET ) );
33763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!ret)
33773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         goto done;
33783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3380a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   assert(emit->dynamic_branching_level == 0);
3381a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
33823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to terminate the whole shader:
33833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
33843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
33853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!ret)
33863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      goto done;
33873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzdone:
33893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_free( &parse );
33903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return ret;
33913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
33923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3393