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 Bornecrantzstatic unsigned
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_opcode(
433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   uint opcode )
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (opcode) {
463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ABS:        return SVGA3DOP_ABS;
473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ADD:        return SVGA3DOP_ADD;
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BREAKC:     return SVGA3DOP_BREAKC;
493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP2A:       return SVGA3DOP_DP2ADD;
503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP3:        return SVGA3DOP_DP3;
513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP4:        return SVGA3DOP_DP4;
523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_FRC:        return SVGA3DOP_FRC;
533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MAD:        return SVGA3DOP_MAD;
543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MAX:        return SVGA3DOP_MAX;
553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MIN:        return SVGA3DOP_MIN;
563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MOV:        return SVGA3DOP_MOV;
573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_MUL:        return SVGA3DOP_MUL;
583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NOP:        return SVGA3DOP_NOP;
593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NRM4:       return SVGA3DOP_NRM;
603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      debug_printf("Unkown opcode %u\n", opcode);
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert( 0 );
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return SVGA3DOP_LAST_INST;
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic unsigned translate_file( unsigned file )
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (file) {
713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_TEMPORARY: return SVGA3DREG_TEMP;
723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_INPUT:     return SVGA3DREG_INPUT;
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_OUTPUT:    return SVGA3DREG_OUTPUT; /* VS3.0+ only */
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_IMMEDIATE: return SVGA3DREG_CONST;
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_CONSTANT:  return SVGA3DREG_CONST;
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_SAMPLER:   return SVGA3DREG_SAMPLER;
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_ADDRESS:   return SVGA3DREG_ADDR;
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert( 0 );
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return SVGA3DREG_TEMP;
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
85bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paulstatic SVGA3dShaderDestToken
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_dst_register( struct svga_shader_emitter *emit,
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn,
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        unsigned idx )
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
907d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &insn->Dst[idx];
913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dest;
923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
935b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch (reg->Register.File) {
943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_OUTPUT:
953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Output registers encode semantic information in their name.
963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Need to lookup a table built at decl time:
973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
985b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      dest = emit->output_map[reg->Register.Index];
993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
1024516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul      {
1034516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         unsigned index = reg->Register.Index;
1044516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         assert(index < SVGA3D_TEMPREG_MAX);
1054516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         index = MIN2(index, SVGA3D_TEMPREG_MAX - 1);
1064516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul         dest = dst_register(translate_file(reg->Register.File), index);
107bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      }
1083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1115b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   dest.mask = reg->Register.WriteMask;
1127384cdf651dc69098f4d988dd3b217879ec63336José Fonseca   assert(dest.mask);
1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
114bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   if (insn->Instruction.Saturate)
1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      dest.dstMod = SVGA3DDSTMOD_SATURATE;
1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return dest;
1183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
121bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paulstatic struct src_register
1223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzswizzle( struct src_register src,
1233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int x,
1243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int y,
1253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int z,
1263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         int w )
1273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   x = (src.base.swizzle >> (x * 2)) & 0x3;
1293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   y = (src.base.swizzle >> (y * 2)) & 0x3;
1303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   z = (src.base.swizzle >> (z * 2)) & 0x3;
1313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   w = (src.base.swizzle >> (w * 2)) & 0x3;
1323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src.base.swizzle = TRANSLATE_SWIZZLE(x,y,z,w);
1343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src;
1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic struct src_register
1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzscalar( struct src_register src,
1403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz        int comp )
1413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return swizzle( src, comp, comp, comp, comp );
1433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
1463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_arl_needs_adjustment( const struct svga_shader_emitter *emit )
1473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
1493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl)
1523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return FALSE;
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE int
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_arl_adjustment( const struct svga_shader_emitter *emit )
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl)
1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return emit->arl_consts[i].number;
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
169bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paulstatic struct src_register
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantztranslate_src_register( const struct svga_shader_emitter *emit,
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_src_register *reg )
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src;
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   switch (reg->Register.File) {
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_INPUT:
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Input registers are referred to by their semantic name rather
1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * than by index.  Use the mapping build up from the decls:
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
18091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = emit->input_map[reg->Register.Index];
1813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
182bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_FILE_IMMEDIATE:
1843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Immediates are appended after TGSI constants in the D3D
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * constant buffer.
1863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
18791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = src_register( translate_file( reg->Register.File ),
188bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                          reg->Register.Index + emit->imm_start );
1893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
19291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      src = src_register( translate_file( reg->Register.File ),
19391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                          reg->Register.Index );
1943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
1963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
1973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1980742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   /* Indirect addressing.
1993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
2000742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   if (reg->Register.Indirect) {
2010742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      if (emit->unit == PIPE_SHADER_FRAGMENT) {
2020742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         /* Pixel shaders have only loop registers for relative
2030742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          * addressing into inputs. Ignore the redundant address
2040742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          * register, the contents of aL should be in sync with it.
2050742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          */
2060742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         if (reg->Register.File == TGSI_FILE_INPUT) {
2070742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.base.relAddr = 1;
2080742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect = src_token(SVGA3DREG_LOOP, 0);
2090742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         }
2100742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      }
2110742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      else {
2120742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         /* Constant buffers only.
2130742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol          */
2140742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         if (reg->Register.File == TGSI_FILE_CONSTANT) {
2150742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            /* we shift the offset towards the minimum */
2160742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            if (svga_arl_needs_adjustment( emit )) {
2170742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol               src.base.num -= svga_arl_adjustment( emit );
2180742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            }
2190742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.base.relAddr = 1;
2200742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol
2210742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            /* Not really sure what should go in the second token:
2220742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol             */
2230742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect = src_token( SVGA3DREG_ADDR,
2240742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol                                      reg->Indirect.Index );
2250742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol
2260742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol            src.indirect.swizzle = SWIZZLE_XXXX;
2270742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol         }
2283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src = swizzle( src,
23291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleX,
23391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleY,
23491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleZ,
23591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell                  reg->Register.SwizzleW );
2363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* src.mod isn't a bitfield, unfortunately:
2383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * See tgsi_util_get_full_src_register_sign_mode for implementation details.
2393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
24091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (reg->Register.Absolute) {
24191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Negate)
2423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_ABSNEG;
2433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
2443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_ABS;
2453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
24791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Negate)
2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_NEG;
2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src.base.srcMod = SVGA3DSRCMOD_NONE;
2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src;
2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
2584516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * Get a temporary register.
2594516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * Note: if we exceed the temporary register limit we just use
2604516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul * register SVGA3D_TEMPREG_MAX - 1.
2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
262bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paulstatic INLINE SVGA3dShaderDestToken
2633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_temp( struct svga_shader_emitter *emit )
2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i = emit->nr_hw_temp + emit->internal_temp_count++;
2664516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul   assert(i < SVGA3D_TEMPREG_MAX);
2674516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7dBrian Paul   i = MIN2(i, SVGA3D_TEMPREG_MAX - 1);
2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return dst_register( SVGA3DREG_TEMP, i );
2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Release a single temp.  Currently only effective if it was the last
2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * allocated temp, otherwise release will be delayed until the next
2733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * call to reset_temp_regs().
2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
275bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paulstatic INLINE void
2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzrelease_temp( struct svga_shader_emitter *emit,
2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz              SVGA3dShaderDestToken temp )
2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (temp.num == emit->internal_temp_count - 1)
2803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->internal_temp_count--;
2813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
2823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void reset_temp_regs( struct svga_shader_emitter *emit )
2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->internal_temp_count = 0;
2863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
287bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
2883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
289965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca/* Replace the src with the temporary specified in the dst, but copying
290965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * only the necessary channels, and preserving the original swizzle (which is
291965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * important given that several opcodes have constraints in the allowed
292965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca * swizzles).
293965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca */
294965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonsecastatic boolean emit_repl( struct svga_shader_emitter *emit,
295965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca                          SVGA3dShaderDestToken dst,
296965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca                          struct src_register *src0)
297965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca{
298965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   unsigned src0_swizzle;
299965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   unsigned chan;
300965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
301965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   assert(SVGA3dShaderGetRegType(dst.value) == SVGA3DREG_TEMP);
302965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
303965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0_swizzle = src0->base.swizzle;
304965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
305965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   dst.mask = 0;
306965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   for (chan = 0; chan < 4; ++chan) {
307965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      unsigned swizzle = (src0_swizzle >> (chan *2)) & 0x3;
308965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      dst.mask |= 1 << swizzle;
309965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   }
310965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   assert(dst.mask);
311965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
312965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0->base.swizzle = SVGA3DSWIZZLE_NONE;
313965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
314965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, *src0 ))
315965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      return FALSE;
316965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
317965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   *src0 = src( dst );
318965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   src0->base.swizzle = src0_swizzle;
319965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
320965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   return TRUE;
321965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca}
322965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
323965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca
3243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op0( struct svga_shader_emitter *emit,
3253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest )
3273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
328bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   return (emit_instruction( emit, inst ) &&
3293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_dst( emit, dest ));
3303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op1( struct svga_shader_emitter *emit,
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0 )
3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_op1( emit, inst, dest, src0 );
3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* SVGA shaders may not refer to >1 constant register in a single
3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * instruction.  This function checks for that usage and inserts a
3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * move to temporary if detected.
3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The same applies to input registers -- at most a single input
3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * register may be read by any instruction.
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op2( struct svga_shader_emitter *emit,
3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0,
3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src1 )
3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderRegType type0, type1;
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp = FALSE;
3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp.value = 0;
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type0 = SVGA3dShaderGetRegType( src0.base.value );
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type1 = SVGA3dShaderGetRegType( src1.base.value );
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_CONST &&
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       type1 == SVGA3DREG_CONST &&
3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.num != src1.base.num)
3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp = TRUE;
3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_INPUT &&
3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       type1 == SVGA3DREG_INPUT &&
3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.num != src1.base.num)
3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp = TRUE;
3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
372965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp) {
3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp = get_temp( emit );
3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
375965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp, &src0 ))
3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_op2( emit, inst, dest, src0, src1 ))
3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp)
3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp );
3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* SVGA shaders may not refer to >1 constant register in a single
3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * instruction.  This function checks for that usage and inserts a
3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * move to temporary if detected.
3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean submit_op3( struct svga_shader_emitter *emit,
3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderInstToken inst,
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           SVGA3dShaderDestToken dest,
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src0,
3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src1,
3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           struct src_register src2 )
3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp0;
4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp1;
4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp0 = FALSE;
4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_temp1 = FALSE;
4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderRegType type0, type1, type2;
4053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp0.value = 0;
4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp1.value = 0;
4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type0 = SVGA3dShaderGetRegType( src0.base.value );
4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type1 = SVGA3dShaderGetRegType( src1.base.value );
4103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   type2 = SVGA3dShaderGetRegType( src2.base.value );
4113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (inst.op != SVGA3DOP_SINCOS) {
4133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (type0 == SVGA3DREG_CONST &&
4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          ((type1 == SVGA3DREG_CONST && src0.base.num != src1.base.num) ||
4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_temp0 = TRUE;
4173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (type1 == SVGA3DREG_CONST &&
4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          (type2 == SVGA3DREG_CONST && src1.base.num != src2.base.num))
4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_temp1 = TRUE;
4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type0 == SVGA3DREG_INPUT &&
4243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       ((type1 == SVGA3DREG_INPUT && src0.base.num != src1.base.num) ||
4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp0 = TRUE;
4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (type1 == SVGA3DREG_INPUT &&
4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       (type2 == SVGA3DREG_INPUT && src1.base.num != src2.base.num))
4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_temp1 = TRUE;
4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
432965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp0) {
4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp0 = get_temp( emit );
434bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
435965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp0, &src0 ))
4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
439965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp1) {
4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      temp1 = get_temp( emit );
4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
442965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp1, &src1 ))
4433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
4443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_op3( emit, inst, dest, src0, src1, src2 ))
4473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
4483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp1)
4503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp1 );
4513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_temp0)
4523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, temp0 );
4533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
4543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
45784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
45884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
45984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell/* SVGA shaders may not refer to >1 constant register in a single
46084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell * instruction.  This function checks for that usage and inserts a
46184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell * move to temporary if detected.
46284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell */
46384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwellstatic boolean submit_op4( struct svga_shader_emitter *emit,
46484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           SVGA3dShaderInstToken inst,
46584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           SVGA3dShaderDestToken dest,
46684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src0,
46784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src1,
46884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src2,
46984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell                           struct src_register src3)
47084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell{
47184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderDestToken temp0;
47284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderDestToken temp3;
47384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   boolean need_temp0 = FALSE;
47484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   boolean need_temp3 = FALSE;
47584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   SVGA3dShaderRegType type0, type1, type2, type3;
47684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
47784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   temp0.value = 0;
47884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   temp3.value = 0;
47984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type0 = SVGA3dShaderGetRegType( src0.base.value );
48084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type1 = SVGA3dShaderGetRegType( src1.base.value );
48184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type2 = SVGA3dShaderGetRegType( src2.base.value );
48284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   type3 = SVGA3dShaderGetRegType( src2.base.value );
48384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
48484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   /* Make life a little easier - this is only used by the TXD
48584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    * instruction which is guaranteed not to have a constant/input reg
48684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    * in one slot at least:
48784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell    */
48884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   assert(type1 == SVGA3DREG_SAMPLER);
48984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
49084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type0 == SVGA3DREG_CONST &&
49184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       ((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
49284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell        (type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
49384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp0 = TRUE;
49484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
49584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type3 == SVGA3DREG_CONST &&
49684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       (type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
49784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp3 = TRUE;
49884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
49984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type0 == SVGA3DREG_INPUT &&
50084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       ((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
50184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell        (type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
50284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp0 = TRUE;
50384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
50484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (type3 == SVGA3DREG_INPUT &&
50584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       (type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
50684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      need_temp3 = TRUE;
50784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
508965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp0) {
50984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      temp0 = get_temp( emit );
510bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
511965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp0, &src0 ))
51284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell         return FALSE;
51384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   }
51484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
515965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca   if (need_temp3) {
51684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      temp3 = get_temp( emit );
51784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
518965ab5fed3c734e6205070e6cf40544a44b5dbf6José Fonseca      if (!emit_repl( emit, temp3, &src3 ))
51984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell         return FALSE;
52084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   }
52184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
52284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
52384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      return FALSE;
52484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
52584d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (need_temp3)
52684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      release_temp( emit, temp3 );
52784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   if (need_temp0)
52884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      release_temp( emit, temp0 );
52984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   return TRUE;
53084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell}
53184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
53284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
53315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonsecastatic boolean alias_src_dst( struct src_register src,
53415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                              SVGA3dShaderDestToken dst )
53515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca{
53615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (src.base.num != dst.num)
53715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
53815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
53915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (SVGA3dShaderGetRegType(dst.value) !=
54015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       SVGA3dShaderGetRegType(src.base.value))
54115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
54215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
54315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return TRUE;
54415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca}
54515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
54615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
54715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonsecastatic boolean submit_lrp(struct svga_shader_emitter *emit,
54815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          SVGA3dShaderDestToken dst,
54915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src0,
55015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src1,
55115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca                          struct src_register src2)
55215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca{
55315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   SVGA3dShaderDestToken tmp;
55415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   boolean need_dst_tmp = FALSE;
55515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
55615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   /* The dst reg must be a temporary, and not be the same as src0 or src2 */
55715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
55815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       alias_src_dst(src0, dst) ||
55915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca       alias_src_dst(src2, dst))
56015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      need_dst_tmp = TRUE;
56115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
56215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (need_dst_tmp) {
56315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp = get_temp( emit );
56415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp.mask = dst.mask;
56515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
56615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   else {
56715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      tmp = dst;
56815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
56915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
57015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (!submit_op3(emit, inst_token( SVGA3DOP_LRP ), tmp, src0, src1, src2))
57115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      return FALSE;
57215c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
57315c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   if (need_dst_tmp) {
57415c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
57515c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca         return FALSE;
57615c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   }
57715c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
57815c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return TRUE;
57915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca}
58015c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
58115c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca
5823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_def_const( struct svga_shader_emitter *emit,
5833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               SVGA3dShaderConstType type,
5843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               unsigned idx,
5853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float a,
5863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float b,
5873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float c,
5883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float d )
5893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3DOpDefArgs def;
5913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken opcode;
5923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (type) {
5943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case SVGA3D_CONST_TYPE_FLOAT:
5953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      opcode = inst_token( SVGA3DOP_DEF );
5963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.dst = dst_register( SVGA3DREG_CONST, idx );
5973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[0] = a;
5983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[1] = b;
5993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[2] = c;
6003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constValues[3] = d;
6013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case SVGA3D_CONST_TYPE_INT:
6033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      opcode = inst_token( SVGA3DOP_DEFI );
6043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.dst = dst_register( SVGA3DREG_CONSTINT, idx );
6053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[0] = (int)a;
6063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[1] = (int)b;
6073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[2] = (int)c;
6083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      def.constIValues[3] = (int)d;
6093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
6113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
6127e64701263f8158fb4138610ba63df41eefe6594Vinson Lee      opcode = inst_token( SVGA3DOP_NOP );
6133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
6143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
6153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_instruction(emit, opcode) ||
6173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       !svga_shader_emit_dwords( emit, def.values, Elements(def.values)))
6183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_zero_immediate( struct svga_shader_emitter *emit )
6253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
626279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_float_const++;
6273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6281ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   /* Emit the constant (0, 0.5, -1, 1) and use swizzling to generate
6292f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul    * other useful vectors.
6302f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul    */
6313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
6321ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                        idx, 0, 0.5, -1, 1 ))
6333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->zero_immediate_idx = idx;
6363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->created_zero_immediate = TRUE;
6373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_loop_const( struct svga_shader_emitter *emit )
6433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
644279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_int_const++;
6453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_INT, idx,
6473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        255, /* iteration count */
6483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        0, /* initial value */
6493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        1, /* step size */
6503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        0 /* not used, must be 0 */))
6513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
6523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->loop_const_idx = idx;
6543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->created_loop_const = TRUE;
6553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
6603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzcreate_arl_consts( struct svga_shader_emitter *emit )
6613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
6623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
6633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; i += 4) {
6653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      int j;
666279492386ffe741c2f5b91919b37068562b6a282Michal Krol      unsigned idx = emit->nr_hw_float_const++;
6673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float vals[4];
6683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      for (j = 0; j < 4 && (j + i) < emit->num_arl_consts; ++j) {
6693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         vals[j] = emit->arl_consts[i + j].number;
6703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit->arl_consts[i + j].idx = idx;
6713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         switch (j) {
6723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 0:
6733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_X;
6743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 1:
6763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Y;
6773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 2:
6793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_Z;
6803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         case 3:
6823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            emit->arl_consts[i + 0].swizzle = TGSI_SWIZZLE_W;
6833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            break;
6843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
6853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
6863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      while (j < 4)
6873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         vals[j++] = 0;
6883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT, idx,
6903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vals[0], vals[1],
6913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           vals[2], vals[3]))
6923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
6933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
6943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
6963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
6973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
6983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
6993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_vface( struct svga_shader_emitter *emit )
7003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->emitted_vface);
702bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   return src_register(SVGA3DREG_MISCTYPE, SVGA3DMISCREG_FACE);
7033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* returns {0, 0, 0, 1} immediate */
7063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_zero_immediate( struct svga_shader_emitter *emit )
7083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->created_zero_immediate);
7103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->zero_immediate_idx >= 0);
7112f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return swizzle(src_register( SVGA3DREG_CONST,
7122f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                                emit->zero_immediate_idx),
7132f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                  0, 0, 0, 3);
7142f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul}
7152f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
7162f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul/* returns {1, 1, 1, -1} immediate */
7172f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulstatic INLINE struct src_register
7182f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulget_pos_neg_one_immediate( struct svga_shader_emitter *emit )
7192f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul{
7202f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   assert(emit->created_zero_immediate);
7212f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   assert(emit->zero_immediate_idx >= 0);
7222f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return swizzle(src_register( SVGA3DREG_CONST,
7232f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                                emit->zero_immediate_idx),
7242f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                  3, 3, 3, 2);
7253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7271ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul/* returns {0.5, 0.5, 0.5, 0.5} immediate */
7281ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulstatic INLINE struct src_register
7291ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulget_half_immediate( struct svga_shader_emitter *emit )
7301ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul{
7311ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   assert(emit->created_zero_immediate);
7321ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   assert(emit->zero_immediate_idx >= 0);
7331ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   return swizzle(src_register(SVGA3DREG_CONST, emit->zero_immediate_idx),
7341ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                  1, 1, 1, 1);
7351ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul}
7361ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
7373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* returns the loop const */
7383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_loop_const( struct svga_shader_emitter *emit )
7403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->created_loop_const);
7423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(emit->loop_const_idx >= 0);
7433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return src_register( SVGA3DREG_CONSTINT,
7443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        emit->loop_const_idx );
7453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_fake_arl_const( struct svga_shader_emitter *emit )
7493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register reg;
7513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int idx = 0, swizzle = 0, i;
7523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++ i) {
7543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == emit->current_arl) {
7553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         idx = emit->arl_consts[i].idx;
7563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         swizzle = emit->arl_consts[i].swizzle;
7573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
7583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
7593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   reg = src_register( SVGA3DREG_CONST, idx );
7613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return scalar(reg, swizzle);
7623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE struct src_register
7653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzget_tex_dimensions( struct svga_shader_emitter *emit, int sampler_num )
7663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int idx;
7683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register reg;
7693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* the width/height indexes start right after constants */
7713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   idx = emit->key.fkey.tex[sampler_num].width_height_idx +
7723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
7733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   reg = src_register( SVGA3DREG_CONST, idx );
7753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return reg;
7763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
7773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_fake_arl(struct svga_shader_emitter *emit,
7793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn)
7803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
7813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
7827d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
7833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = get_fake_arl_const( emit );
7843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
7853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken tmp = get_temp( emit );
7863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
7883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
7893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), tmp, src( tmp ),
7913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src1))
7923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
7933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* replicate the original swizzle */
7953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = src(tmp);
7963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1.base.swizzle = src0.base.swizzle;
7973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
7983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst_token( SVGA3DOP_MOVA ),
7993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      dst, src1 );
8003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_if(struct svga_shader_emitter *emit,
8033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn)
8043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8050adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   struct src_register src0 = translate_src_register(
8067d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
8073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
8083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken if_token = inst_token( SVGA3DOP_IFC );
8093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if_token.control = SVGA3DOPCOMPC_NE;
8113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = scalar(zero, TGSI_SWIZZLE_X);
8123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8130adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   if (SVGA3dShaderGetRegType(src0.base.value) == SVGA3DREG_CONST) {
8140adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      /*
8150adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca       * Max different constant registers readable per IFC instruction is 1.
8160adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca       */
8170adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      SVGA3dShaderDestToken tmp = get_temp( emit );
8180adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
8190adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), tmp, src0))
8200adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca         return FALSE;
8210adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
8220adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca      src0 = scalar(src( tmp ), TGSI_SWIZZLE_X);
8230adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca   }
8240adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca
825a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level++;
826a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
8273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, if_token ) &&
8280adeaf00e6c4592e78cca36c3b365110b83c965dJosé Fonseca           emit_src( emit, src0 ) &&
8293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, zero ) );
8303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_endif(struct svga_shader_emitter *emit,
8333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn)
8343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
835a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level--;
836a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
837bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   return emit_instruction(emit, inst_token(SVGA3DOP_ENDIF));
8383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_else(struct svga_shader_emitter *emit,
8413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn)
8423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
843bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   return emit_instruction(emit, inst_token(SVGA3DOP_ELSE));
8443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI FLR instruction.
8473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    FLR  DST, SRC
8483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
8493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    FRC  TMP, SRC
8503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    SUB  DST, SRC, TMP
8513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
8523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_floor(struct svga_shader_emitter *emit,
8533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          const struct tgsi_full_instruction *insn )
8543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
8553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
8563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
8577d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
8583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
8593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* FRC  TMP, SRC */
8613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ), temp, src0 ))
8623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
8633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SUB  DST, SRC, TMP */
8653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src0,
8663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    negate( src( temp ) ) ))
8673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
8683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
8703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
8713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
8723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
873a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul/* Translate the following TGSI CEIL instruction.
874a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    CEIL  DST, SRC
875a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul * To the following SVGA3D instruction sequence.
876a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    FRC  TMP, -SRC
877a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul *    ADD  DST, SRC, TMP
878a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul */
879a1c5513c175a2c13594dde7110822b205cabfc14Brian Paulstatic boolean emit_ceil(struct svga_shader_emitter *emit,
880a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul                         const struct tgsi_full_instruction *insn)
881a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul{
882a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
883a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   const struct src_register src0 = translate_src_register(emit, &insn->Src[0]);
884a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   SVGA3dShaderDestToken temp = get_temp(emit);
885a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
886a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   /* FRC  TMP, -SRC */
887a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), temp, negate(src0)))
888a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return FALSE;
889a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
890a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   /* ADD DST, SRC, TMP */
891a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), dst, src0, src(temp)))
892a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return FALSE;
893a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
894a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   return TRUE;
895a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul}
896a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
897a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
8983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DIV instruction.
8993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DIV  DST.xy, SRC0, SRC1
9003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RCP  TMP.x, SRC1.xxxx
9023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RCP  TMP.y, SRC1.yyyy
9033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  DST.xy, SRC0, TMP
9043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_div(struct svga_shader_emitter *emit,
9063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9107d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
9127d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
9143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
9153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* For each enabled element, perform a RCP instruction.  Note that
9173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * RCP is scalar in SVGA3D:
9183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
9193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < 4; i++) {
9203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned channel = 1 << i;
9213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & channel) {
9223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* RCP  TMP.?, SRC1.???? */
923bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
924bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                          writemask(temp, channel),
9253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar(src1, i) ))
9263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
9273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
9283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
9293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
930bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   /* Vector mul:
9313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * MUL  DST, SRC0, TMP
9323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
9333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst, src0,
9343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( temp ) ))
9353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
9383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
9393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DP2 instruction.
9413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP2  DST, SRC1, SRC2
9423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  TMP, SRC1, SRC2
9443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    ADD  DST, TMP.xxxx, TMP.yyyy
9453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dp2(struct svga_shader_emitter *emit,
9473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9517d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
9537d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
9553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register temp_src0, temp_src1;
9563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MUL  TMP, SRC1, SRC2 */
9583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), temp, src0, src1 ))
9593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp_src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
9623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp_src1 = scalar(src( temp ), TGSI_SWIZZLE_Y);
9633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* ADD  DST, TMP.xxxx, TMP.yyyy */
9653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
9663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    temp_src0, temp_src1 ))
9673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
9703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
9713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DPH instruction.
9743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DPH  DST, SRC1, SRC2
9753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
9763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP3  TMP, SRC1, SRC2
9773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    ADD  DST, TMP, SRC2.wwww
9783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
9793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dph(struct svga_shader_emitter *emit,
9803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
9813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
9823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
9833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
9847d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
9853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
9867d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
9873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
9883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* DP3  TMP, SRC1, SRC2 */
9903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src1 ))
9913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = scalar(src1, TGSI_SWIZZLE_W);
9943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
9953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* ADD  DST, TMP, SRC2.wwww */
9963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
9973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( temp ), src1 ))
9983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
9993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate the following TGSI DST instruction.
10043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    NRM  DST, SRC
10053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * To the following SVGA3D instruction sequence.
10063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    DP3  TMP, SRC, SRC
10073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    RSQ  TMP, TMP
10083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *    MUL  DST, SRC, TMP
10093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
10103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_nrm(struct svga_shader_emitter *emit,
10113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
10123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
10157d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* DP3  TMP, SRC, SRC */
10193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_DP3 ), temp, src0, src0 ))
10203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* RSQ  TMP, TMP */
10233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_RSQ ), temp, src( temp )))
10243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MUL  DST, SRC, TMP */
10273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ), dst,
10283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src( temp )))
10293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean do_emit_sincos(struct svga_shader_emitter *emit,
10363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              SVGA3dShaderDestToken dst,
10373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              struct src_register src0)
10383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src0, TGSI_SWIZZLE_X);
1040bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   return submit_op1(emit, inst_token(SVGA3DOP_SINCOS), dst, src0);
10413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sincos(struct svga_shader_emitter *emit,
10443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn)
10453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
10487d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
10523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_XY), src0 ))
10533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP */
10563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src( temp ) ))
10573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
10633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SCS TMP SRC
10643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV DST TMP.yyyy
10653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
10663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sin(struct svga_shader_emitter *emit,
10673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
10683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
10717d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
10753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos(emit, writemask(temp, TGSI_WRITEMASK_Y), src0))
10763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src( temp ), TGSI_SWIZZLE_Y);
10793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP.yyyy */
10813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
10823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
10833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
10853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
10863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
10883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SCS TMP SRC
10893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV DST TMP.xxxx
10903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
10913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_cos(struct svga_shader_emitter *emit,
10923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
10933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
10943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
10953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
10967d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
10973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp = get_temp( emit );
10983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
10993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SCS TMP SRC */
11003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!do_emit_sincos( emit, writemask(temp, TGSI_WRITEMASK_X), src0 ))
11013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar(src( temp ), TGSI_SWIZZLE_X);
11043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV DST TMP.xxxx */
11063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src0 ))
11073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
11103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
11113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11125a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzerstatic boolean emit_ssg(struct svga_shader_emitter *emit,
11135a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                        const struct tgsi_full_instruction *insn )
11145a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer{
11155a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
11165a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   struct src_register src0 = translate_src_register(
11175a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      emit, &insn->Src[0] );
11185a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken temp0 = get_temp( emit );
11195a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   SVGA3dShaderDestToken temp1 = get_temp( emit );
11205a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   struct src_register zero, one;
11215a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11225a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (emit->unit == PIPE_SHADER_VERTEX) {
11235a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      /* SGN  DST, SRC0, TMP0, TMP1 */
11245a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return submit_op3( emit, inst_token( SVGA3DOP_SGN ), dst, src0,
11255a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                         src( temp0 ), src( temp1 ) );
11265a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   }
11275a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11285a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   zero = get_zero_immediate( emit );
11295a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   one = scalar( zero, TGSI_SWIZZLE_W );
11305a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   zero = scalar( zero, TGSI_SWIZZLE_X );
11315a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11325a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* CMP  TMP0, SRC0, one, zero */
11335a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
11345a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    writemask( temp0, dst.mask ), src0, one, zero ))
11355a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return FALSE;
11365a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11375a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* CMP  TMP1, negate(SRC0), negate(one), zero */
11385a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   if (!submit_op3( emit, inst_token( SVGA3DOP_CMP ),
11395a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    writemask( temp1, dst.mask ), negate( src0 ), negate( one ),
11405a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                    zero ))
11415a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return FALSE;
11425a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
11435a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   /* ADD  DST, TMP0, TMP1 */
11445a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   return submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst, src( temp0 ),
11455a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer                      src( temp1 ) );
11465a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer}
11473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
11493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ADD DST SRC0, negate(SRC0)
11503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
11513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_sub(struct svga_shader_emitter *emit,
11523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
11533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
11543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
11553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
11567d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
11573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
11587d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
11593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = negate(src1);
11613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ), dst,
11633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src1 ))
11643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
11653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
11673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
11683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
11703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_kil(struct svga_shader_emitter *emit,
11713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
11723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
11737d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &insn->Src[0];
11742b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   struct src_register src0, srcIn;
11752b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   /* is the W component tested in another position? */
11762b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   const boolean w_tested = (reg->Register.SwizzleW == reg->Register.SwizzleX ||
11772b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                             reg->Register.SwizzleW == reg->Register.SwizzleY ||
11782b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                             reg->Register.SwizzleW == reg->Register.SwizzleZ);
11792b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   const boolean special = (reg->Register.Absolute ||
11802b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.Negate ||
11812b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.Indirect ||
11822b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleX != 0 ||
11832b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleY != 1 ||
11842b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.SwizzleZ != 2 ||
11852b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                            reg->Register.File != TGSI_FILE_TEMPORARY);
11862b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   SVGA3dShaderDestToken temp;
11872b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
11882b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   src0 = srcIn = translate_src_register( emit, reg );
11892b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
11902b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (special || !w_tested) {
11912b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* need a temp reg */
11922b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      temp = get_temp( emit );
11932b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   }
11942b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
11952b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (special) {
11962b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* move the source into a temp register */
11972b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      submit_op1( emit, inst_token( SVGA3DOP_MOV ),
11982b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                  writemask( temp, TGSI_WRITEMASK_XYZ ),
11992b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                  src0 );
12003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      src0 = src( temp );
12023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
12033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12042b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   /* do the texkill (on the xyz components) */
12052b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), dst(src0) ))
12062b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      return FALSE;
12072b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12082b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   if (!w_tested) {
12092b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* need to emit a second texkill to test the W component */
12102b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* put src.wwww into temp register */
12112b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      if (!submit_op1(emit,
12122b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      inst_token( SVGA3DOP_MOV ),
12132b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      writemask( temp, TGSI_WRITEMASK_XYZ ),
12142b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul                      scalar(srcIn, TGSI_SWIZZLE_W)))
12152b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul         return FALSE;
12162b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12172b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      /* second texkill */
12182b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul      if (!submit_op0( emit, inst_token( SVGA3DOP_TEXKILL ), temp ))
12192b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul         return FALSE;
12202b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   }
12212b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul
12222b2a69e088416a18e3bb119ea1edb594b06e06feBrian Paul   return TRUE;
12233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
12243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* mesa state tracker always emits kilp as an unconditional
12273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * kil */
12283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_kilp(struct svga_shader_emitter *emit,
12293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
12303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
12313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
12323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
1233fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell   struct src_register one = scalar( get_zero_immediate( emit ),
1234fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                                     TGSI_SWIZZLE_W );
12353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( SVGA3DOP_TEXKILL );
12373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* texkill doesn't allow negation on the operand so lets move
12393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * negation of {1} to a temp register */
12403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp = get_temp( emit );
12413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), temp,
12423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    negate( one ) ))
12433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
12443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op0( emit, inst, temp );
12463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
12473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12480bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12490bd3a75de9002e73214cde883691da558db7bc70Brian Paul/**
12500bd3a75de9002e73214cde883691da558db7bc70Brian Paul * Test if r1 and r2 are the same register.
12510bd3a75de9002e73214cde883691da558db7bc70Brian Paul */
12520bd3a75de9002e73214cde883691da558db7bc70Brian Paulstatic boolean
12530bd3a75de9002e73214cde883691da558db7bc70Brian Paulsame_register(struct src_register r1, struct src_register r2)
12540bd3a75de9002e73214cde883691da558db7bc70Brian Paul{
12550bd3a75de9002e73214cde883691da558db7bc70Brian Paul   return (r1.base.num == r2.base.num &&
12560bd3a75de9002e73214cde883691da558db7bc70Brian Paul           r1.base.type_upper == r2.base.type_upper &&
12570bd3a75de9002e73214cde883691da558db7bc70Brian Paul           r1.base.type_lower == r2.base.type_lower);
12580bd3a75de9002e73214cde883691da558db7bc70Brian Paul}
12590bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12600bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12610bd3a75de9002e73214cde883691da558db7bc70Brian Paul
12623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Implement conditionals by initializing destination reg to 'fail',
12633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * then set predicate reg with UFOP_SETP, then move 'pass' to dest
12643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * based on predicate reg.
12653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
12663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SETP src0, cmp, src1  -- do this first to avoid aliasing problems.
12673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MOV dst, fail
1268bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul * MOV dst, pass, p0
12693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
12703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
12713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzemit_conditional(struct svga_shader_emitter *emit,
12723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 unsigned compare_func,
12733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 SVGA3dShaderDestToken dst,
12743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register src0,
12753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register src1,
12763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register pass,
12773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 struct src_register fail)
12783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
12793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
12803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken setp_token, mov_token;
12813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   setp_token = inst_token( SVGA3DOP_SETP );
12823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
12833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (compare_func) {
12843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_NEVER:
12853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
12863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst, fail );
12873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
12883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_LESS:
12893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_LT;
12903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
12913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_EQUAL:
12923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_EQ;
12933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
12943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_LEQUAL:
12953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_LE;
12963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
12973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_GREATER:
12983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_GT;
12993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_NOTEQUAL:
13013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMPC_NE;
13023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_GEQUAL:
13043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      setp_token.control = SVGA3DOPCOMP_GE;
13053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case PIPE_FUNC_ALWAYS:
13073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
13083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst, pass );
13093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
13103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
13110bd3a75de9002e73214cde883691da558db7bc70Brian Paul
13120bd3a75de9002e73214cde883691da558db7bc70Brian Paul   if (same_register(src(dst), pass)) {
13130bd3a75de9002e73214cde883691da558db7bc70Brian Paul      /* We'll get bad results if the dst and pass registers are the same
13140bd3a75de9002e73214cde883691da558db7bc70Brian Paul       * so use a temp register containing pass.
13150bd3a75de9002e73214cde883691da558db7bc70Brian Paul       */
13160bd3a75de9002e73214cde883691da558db7bc70Brian Paul      SVGA3dShaderDestToken temp = get_temp(emit);
13170bd3a75de9002e73214cde883691da558db7bc70Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass))
13180bd3a75de9002e73214cde883691da558db7bc70Brian Paul         return FALSE;
13190bd3a75de9002e73214cde883691da558db7bc70Brian Paul      pass = src(temp);
13200bd3a75de9002e73214cde883691da558db7bc70Brian Paul   }
13213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* SETP src0, COMPOP, src1 */
13233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, setp_token, pred_reg,
13243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src0, src1 ))
13253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   mov_token = inst_token( SVGA3DOP_MOV );
13283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV dst, fail */
13303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op1( emit, mov_token, dst,
13313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    fail ))
13323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* MOV dst, pass (predicated)
13353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    *
13363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * Note that the predicate reg (and possible modifiers) is passed
13373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * as the first source argument.
13383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   mov_token.predicated = 1;
13403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!submit_op2( emit, mov_token, dst,
13413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                    src( pred_reg ), pass ))
13423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
13433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
13453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
13463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
13493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzemit_select(struct svga_shader_emitter *emit,
13503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            unsigned compare_func,
13513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            SVGA3dShaderDestToken dst,
13523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            struct src_register src0,
13533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            struct src_register src1 )
13543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
13553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* There are some SVGA instructions which implement some selects
13563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * directly, but they are only available in the vertex shader.
13573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
13593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (compare_func) {
13603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_GEQUAL:
13613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src0, src1 );
13623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_LEQUAL:
13633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SGE ), dst, src1, src0 );
13643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_GREATER:
13653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src1, src0 );
13663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case PIPE_FUNC_LESS:
13673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return submit_op2( emit, inst_token( SVGA3DOP_SLT ), dst, src0, src1 );
13683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
13693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
13703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
13713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
13723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Otherwise, need to use the setp approach:
13753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
13763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   {
13773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register one, zero;
13783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* zero immediate is 0,0,0,1 */
13793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      zero = get_zero_immediate( emit );
13803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      one  = scalar( zero, TGSI_SWIZZLE_W );
13813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      zero = scalar( zero, TGSI_SWIZZLE_X );
13823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_conditional(
13843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit,
13853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         compare_func,
13863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         dst,
13873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src0,
13883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         src1,
13893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         one, zero);
13903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
13913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
13923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
13943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_select_op(struct svga_shader_emitter *emit,
13953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              unsigned compare,
13963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn)
13973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
13983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
13993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
14007d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
14013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
14027d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
1403bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
14043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_select( emit, compare, dst, src0, src1 );
14053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
14063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1408d594f72e1615cda47b838046df4590316da3d1a9Brian Paul/**
1409d594f72e1615cda47b838046df4590316da3d1a9Brian Paul * Translate TGSI CMP instruction.
1410d594f72e1615cda47b838046df4590316da3d1a9Brian Paul */
1411d594f72e1615cda47b838046df4590316da3d1a9Brian Paulstatic boolean
1412d594f72e1615cda47b838046df4590316da3d1a9Brian Paulemit_cmp(struct svga_shader_emitter *emit,
1413d594f72e1615cda47b838046df4590316da3d1a9Brian Paul         const struct tgsi_full_instruction *insn)
1414d594f72e1615cda47b838046df4590316da3d1a9Brian Paul{
1415d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
1416d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src0 =
1417d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[0] );
1418d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src1 =
1419d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[1] );
1420d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   const struct src_register src2 =
1421d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      translate_src_register(emit, &insn->Src[2] );
1422d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1423d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
1424d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      struct src_register zero =
1425d594f72e1615cda47b838046df4590316da3d1a9Brian Paul         scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X);
1426d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      /* We used to simulate CMP with SLT+LRP.  But that didn't work when
1427d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * src1 or src2 was Inf/NaN.  In particular, GLSL sqrt(0) failed
1428d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * because it involves a CMP to handle the 0 case.
1429d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       * Use a conditional expression instead.
1430d594f72e1615cda47b838046df4590316da3d1a9Brian Paul       */
1431d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      return emit_conditional(emit, PIPE_FUNC_LESS, dst,
1432d594f72e1615cda47b838046df4590316da3d1a9Brian Paul                              src0, zero, src1, src2);
1433d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   }
1434d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   else {
1435d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      assert(emit->unit == PIPE_SHADER_FRAGMENT);
1436d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1437d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      /* CMP  DST, SRC0, SRC2, SRC1 */
1438d594f72e1615cda47b838046df4590316da3d1a9Brian Paul      return submit_op3( emit, inst_token( SVGA3DOP_CMP ), dst,
1439d594f72e1615cda47b838046df4590316da3d1a9Brian Paul                         src0, src2, src1);
1440d594f72e1615cda47b838046df4590316da3d1a9Brian Paul   }
1441d594f72e1615cda47b838046df4590316da3d1a9Brian Paul}
1442d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
1443d594f72e1615cda47b838046df4590316da3d1a9Brian Paul
14443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate texture instructions to SVGA3D representation.
14453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
14463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_tex2(struct svga_shader_emitter *emit,
14473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn,
14483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         SVGA3dShaderDestToken dst )
14493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
14503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
1451a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   struct src_register texcoord;
1452a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   struct src_register sampler;
1453a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   SVGA3dShaderDestToken tmp;
1454bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
14553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst.value = 0;
14563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
14573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
14583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
145984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
14613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
146284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      inst.control = SVGA3DOPCONT_PROJECT;
14643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
14653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
146684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEX;
14673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      inst.control = SVGA3DOPCONT_BIAS;
14683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
146984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   case TGSI_OPCODE_TXL:
147084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      inst.op = SVGA3DOP_TEXLDL;
147184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      break;
14723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
14733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
14743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
14753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
14763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1477a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   texcoord = translate_src_register( emit, &insn->Src[0] );
1478a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   sampler = translate_src_register( emit, &insn->Src[1] );
14793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1480a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
1481a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell       emit->dynamic_branching_level > 0)
1482a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      tmp = get_temp( emit );
1483a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1484a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   /* Can't do mipmapping inside dynamic branch constructs.  Force LOD
1485a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    * zero in that case.
1486a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    */
14870748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   if (emit->dynamic_branching_level > 0 &&
148884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell       inst.op == SVGA3DOP_TEX &&
14890748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
1490a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      struct src_register zero = get_zero_immediate( emit );
1491a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1492a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      /* MOV  tmp, texcoord */
1493a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      if (!submit_op1( emit,
1494a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       inst_token( SVGA3DOP_MOV ),
1495a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       tmp,
1496a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       texcoord ))
1497a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell         return FALSE;
1498a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1499a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      /* MOV  tmp.w, zero */
1500bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1( emit,
1501a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       inst_token( SVGA3DOP_MOV ),
1502bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       writemask( tmp, TGSI_WRITEMASK_W ),
1503a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       scalar( zero, TGSI_SWIZZLE_X )))
1504a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell         return FALSE;
1505bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
1506a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      texcoord = src( tmp );
1507a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      inst.op = SVGA3DOP_TEXLDL;
1508a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   }
1509a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1510a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   /* Explicit normalization of texcoords:
1511a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell    */
1512a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
1513a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
15143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* MUL  tmp, SRC0, WH */
15163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
1517a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell                       tmp, texcoord, wh ))
15183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
1519a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1520a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      texcoord = src( tmp );
15213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
15223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1523a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   return submit_op2( emit, inst, dst, texcoord, sampler );
15243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
15253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Translate texture instructions to SVGA3D representation.
15303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
153184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwellstatic boolean emit_tex4(struct svga_shader_emitter *emit,
15323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn,
15333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         SVGA3dShaderDestToken dst )
15343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
15353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
153684d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register texcoord;
153784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register ddx;
153884d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register ddy;
153984d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   struct src_register sampler;
154084d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell
154184d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   texcoord = translate_src_register( emit, &insn->Src[0] );
154284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   ddx      = translate_src_register( emit, &insn->Src[1] );
154384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   ddy      = translate_src_register( emit, &insn->Src[2] );
154484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   sampler  = translate_src_register( emit, &insn->Src[3] );
15453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst.value = 0;
15473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
1549bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   case TGSI_OPCODE_TXD:
1550a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell      inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
15513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
155284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   default:
155384d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      assert(0);
155484d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      return FALSE;
15553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
15563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
155784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
15583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
15593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
15619bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul/**
15629bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul * Emit texture swizzle code.
15639bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul */
15649bd15aef865352b9234fedae76617fc51c71e6d5Brian Paulstatic boolean emit_tex_swizzle( struct svga_shader_emitter *emit,
15659bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 SVGA3dShaderDestToken dst,
15669bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 struct src_register src,
15679bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_x,
15689bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_y,
15699bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_z,
15709bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                                 unsigned swizzle_w)
15719bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul{
15729bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   const unsigned swizzleIn[4] = {swizzle_x, swizzle_y, swizzle_z, swizzle_w};
15739bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   unsigned srcSwizzle[4];
15749bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   unsigned srcWritemask = 0x0, zeroWritemask = 0x0, oneWritemask = 0x0;
15759bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   int i;
15769bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
15779bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* build writemasks and srcSwizzle terms */
15789bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   for (i = 0; i < 4; i++) {
15799bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      if (swizzleIn[i] == PIPE_SWIZZLE_ZERO) {
15809bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
15819bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         zeroWritemask |= (1 << i);
15829bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
15839bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else if (swizzleIn[i] == PIPE_SWIZZLE_ONE) {
15849bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = TGSI_SWIZZLE_X + i;
15859bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         oneWritemask |= (1 << i);
15869bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
15879bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else {
15889bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcSwizzle[i] = swizzleIn[i];
15899bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         srcWritemask |= (1 << i);
15909bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
15919bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
15929bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
15939bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write x/y/z/w comps */
15949bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & srcWritemask) {
1595bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1(emit,
1596bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token(SVGA3DOP_MOV),
1597bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      writemask(dst, srcWritemask),
15989bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      swizzle(src,
15999bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[0],
16009bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[1],
16019bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[2],
16029bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                              srcSwizzle[3])))
16039bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16049bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16059bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16069bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write 0 comps */
16079bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & zeroWritemask) {
1608bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1(emit,
1609bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token(SVGA3DOP_MOV),
1610bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      writemask(dst, zeroWritemask),
16119bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_X)))
16129bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16139bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16149bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16159bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* write 1 comps */
16169bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   if (dst.mask & oneWritemask) {
1617bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1(emit,
1618bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token(SVGA3DOP_MOV),
1619bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      writemask(dst, oneWritemask),
16209bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      scalar(get_zero_immediate(emit), TGSI_SWIZZLE_W)))
16219bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         return FALSE;
16229bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
16239bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16249bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   return TRUE;
16259bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul}
16269bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16279bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_tex(struct svga_shader_emitter *emit,
16293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn )
16303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1631bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   SVGA3dShaderDestToken dst =
16323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      translate_dst_register( emit, insn, 0 );
16333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
16347d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
16353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 =
16367d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[1] );
16373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken tex_result;
16399bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   const unsigned unit = src1.base.num;
16403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* check for shadow samplers */
16429bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   boolean compare = (emit->key.fkey.tex[unit].compare_mode ==
16433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      PIPE_TEX_COMPARE_R_TO_TEXTURE);
16443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16459bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   /* texture swizzle */
16469bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   boolean swizzle = (emit->key.fkey.tex[unit].swizzle_r != PIPE_SWIZZLE_RED ||
16479bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_g != PIPE_SWIZZLE_GREEN ||
16489bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_b != PIPE_SWIZZLE_BLUE ||
16499bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                      emit->key.fkey.tex[unit].swizzle_a != PIPE_SWIZZLE_ALPHA);
16503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16518009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   boolean saturate = insn->Instruction.Saturate != TGSI_SAT_NONE;
16528009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul
16538009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   /* If doing compare processing or tex swizzle or saturation, we need to put
16548009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul    * the fetched color into a temporary so it can be used as a source later on.
16553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
16568009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   if (compare || swizzle || saturate) {
16573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tex_result = get_temp( emit );
16583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
16603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tex_result = dst;
16613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch(insn->Instruction.Opcode) {
16643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
16653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
16663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
166784d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell   case TGSI_OPCODE_TXL:
16683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_tex2( emit, insn, tex_result ))
16693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
16703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
16713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXD:
167284d41f3c7f636d182c659ab85a4449df50c43bc8Keith Whitwell      if (!emit_tex4( emit, insn, tex_result ))
16733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
16743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      break;
16753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
16763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
16773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
16783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
16793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (compare) {
16809bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      SVGA3dShaderDestToken dst2;
16819bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16828009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      if (swizzle || saturate)
16839bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         dst2 = tex_result;
16849bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      else
16859bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         dst2 = dst;
16869bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
16877384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      if (dst.mask & TGSI_WRITEMASK_XYZ) {
16887384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
16899bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         /* When sampling a depth texture, the result of the comparison is in
16909bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul          * the Y component.
16919bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul          */
16927384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
16937d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         struct src_register r_coord;
16947d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
16957d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         if (insn->Instruction.Opcode == TGSI_OPCODE_TXP) {
16967d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            /* Divide texcoord R by Q */
16977d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
16987d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
16997d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src0, TGSI_SWIZZLE_W) ))
17007d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul               return FALSE;
17017d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
17027d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
17037d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             writemask(src0_zdivw, TGSI_WRITEMASK_X),
17047d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src0, TGSI_SWIZZLE_Z),
17057d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                             scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
17067d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul               return FALSE;
17077d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul
17087d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            r_coord = scalar(src(src0_zdivw), TGSI_SWIZZLE_X);
17097d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         }
17107d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         else {
17117d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul            r_coord = scalar(src0, TGSI_SWIZZLE_Z);
17127d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         }
17137384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17147d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         /* Compare texture sample value against R component of texcoord */
17157d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul         if (!emit_select(emit,
17167d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          emit->key.fkey.tex[unit].compare_func,
17177d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          writemask( dst2, TGSI_WRITEMASK_XYZ ),
17187d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          r_coord,
17197d09df0cbc7e4524919a025cdd506b29e2d8b4f1Brian Paul                          tex_src_x))
17207384cdf651dc69098f4d988dd3b217879ec63336José Fonseca            return FALSE;
17217384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      }
17223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17237384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      if (dst.mask & TGSI_WRITEMASK_W) {
17247384cdf651dc69098f4d988dd3b217879ec63336José Fonseca         struct src_register one =
17257384cdf651dc69098f4d988dd3b217879ec63336José Fonseca            scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
17267384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17277384cdf651dc69098f4d988dd3b217879ec63336José Fonseca        if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
17289bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                         writemask( dst2, TGSI_WRITEMASK_W ),
17297384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                         one ))
17307384cdf651dc69098f4d988dd3b217879ec63336José Fonseca           return FALSE;
17317384cdf651dc69098f4d988dd3b217879ec63336José Fonseca      }
17329bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul   }
17337384cdf651dc69098f4d988dd3b217879ec63336José Fonseca
17348009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   if (saturate && !swizzle) {
17358009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      /* MOV_SAT real_dst, dst */
17368009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst, src(tex_result) ))
17378009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul         return FALSE;
17388009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   }
17398009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul   else if (swizzle) {
17408009fca501a021cbaf9b25e01ff3a7793cc2c6cbBrian Paul      /* swizzle from tex_result to dst (handles saturation too, if any) */
17419bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      emit_tex_swizzle(emit,
17429bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       dst, src(tex_result),
17439bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_r,
17449bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_g,
17459bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_b,
17469bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul                       emit->key.fkey.tex[unit].swizzle_a);
17473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
17489bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
17493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
17503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_bgnloop2( struct svga_shader_emitter *emit,
17533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn )
17543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_LOOP );
17563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
17573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register const_int = get_loop_const( emit );
17583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1759a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level++;
1760a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
17613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, inst ) &&
17623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, loop_reg ) &&
17633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, const_int ) );
17643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_endloop2( struct svga_shader_emitter *emit,
17673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              const struct tgsi_full_instruction *insn )
17683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
1770a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
1771a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   emit->dynamic_branching_level--;
1772a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
17733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_instruction( emit, inst );
17743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_brk( struct svga_shader_emitter *emit,
17773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn )
17783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_BREAK );
17803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_instruction( emit, inst );
17813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_scalar_op1( struct svga_shader_emitter *emit,
17843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                unsigned opcode,
17853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                const struct tgsi_full_instruction *insn )
17863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
17873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
17883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
17893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src;
17903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( opcode );
17923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
17937d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   src = translate_src_register( emit, &insn->Src[0] );
17943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src = scalar( src, TGSI_SWIZZLE_X );
17953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst, dst, src );
17973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
17983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
17993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_simple_instruction(struct svga_shader_emitter *emit,
18013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       unsigned opcode,
18023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       const struct tgsi_full_instruction *insn )
18033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
18047d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *src = insn->Src;
18053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
18063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
18073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( opcode );
18093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
18103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.NumSrcRegs) {
18123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 0:
18133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op0( emit, inst, dst );
18143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 1:
18153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst, dst,
18163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ));
18173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 2:
18183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op2( emit, inst, dst,
18193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ),
18203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[1] ) );
18213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case 3:
18223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op3( emit, inst, dst,
18233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[0] ),
18243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[1] ),
18253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         translate_src_register( emit, &src[2] ) );
18263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default:
18273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(0);
18283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
18293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
18303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
18313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18320748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18330748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwellstatic boolean emit_deriv(struct svga_shader_emitter *emit,
18340748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                          const struct tgsi_full_instruction *insn )
18350748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell{
18360748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   if (emit->dynamic_branching_level > 0 &&
1837bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul       insn->Src[0].Register.File == TGSI_FILE_TEMPORARY)
18380748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   {
18390748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      struct src_register zero = get_zero_immediate( emit );
1840bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      SVGA3dShaderDestToken dst =
18410748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         translate_dst_register( emit, insn, 0 );
18420748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18430748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      /* Deriv opcodes not valid inside dynamic branching, workaround
18440748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       * by zeroing out the destination.
18450748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       */
1846bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1(emit,
1847bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token( SVGA3DOP_MOV ),
18480748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                      dst,
18490748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell                      scalar(zero, TGSI_SWIZZLE_X)))
18500748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         return FALSE;
1851bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
18520748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      return TRUE;
18530748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   }
18540748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   else {
18550748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      unsigned opcode;
1856f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      const struct tgsi_full_src_register *reg = &insn->Src[0];
1857f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      SVGA3dShaderInstToken inst;
1858f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      SVGA3dShaderDestToken dst;
1859f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      struct src_register src0;
18600748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18610748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      switch (insn->Instruction.Opcode) {
18620748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      case TGSI_OPCODE_DDX:
18630748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         opcode = SVGA3DOP_DSX;
18640748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         break;
18650748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      case TGSI_OPCODE_DDY:
18660748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         opcode = SVGA3DOP_DSY;
18670748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         break;
18680748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      default:
18690748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell         return FALSE;
18700748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      }
18710748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
1872f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      inst = inst_token( opcode );
1873f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      dst = translate_dst_register( emit, insn, 0 );
1874f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      src0 = translate_src_register( emit, reg );
1875f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1876f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      /* We cannot use negate or abs on source to dsx/dsy instruction.
1877f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca       */
1878f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      if (reg->Register.Absolute ||
1879f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca          reg->Register.Negate) {
1880f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca         SVGA3dShaderDestToken temp = get_temp( emit );
1881f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1882f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca         if (!emit_repl( emit, temp, &src0 ))
1883f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca            return FALSE;
1884f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      }
1885f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca
1886f9b48678463e926571ab5e547bb5ced5f4a6896aJosé Fonseca      return submit_op1( emit, inst, dst, src0 );
18870748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   }
18880748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell}
18890748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
18903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_arl(struct svga_shader_emitter *emit,
18913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
18923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
18933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ++emit->current_arl;
18940742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   if (emit->unit == PIPE_SHADER_FRAGMENT) {
18950742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      /* MOVA not present in pixel shader instruction set.
18960742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * Ignore this instruction altogether since it is
18970742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * only used for loop counters -- and for that
18980742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       * we reference aL directly.
18990742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol       */
19000742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol      return TRUE;
19010742e0b3767072fe664ca9f39fc31d86d8d314edMichal Krol   }
19023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga_arl_needs_adjustment( emit )) {
19033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_fake_arl( emit, insn );
19043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   } else {
19053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* no need to adjust, just emit straight arl */
19063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_MOVA, insn);
19073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
19093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_pow(struct svga_shader_emitter *emit,
19113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
19123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
19133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
19143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 = translate_src_register(
19157d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
19163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src1 = translate_src_register(
19177d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
19183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_tmp = FALSE;
1919bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
19203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* POW can only output to a temporary */
19215b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   if (insn->Dst[0].Register.File != TGSI_FILE_TEMPORARY)
19223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_tmp = TRUE;
1923bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
19243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* POW src1 must not be the same register as dst */
19253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (alias_src_dst( src1, dst ))
19263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_tmp = TRUE;
19273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* it's a scalar op */
19293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar( src0, TGSI_SWIZZLE_X );
19303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src1 = scalar( src1, TGSI_SWIZZLE_X );
19313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_tmp) {
19333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = writemask(get_temp( emit ), TGSI_WRITEMASK_X );
19343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_POW ), tmp, src0, src1))
19363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, scalar(src(tmp), 0) );
1939bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   }
19403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
19413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op2(emit, inst_token( SVGA3DOP_POW ), dst, src0, src1);
19423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
19443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_xpd(struct svga_shader_emitter *emit,
19463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
19473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
19483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
19493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
19507d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
19513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
19527d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
19533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean need_dst_tmp = FALSE;
19543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* XPD can only output to a temporary */
1956bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP)
19573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_dst_tmp = TRUE;
19583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* The dst reg must not be the same as src0 or src1*/
19603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (alias_src_dst(src0, dst) ||
19613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       alias_src_dst(src1, dst))
19623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      need_dst_tmp = TRUE;
19633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (need_dst_tmp) {
19653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
19663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Obey DX9 restrictions on mask:
19683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
19693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tmp.mask = dst.mask & TGSI_WRITEMASK_XYZ;
19703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), tmp, src0, src1))
19723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1(emit, inst_token( SVGA3DOP_MOV ), dst, src( tmp )))
19753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
1976bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul   }
19773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
19783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2(emit, inst_token( SVGA3DOP_CRS ), dst, src0, src1))
19793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to emit 1.0 to dst.w?
19833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
19843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
19853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
19863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1987bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op1(emit,
1988bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token( SVGA3DOP_MOV ),
19893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      writemask(dst, TGSI_WRITEMASK_W),
19903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                      zero))
19913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
19923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
19933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
19953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
19963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_lrp(struct svga_shader_emitter *emit,
19993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
20003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
20013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
20023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src0 = translate_src_register(
20037d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[0] );
20043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src1 = translate_src_register(
20057d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[1] );
20063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct src_register src2 = translate_src_register(
20077d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      emit, &insn->Src[2] );
20083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
200915c3e21097ba6d410daaff525eb4eeeb5e1e481aJosé Fonseca   return submit_lrp(emit, dst, src0, src1, src2);
20103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
20113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_dst_insn(struct svga_shader_emitter *emit,
20143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn )
20153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
20163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
20173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* SVGA/DX9 has a DST instruction, but only for vertex shaders:
20183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_DST, insn);
20203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
20213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
20223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* result[0] = 1    * 1;
20243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[1] = a[1] * b[1];
20253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[2] = a[2] * 1;
20263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * result[3] = 1    * b[3];
20273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
20303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp;
20313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src0 = translate_src_register(
20327d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[0] );
20333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src1 = translate_src_register(
20347d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[1] );
20353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
20363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      boolean need_tmp = FALSE;
20373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (SVGA3dShaderGetRegType(dst.value) != SVGA3DREG_TEMP ||
20393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          alias_src_dst(src0, dst) ||
20403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          alias_src_dst(src1, dst))
20413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         need_tmp = TRUE;
20423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (need_tmp) {
20443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         tmp = get_temp( emit );
20453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
20473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         tmp = dst;
20483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.xw = 1.0
20513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_XW) {
2053bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_XW ),
20553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar( zero, 3 )))
20563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
2058bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
20593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.yz = src0
20603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_YZ) {
2062bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_YZ ),
20643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src0))
20653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.yw = tmp * src1
20693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (tmp.mask & TGSI_WRITEMASK_YW) {
2071bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
20723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_YW ),
20733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src(tmp),
20743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src1))
20753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
20763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
20773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* dst = tmp
20793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
20803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (need_tmp) {
2081bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
20823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          dst,
20833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src(tmp)))
20843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
2085bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      }
20863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2087bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
20883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
20893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
20903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
20923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_exp(struct svga_shader_emitter *emit,
20933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
20943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
20953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
20963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
20977d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
20983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
20993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken fraction;
21003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Y)
21023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fraction = dst;
21033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else if (dst.mask & TGSI_WRITEMASK_X)
21043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fraction = get_temp( emit );
21053f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   else
21063f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee      fraction.value = 0;
21073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If y is being written, fill it with src0 - floor(src0).
21093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XY) {
21113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
21123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( fraction, TGSI_WRITEMASK_Y ),
21133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0 ))
21143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If x is being written, fill it with 2 ^ floor(src0).
21183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_X) {
21203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
21217384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_X ),
21223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0,
21233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
21243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
21277384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_X ),
21283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
21293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_Y))
21323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, fraction );
21333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If z is being written, fill it with 2 ^ src0 (partial precision).
21363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Z) {
21383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
21397384cdf651dc69098f4d988dd3b217879ec63336José Fonseca                       writemask( dst, TGSI_WRITEMASK_Z ),
21403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src0 ) )
21413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If w is being written, fill it with one.
21453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
21463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
21473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
21483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(dst, TGSI_WRITEMASK_W),
21493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( zero, TGSI_SWIZZLE_W ) ))
21503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
21513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
21543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
21553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_lit(struct svga_shader_emitter *emit,
21573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             const struct tgsi_full_instruction *insn )
21583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
21593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
21603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* SVGA/DX9 has a LIT instruction, but only for vertex shaders:
21613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
21623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_simple_instruction(emit, SVGA3DOP_LIT, insn);
21633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
21643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
21653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* D3D vs. GL semantics can be fairly easily accomodated by
21663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * variations on this sequence.
21673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * GL:
21693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.y = src.x
21703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.z = pow(src.y,src.w)
21713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   p0 = src0.xxxx > 0
21723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   result = zero.wxxw
21733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   (p0) result.yz = tmp
21743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * D3D:
21763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.y = src.x
21773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   tmp.z = pow(src.y,src.w)
21783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   p0 = src0.xxyy > 0
21793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   result = zero.wxxw
21803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   (p0) result.yz = tmp
21813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
21823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Will implement the GL version for now.
21833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
21843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
21853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
21863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      const struct src_register src0 = translate_src_register(
21877d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         emit, &insn->Src[0] );
21883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register zero = get_zero_immediate( emit );
21893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp = pow(src.y, src.w)
21913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
21923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Z) {
2193bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op2(emit, inst_token( SVGA3DOP_POW ),
2194bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                         tmp,
2195bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                         scalar(src0, 1),
21963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         scalar(src0, 3)))
21973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
21983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
21993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* tmp.y = src.x
22013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Y) {
2203bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
22043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask(tmp, TGSI_WRITEMASK_Y ),
22053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          scalar(src0, 0)))
22063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
22073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
2208bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
22093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Can't quite do this with emit conditional due to the extra
22103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * writemask on the predicated mov:
22113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
22123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      {
22133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         SVGA3dShaderDestToken pred_reg = dst_register( SVGA3DREG_PREDICATE, 0 );
22143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         SVGA3dShaderInstToken setp_token, mov_token;
22153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         struct src_register predsrc;
22163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         setp_token = inst_token( SVGA3DOP_SETP );
22183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         mov_token = inst_token( SVGA3DOP_MOV );
22193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         setp_token.control = SVGA3DOPCOMP_GT;
22213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* D3D vs GL semantics:
22233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          */
22243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (0)
22253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            predsrc = swizzle(src0, 0, 0, 1, 1); /* D3D */
22263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         else
22273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            predsrc = swizzle(src0, 0, 0, 0, 0); /* GL */
22283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* SETP src0.xxyy, GT, {0}.x */
22303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2( emit, setp_token, pred_reg,
2231bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                          predsrc,
22323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          swizzle(zero, 0, 0, 0, 0) ))
22333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
2234bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
22353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* MOV dst, fail */
22363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), dst,
22373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          swizzle(zero, 3, 0, 0, 3 )))
22383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz             return FALSE;
22393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         /* MOV dst.yz, tmp (predicated)
22413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          *
22423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          * Note that the predicate reg (and possible modifiers) is passed
22433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          * as the first source argument.
22443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          */
22453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (dst.mask & TGSI_WRITEMASK_YZ) {
22463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            mov_token.predicated = 1;
22473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            if (!submit_op2( emit, mov_token,
22483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             writemask(dst, TGSI_WRITEMASK_YZ),
22493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             src( pred_reg ), src( tmp ) ))
22503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               return FALSE;
22513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
22523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
22533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
22543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
22563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
22573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ex2( struct svga_shader_emitter *emit,
22603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         const struct tgsi_full_instruction *insn )
22613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
22623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken inst;
22633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst;
22643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0;
22653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   inst = inst_token( SVGA3DOP_EXP );
22673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   dst = translate_dst_register( emit, insn, 0 );
22687d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   src0 = translate_src_register( emit, &insn->Src[0] );
22693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   src0 = scalar( src0, TGSI_SWIZZLE_X );
22703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask != TGSI_WRITEMASK_XYZW) {
22723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken tmp = get_temp( emit );
22733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst, tmp, src0 ))
22753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
22763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
22783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         dst,
22793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         scalar( src( tmp ), TGSI_SWIZZLE_X ) );
22803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
22813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return submit_op1( emit, inst, dst, src0 );
22833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
22843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_log(struct svga_shader_emitter *emit,
22873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        const struct tgsi_full_instruction *insn)
22883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
22893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken dst = translate_dst_register( emit, insn, 0 );
22903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register src0 =
22917d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      translate_src_register( emit, &insn->Src[0] );
22923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register zero = get_zero_immediate( emit );
22933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken abs_tmp;
22943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register abs_src0;
22953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken log2_abs;
22963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22973f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   abs_tmp.value = 0;
22983f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee
22993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_Z)
23003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      log2_abs = dst;
23013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else if (dst.mask & TGSI_WRITEMASK_XY)
23023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      log2_abs = get_temp( emit );
23033f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee   else
23043f7af8440568d083dd9bb1370b785b60f5a141f0Vinson Lee      log2_abs.value = 0;
23053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If z is being written, fill it with log2( abs( src0 ) ).
23073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
23083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XYZ) {
23093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!src0.base.srcMod || src0.base.srcMod == SVGA3DSRCMOD_ABS)
23103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_src0 = src0;
23113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
23123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_tmp = get_temp( emit );
23133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
23153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          abs_tmp,
23163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src0 ) )
23173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         abs_src0 = src( abs_tmp );
23203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
23213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      abs_src0 = absolute( scalar( abs_src0, TGSI_SWIZZLE_X ) );
23233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_LOG ),
23253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( log2_abs, TGSI_WRITEMASK_Z ),
23263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       abs_src0 ) )
23273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XY) {
23313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken floor_log2;
23323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_X)
23343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         floor_log2 = dst;
23353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else
23363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         floor_log2 = get_temp( emit );
23373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* If x is being written, fill it with floor( log2( abs( src0 ) ) ).
23393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
23403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_FRC ),
23413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( floor_log2, TGSI_WRITEMASK_X ),
23423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ) ) )
23433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
23463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask( floor_log2, TGSI_WRITEMASK_X ),
23473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( src( log2_abs ), TGSI_SWIZZLE_Z ),
23483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       negate( src( floor_log2 ) ) ) )
23493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* If y is being written, fill it with
23523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * abs ( src0 ) / ( 2 ^ floor( log2( abs( src0 ) ) ) ).
23533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
23543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (dst.mask & TGSI_WRITEMASK_Y) {
23553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
23563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask( dst, TGSI_WRITEMASK_Y ),
23573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          negate( scalar( src( floor_log2 ),
23583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                          TGSI_SWIZZLE_X ) ) ) )
23593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
23623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          writemask( dst, TGSI_WRITEMASK_Y ),
23633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          src( dst ),
23643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          abs_src0 ) )
23653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
23663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
23673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_X))
23693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, floor_log2 );
23703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!(dst.mask & TGSI_WRITEMASK_Z))
23723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         release_temp( emit, log2_abs );
23733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_XYZ && src0.base.srcMod &&
23763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       src0.base.srcMod != SVGA3DSRCMOD_ABS)
23773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      release_temp( emit, abs_tmp );
23783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* If w is being written, fill it with one.
23803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
23813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (dst.mask & TGSI_WRITEMASK_W) {
23823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
23833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       writemask(dst, TGSI_WRITEMASK_W),
23843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar( zero, TGSI_SWIZZLE_W ) ))
23853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
23863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
23873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
23893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
23903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
239230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul/**
23931ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul * Translate TGSI TRUNC or ROUND instruction.
239430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul * We need to truncate toward zero. Ex: trunc(-1.9) = -1
239530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul * Different approaches are needed for VS versus PS.
239630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul */
239730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paulstatic boolean
23981ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paulemit_trunc_round(struct svga_shader_emitter *emit,
23991ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                 const struct tgsi_full_instruction *insn,
24001ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                 boolean round)
240130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul{
240230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   SVGA3dShaderDestToken dst = translate_dst_register(emit, insn, 0);
240330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   const struct src_register src0 =
240430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      translate_src_register(emit, &insn->Src[0] );
240530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   SVGA3dShaderDestToken t1 = get_temp(emit);
240630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24071ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   if (round) {
24081ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      SVGA3dShaderDestToken t0 = get_temp(emit);
24091ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      struct src_register half = get_half_immediate(emit);
241030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24111ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t0 = abs(src0) + 0.5 */
24121ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t0,
24131ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      absolute(src0), half))
24141ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24151ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24161ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = fract(t0) */
24171ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, src(t0)))
24181ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24191ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24201ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = t0 - t1 */
24211ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, src(t0),
24221ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      negate(src(t1))))
24231ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24241ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   }
24251ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   else {
24261ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* trunc */
24271ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24281ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = fract(abs(src0)) */
24291ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op1(emit, inst_token(SVGA3DOP_FRC), t1, absolute(src0)))
24301ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24311ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
24321ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* t1 = abs(src0) - t1 */
24331ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_ADD), t1, absolute(src0),
24341ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul                      negate(src(t1))))
24351ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul         return FALSE;
24361ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   }
243730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
243830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   /*
243930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul    * Now we need to multiply t1 by the sign of the original value.
244030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   */
244130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   if (emit->unit == PIPE_SHADER_VERTEX) {
244230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* For VS: use SGN instruction */
24431ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      /* Need two extra/dummy registers: */
244430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      SVGA3dShaderDestToken t2 = get_temp(emit), t3 = get_temp(emit),
244530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         t4 = get_temp(emit);
244630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
244730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* t2 = sign(src0) */
244830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      if (!submit_op3(emit, inst_token(SVGA3DOP_SGN), t2, src0,
244930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul                      src(t3), src(t4)))
245030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         return FALSE;
245130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
245230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* dst = t1 * t2 */
245330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      if (!submit_op2(emit, inst_token(SVGA3DOP_MUL), dst, src(t1), src(t2)))
245430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul         return FALSE;
245530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   }
245630f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   else {
245730f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      /* For FS: Use CMP instruction */
245830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul      return submit_op3(emit, inst_token( SVGA3DOP_CMP ), dst,
245930f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul                        src0, src(t1), negate(src(t1)));
246030f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   }
246130f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
246230f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   return TRUE;
246330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul}
246430f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
246530f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
24663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_bgnsub( struct svga_shader_emitter *emit,
24673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           unsigned position,
24683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn )
24693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
24703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
24713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Note that we've finished the main function and are now emitting
24733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * subroutines.  This affects how we terminate the generated
24743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * shader.
24753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
24763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->in_main_func = FALSE;
2477bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
24783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->nr_labels; i++) {
24793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->label[i] == position) {
24803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return (emit_instruction( emit, inst_token( SVGA3DOP_RET ) ) &&
24813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 emit_instruction( emit, inst_token( SVGA3DOP_LABEL ) ) &&
24823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                 emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
24833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
24843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
24853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(0);
24873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
24883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
24893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_call( struct svga_shader_emitter *emit,
24913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           const struct tgsi_full_instruction *insn )
24923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
24937d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   unsigned position = insn->Label.Label;
24943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
2495bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
24963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->nr_labels; i++) {
2497bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (emit->label[i] == position)
24983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
24993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->nr_labels == Elements(emit->label))
25023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
25033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (i == emit->nr_labels) {
25053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->label[i] = position;
25063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->nr_labels++;
25073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit_instruction( emit, inst_token( SVGA3DOP_CALL ) ) &&
25103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz           emit_src( emit, src_register( SVGA3DREG_LABEL, i )));
25113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
25123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_end( struct svga_shader_emitter *emit )
25153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
25163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
25173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_vs_postamble( emit );
25183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
25203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_ps_postamble( emit );
25213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
25223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
25233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_emit_instruction( struct svga_shader_emitter *emit,
25273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      unsigned position,
25283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      const struct tgsi_full_instruction *insn )
25293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
25303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   switch (insn->Instruction.Opcode) {
25313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ARL:
25333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_arl( emit, insn );
25343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TEX:
25363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXB:
25373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXP:
25383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXL:
25393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_TXD:
25403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_tex( emit, insn );
25413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25420748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   case TGSI_OPCODE_DDX:
25430748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell   case TGSI_OPCODE_DDY:
25440748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell      return emit_deriv( emit, insn );
25450748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell
25463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BGNSUB:
25473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_bgnsub( emit, position, insn );
25483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDSUB:
25503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
25513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CAL:
25533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_call( emit, insn );
25543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_FLR:
25563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_floor( emit, insn );
25573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
255830f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul   case TGSI_OPCODE_TRUNC:
25591ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      return emit_trunc_round( emit, insn, FALSE );
25601ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul
25611ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul   case TGSI_OPCODE_ROUND:
25621ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul      return emit_trunc_round( emit, insn, TRUE );
256330f8575fde673f2279aee1fbe89e7df07cb81081Brian Paul
2564a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul   case TGSI_OPCODE_CEIL:
2565a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul      return emit_ceil( emit, insn );
2566a1c5513c175a2c13594dde7110822b205cabfc14Brian Paul
25673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CMP:
25683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_cmp( emit, insn );
25693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DIV:
25713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_div( emit, insn );
25723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DP2:
25743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dp2( emit, insn );
25753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DPH:
25773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dph( emit, insn );
25783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NRM:
25803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_nrm( emit, insn );
25813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_COS:
25833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_cos( emit, insn );
25843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SIN:
25863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sin( emit, insn );
25873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SCS:
25893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sincos( emit, insn );
25903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_END:
25923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* TGSI always finishes the main func with an END */
25933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_end( emit );
25943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_KIL:
25963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_kil( emit, insn );
25973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Selection opcodes.  The underlying language is fairly
25993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * non-orthogonal about these.
26003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SEQ:
26023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_EQUAL, insn );
26033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SNE:
26053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_NOTEQUAL, insn );
26063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SGT:
26083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_GREATER, insn );
26093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SGE:
26113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_GEQUAL, insn );
26123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SLT:
26143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_LESS, insn );
26153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SLE:
26173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_select_op( emit, PIPE_FUNC_LEQUAL, insn );
26183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SUB:
26203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_sub( emit, insn );
26213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_POW:
26233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_pow( emit, insn );
26243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_EX2:
26263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_ex2( emit, insn );
26273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_EXP:
26293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_exp( emit, insn );
26303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LOG:
26323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_log( emit, insn );
26333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LG2:
26353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_LOG, insn );
26363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RSQ:
26383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_RSQ, insn );
26393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RCP:
26413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_scalar_op1( emit, SVGA3DOP_RCP, insn );
26423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CONT:
26443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_RET:
26453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* This is a noop -- we tell mesa that we can't support RET
26463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * within a function (early return), so this will always be
26473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * followed by an ENDSUB.
26483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
26503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* These aren't actually used by any of the frontends we care
26523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * about:
26533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
26543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_CLAMP:
26553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_AND:
26563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_OR:
26573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_I2F:
26583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_NOT:
26593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_SHL:
26602c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
26613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_XOR:
26623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
26633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_IF:
26653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_if( emit, insn );
26663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ELSE:
26673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_else( emit, insn );
26683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDIF:
26693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_endif( emit, insn );
26703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BGNLOOP:
26723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_bgnloop2( emit, insn );
26733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_ENDLOOP:
26743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_endloop2( emit, insn );
26753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_BRK:
26763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_brk( emit, insn );
26773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_XPD:
26793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_xpd( emit, insn );
26803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_KILP:
26823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_kilp( emit, insn );
26833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_DST:
26853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_dst_insn( emit, insn );
26863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LIT:
26883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_lit( emit, insn );
26893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   case TGSI_OPCODE_LRP:
26913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return emit_lrp( emit, insn );
26923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26935a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer   case TGSI_OPCODE_SSG:
26945a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer      return emit_ssg( emit, insn );
26955a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer
26963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   default: {
26973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned opcode = translate_opcode(insn->Instruction.Opcode);
26983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (opcode == SVGA3DOP_LAST_INST)
27003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_simple_instruction( emit, opcode, insn ))
27033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_emit_immediate( struct svga_shader_emitter *emit,
27123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                    struct tgsi_full_immediate *imm)
27133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
27143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   static const float id[4] = {0,0,0,1};
27153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float value[4];
27163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
27173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(1 <= imm->Immediate.NrTokens && imm->Immediate.NrTokens <= 5);
27193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < imm->Immediate.NrTokens - 1; i++)
27203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      value[i] = imm->u[i].Float;
27213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for ( ; i < 4; i++ )
27233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      value[i] = id[i];
27243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
27263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          emit->imm_start + emit->internal_imm_count++,
27273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          value[0], value[1], value[2], value[3]);
27283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean make_immediate( struct svga_shader_emitter *emit,
27313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float a,
27323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float b,
27333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float c,
27343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               float d,
27353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                               struct src_register *out )
27363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
2737279492386ffe741c2f5b91919b37068562b6a282Michal Krol   unsigned idx = emit->nr_hw_float_const++;
27383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_def_const( emit, SVGA3D_CONST_TYPE_FLOAT,
27403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        idx, a, b, c, d ))
27413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
27423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   *out = src_register( SVGA3DREG_CONST, idx );
27443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_vs_preamble( struct svga_shader_emitter *emit )
27493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
27503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit->key.vkey.need_prescale) {
27513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!make_immediate( emit, 0, 0, .5, .5,
27523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                           &emit->imm_0055))
27533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
27543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ps_preamble( struct svga_shader_emitter *emit )
27603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
276194b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul   if (emit->ps_reads_pos && emit->info.reads_z) {
2762166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /*
2763166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * Assemble the position from various bits of inputs. Depth and W are
2764166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * passed in a texcoord this is due to D3D's vPos not hold Z or W.
2765166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * Also fixup the perspective interpolation.
2766166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       *
2767166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.xy = vPos.xy
2768166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.w = rcp(texcoord1.w);
2769166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       * temp_pos.z = texcoord1.z * temp_pos.w;
2770166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz       */
2771166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2772166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
2773166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_XY ),
2774166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       emit->ps_true_pos ))
2775166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2776166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2777166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2778166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_RCP),
2779166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_W ),
2780166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_W ) ))
2781166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2782166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2783166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op2( emit,
2784166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MUL),
2785166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask( emit->ps_temp_pos, TGSI_WRITEMASK_Z ),
2786166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( emit->ps_depth_pos, TGSI_SWIZZLE_Z ),
2787166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar( src(emit->ps_temp_pos), TGSI_SWIZZLE_W ) ))
2788166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
27893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
27904f17830b3dda5a1727a3c87897e73b56b37613a6Jakob Bornecrantz
27913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
27923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
27933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_ps_postamble( struct svga_shader_emitter *emit )
27953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
27963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
27973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* PS oDepth is incredibly fragile and it's very hard to catch the
27993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * types of usage that break it during shader emit.  Easier just to
28003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * redirect the main program to a temporary and then only touch
28013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * oDepth with a hand-crafted MOV below.
28023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (SVGA3dShaderGetRegType(emit->true_pos.value) != 0) {
28043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
28063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
28073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       emit->true_pos,
28083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar(src(emit->temp_pos), TGSI_SWIZZLE_Z) ))
28093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
28103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
28133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
28143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2815fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         /* Potentially override output colors with white for XOR
2816fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell          * logicop workaround.
2817fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell          */
2818fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         if (emit->unit == PIPE_SHADER_FRAGMENT &&
2819fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell             emit->key.fkey.white_fragments) {
2820fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
2821fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            struct src_register one = scalar( get_zero_immediate( emit ),
2822fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                                              TGSI_SWIZZLE_W );
2823fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
2824fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            if (!submit_op1( emit,
2825fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             inst_token(SVGA3DOP_MOV),
2826fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             emit->true_col[i],
2827fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             one ))
2828fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell               return FALSE;
2829fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         }
2830fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         else {
2831fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell            if (!submit_op1( emit,
2832fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             inst_token(SVGA3DOP_MOV),
2833fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             emit->true_col[i],
2834fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell                             src(emit->temp_col[i]) ))
2835fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell               return FALSE;
2836fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         }
28373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
28383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
28413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
28423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_vs_postamble( struct svga_shader_emitter *emit )
28443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
28453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* PSIZ output is incredibly fragile and it's very hard to catch
28463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * the types of usage that break it during shader emit.  Easier
28473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * just to redirect the main program to a temporary and then only
28483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * touch PSIZ with a hand-crafted MOV below.
28493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (SVGA3dShaderGetRegType(emit->true_psiz.value) != 0) {
28513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
28523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
28533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       emit->true_psiz,
28543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       scalar(src(emit->temp_psiz), TGSI_SWIZZLE_X) ))
28553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
28563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
28573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
28583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to perform various manipulations on vertex position to cope
28593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * with the different GL and D3D clip spaces.
28603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
28613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->key.vkey.need_prescale) {
28623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2863166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      SVGA3dShaderDestToken depth = emit->depth_pos;
28643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken pos = emit->true_pos;
28653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      unsigned offset = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
2866bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      struct src_register prescale_scale = src_register( SVGA3DREG_CONST,
2867bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                                                         offset + 0 );
2868bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      struct src_register prescale_trans = src_register( SVGA3DREG_CONST,
2869bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                                                         offset + 1 );
28703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2871166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2872166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
2873166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_W),
2874166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       scalar(src(temp_pos), TGSI_SWIZZLE_W) ))
2875166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
2876166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
28773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* MUL temp_pos.xyz,    temp_pos,      prescale.scale
28783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * MAD result.position, temp_pos.wwww, prescale.trans, temp_pos
28793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   --> Note that prescale.trans.w == 0
28803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
2881bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op2( emit,
2882bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       inst_token(SVGA3DOP_MUL),
2883bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       writemask(temp_pos, TGSI_WRITEMASK_XYZ),
28843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos),
28853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       prescale_scale ))
28863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
28873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2888bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op3( emit,
2889bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       inst_token(SVGA3DOP_MAD),
2890bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       pos,
28913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       swizzle(src(temp_pos), 3, 3, 3, 3),
28923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       prescale_trans,
28933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos)))
28943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
2895166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2896166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /* Also write to depth value */
2897166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op3( emit,
2898166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MAD),
28998bf3fb4eca5594f8348de2f8fb67bc94127f8d5aJakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_Z),
2900166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       swizzle(src(temp_pos), 3, 3, 3, 3),
2901166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       prescale_trans,
2902166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       src(temp_pos) ))
2903166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
29043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
29053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   else {
29063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken temp_pos = emit->temp_pos;
2907166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      SVGA3dShaderDestToken depth = emit->depth_pos;
29083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA3dShaderDestToken pos = emit->true_pos;
29093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      struct src_register imm_0055 = emit->imm_0055;
29103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Adjust GL clipping coordinate space to hardware (D3D-style):
29123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
29133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * DP4 temp_pos.z, {0,0,.5,.5}, temp_pos
2914bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul       * MOV result.position, temp_pos
29153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
2916bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op2( emit,
2917bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       inst_token(SVGA3DOP_DP4),
2918bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       writemask(temp_pos, TGSI_WRITEMASK_Z),
2919bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                       imm_0055,
29203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos) ))
29213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
29223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit,
29243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
29253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       pos,
29263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       src(temp_pos) ))
29273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
2928166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz
2929166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      /* Move the manipulated depth into the extra texcoord reg */
2930166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz      if (!submit_op1( emit,
2931166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       inst_token(SVGA3DOP_MOV),
29328bf3fb4eca5594f8348de2f8fb67bc94127f8d5aJakob Bornecrantz                       writemask(depth, TGSI_WRITEMASK_ZW),
2933166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz                       src(temp_pos) ))
2934166e9421c814d859f849b2aa476380725e74b408Jakob Bornecrantz         return FALSE;
29353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
29363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
29383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
29393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
29413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  0: IF VFACE :4
29423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  1:   COLOR = FrontColor;
29433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  2: ELSE
29443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  3:   COLOR = BackColor;
29453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  4: ENDIF
29463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
29473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_light_twoside( struct svga_shader_emitter *emit )
29483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
29493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register vface, zero;
29503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register front[2];
29513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register back[2];
29523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken color[2];
29533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int count =  emit->internal_color_count;
29543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
29553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderInstToken if_token;
29563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (count == 0)
29583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
29593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vface = get_vface( emit );
29613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = get_zero_immediate( emit );
29623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Can't use get_temp() to allocate the color reg as such
29643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * temporaries will be reclaimed after each instruction by the call
29653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * to reset_temp_regs().
29663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
29673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
2968bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      color[i] = dst_register( SVGA3DREG_TEMP, emit->nr_hw_temp++ );
29693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      front[i] = emit->input_map[emit->internal_color_idx[i]];
29703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Back is always the next input:
29723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
29733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      back[i] = front[i];
29743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      back[i].base.num = front[i].base.num + 1;
29753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Reassign the input_map to the actual front-face color:
29773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
29783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      emit->input_map[emit->internal_color_idx[i]] = src(color[i]);
29793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
2980bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
29813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if_token = inst_token( SVGA3DOP_IFC );
29823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29830bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (emit->key.fkey.front_ccw)
29843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if_token.control = SVGA3DOPCOMP_LT;
29850bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   else
29860bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      if_token.control = SVGA3DOPCOMP_GT;
29873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = scalar(zero, TGSI_SWIZZLE_X);
29893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!(emit_instruction( emit, if_token ) &&
29913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit_src( emit, vface ) &&
29923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         emit_src( emit, zero ) ))
29933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
29943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
29953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
29963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], front[i] ))
29973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
29983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
29993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!(emit_instruction( emit, inst_token( SVGA3DOP_ELSE))))
30013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
3002bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
30033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < count; i++) {
30043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ), color[i], back[i] ))
30053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
30063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_instruction( emit, inst_token( SVGA3DOP_ENDIF ) ))
30093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
30123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
30133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/*
30153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  0: SETP_GT TEMP, VFACE, 0
30163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz  where TEMP is a fake frontface register
30173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
30183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean emit_frontface( struct svga_shader_emitter *emit )
30193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
30203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register vface, zero;
30213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dShaderDestToken temp;
30223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct src_register pass, fail;
30233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   vface = get_vface( emit );
30253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   zero = get_zero_immediate( emit );
30263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Can't use get_temp() to allocate the fake frontface reg as such
30283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * temporaries will be reclaimed after each instruction by the call
30293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * to reset_temp_regs().
30303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
30313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   temp = dst_register( SVGA3DREG_TEMP,
30323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        emit->nr_hw_temp++ );
30333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30340bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   if (emit->key.fkey.front_ccw) {
30353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      pass = scalar( zero, TGSI_SWIZZLE_X );
30363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      fail = scalar( zero, TGSI_SWIZZLE_W );
30370bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   } else {
30380bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      pass = scalar( zero, TGSI_SWIZZLE_W );
30390bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell      fail = scalar( zero, TGSI_SWIZZLE_X );
30403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
30413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit_conditional(emit, PIPE_FUNC_GREATER,
30433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         temp, vface, scalar( zero, TGSI_SWIZZLE_X ),
30443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                         pass, fail))
30453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return FALSE;
30463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Reassign the input_map to the actual front-face color:
30483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
30493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->input_map[emit->internal_frontface_idx] = src(temp);
30503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
30523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
30533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30542f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30552f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul/**
30562f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * Emit code to invert the T component of the incoming texture coordinate.
30572f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * This is used for drawing point sprites when
30582f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul * pipe_rasterizer_state::sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT.
30592f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul */
30602f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paulstatic boolean emit_inverted_texcoords( struct svga_shader_emitter *emit )
30612f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul{
30622f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   struct src_register zero = get_zero_immediate(emit);
30632f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   struct src_register pos_neg_one = get_pos_neg_one_immediate( emit );
30642f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   unsigned inverted_texcoords = emit->inverted_texcoords;
30652f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30662f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   while (inverted_texcoords) {
30672f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      const unsigned unit = ffs(inverted_texcoords) - 1;
30682f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30692f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(emit->inverted_texcoords & (1 << unit));
30702f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30712f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(unit < Elements(emit->ps_true_texcoord));
30722f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30732f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(unit < Elements(emit->ps_inverted_texcoord_input));
30742f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30752f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      assert(emit->ps_inverted_texcoord_input[unit]
30762f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul             < Elements(emit->input_map));
30772f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30782f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      /* inverted = coord * (1, -1, 1, 1) + (0, 1, 0, 0) */
3079bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      if (!submit_op3(emit,
3080bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul                      inst_token(SVGA3DOP_MAD),
30812f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      dst(emit->ps_inverted_texcoord[unit]),
30822f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      emit->ps_true_texcoord[unit],
30832f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      swizzle(pos_neg_one, 0, 3, 0, 0),  /* (1, -1, 1, 1) */
30842f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul                      swizzle(zero, 0, 3, 0, 0)))  /* (0, 1, 0, 0) */
30852f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         return FALSE;
30862f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30872f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      /* Reassign the input_map entry to the new texcoord register */
30882f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      emit->input_map[emit->ps_inverted_texcoord_input[unit]] =
30892f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         emit->ps_inverted_texcoord[unit];
30902f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
3091bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul      inverted_texcoords &= ~(1 << unit);
30922f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   }
30932f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30942f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul   return TRUE;
30952f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul}
30962f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30972f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
30983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
30993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_zero( struct svga_shader_emitter *emit )
31003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
31023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_FRAGMENT) {
31043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->key.fkey.light_twoside)
31053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3107fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell      if (emit->key.fkey.white_fragments)
3108fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell         return TRUE;
3109fc3efccdc67390847fc544f97dbdb1826442ae9aKeith Whitwell
31103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->emit_frontface)
31113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->info.opcode_count[TGSI_OPCODE_DST] >= 1 ||
31145a1ce49c82e245f1f86510d9e1ff7db46a32012bMichel Dänzer          emit->info.opcode_count[TGSI_OPCODE_SSG] >= 1 ||
31153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz          emit->info.opcode_count[TGSI_OPCODE_LIT] >= 1)
31163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return TRUE;
31172f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul
31182f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      if (emit->inverted_texcoords)
31192f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         return TRUE;
31209bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul
31219bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      /* look for any PIPE_SWIZZLE_ZERO/ONE terms */
31229bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      for (i = 0; i < emit->key.fkey.num_textures; i++) {
31239bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul         if (emit->key.fkey.tex[i].swizzle_r > PIPE_SWIZZLE_ALPHA ||
31249bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_g > PIPE_SWIZZLE_ALPHA ||
31259bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_b > PIPE_SWIZZLE_ALPHA ||
31269bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul             emit->key.fkey.tex[i].swizzle_a > PIPE_SWIZZLE_ALPHA)
31279bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul            return TRUE;
31289bd15aef865352b9234fedae76617fc51c71e6d5Brian Paul      }
3129dafa77201f116dc53b18a274fb41eef5bb2bd0e3Brian Paul
3130dafa77201f116dc53b18a274fb41eef5bb2bd0e3Brian Paul      for (i = 0; i < emit->key.fkey.num_textures; i++) {
3131dafa77201f116dc53b18a274fb41eef5bb2bd0e3Brian Paul         if (emit->key.fkey.tex[i].compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
3132dafa77201f116dc53b18a274fb41eef5bb2bd0e3Brian Paul            return TRUE;
3133dafa77201f116dc53b18a274fb41eef5bb2bd0e3Brian Paul      }
31343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
31353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31361bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol   if (emit->unit == PIPE_SHADER_VERTEX) {
31371bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol      if (emit->info.opcode_count[TGSI_OPCODE_CMP] >= 1)
31381bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol         return TRUE;
31391bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol   }
31401bb97610e969918015f46efe6fe32c6c71a8293aMichal Krol
31413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
3142a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
31430748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
31440748fc4f038a0878a981024ac4364f82a23e1ca1Keith Whitwell       emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
31451ab37a2284aa26d797d6ffb955a1e0bfb7aa67d3Brian Paul       emit->info.opcode_count[TGSI_OPCODE_ROUND] >= 1 ||
31463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
31473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
31483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
31493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SLT] >= 1 ||
31503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SNE] >= 1 ||
31513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_SEQ] >= 1 ||
31523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_EXP] >= 1 ||
31533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_LOG] >= 1 ||
31543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_XPD] >= 1 ||
31553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       emit->info.opcode_count[TGSI_OPCODE_KILP] >= 1)
31563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      return TRUE;
31573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return FALSE;
31593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_loop_const( struct svga_shader_emitter *emit )
31633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1);
31653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzneeds_to_create_arl_consts( struct svga_shader_emitter *emit )
31693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return (emit->num_arl_consts > 0);
31713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean
31743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_add_indirect( struct svga_shader_emitter *emit,
31753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                        int num, int current_arl)
31763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
31773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int i;
31783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   assert(num < 0);
31793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < emit->num_arl_consts; ++i) {
31813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->arl_consts[i].arl_num == current_arl)
31823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
31833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
31843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* new entry */
31853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->num_arl_consts == i) {
31863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ++emit->num_arl_consts;
31873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
31883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->arl_consts[i].number = (emit->arl_consts[i].number > num) ?
31893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                num :
31903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                emit->arl_consts[i].number;
31913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->arl_consts[i].arl_num = current_arl;
31923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
31933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
31943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
31963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_instruction( struct svga_shader_emitter *emit,
31973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       const struct tgsi_full_instruction *insn,
31983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                       int current_arl)
31993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
320091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[0].Register.Indirect &&
320191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[0].Indirect.File == TGSI_FILE_ADDRESS) {
32027d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[0];
320391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
320491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
320891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[1].Register.Indirect &&
320991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[1].Indirect.File == TGSI_FILE_ADDRESS) {
32107d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[1];
321191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
321291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
321691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell   if (insn->Src[2].Register.Indirect &&
321791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell       insn->Src[2].Indirect.File == TGSI_FILE_ADDRESS) {
32187d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      const struct tgsi_full_src_register *reg = &insn->Src[2];
321991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      if (reg->Register.Index < 0) {
322091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell         pre_parse_add_indirect(emit, reg->Register.Index, current_arl);
32213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean
32283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzpre_parse_tokens( struct svga_shader_emitter *emit,
32293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                  const struct tgsi_token *tokens )
32303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct tgsi_parse_context parse;
32323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   int current_arl = 0;
32333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_init( &parse, tokens );
32353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   while (!tgsi_parse_end_of_tokens( &parse )) {
32373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tgsi_parse_token( &parse );
32383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (parse.FullToken.Token.Type) {
32393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_IMMEDIATE:
32403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_DECLARATION:
32413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_INSTRUCTION:
32433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (parse.FullToken.FullInstruction.Instruction.Opcode ==
32443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz             TGSI_OPCODE_ARL) {
32453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            ++current_arl;
32463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
32473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!pre_parse_instruction( emit, &parse.FullToken.FullInstruction,
32483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                     current_arl ))
32493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
32503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
32523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
32533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_shader_emit_helpers( struct svga_shader_emitter *emit )
32603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_zero( emit )) {
32633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_zero_immediate( emit );
32643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_loop_const( emit )) {
32663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_loop_const( emit );
32673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (needs_to_create_arl_consts( emit )) {
32693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      create_arl_consts( emit );
32703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_FRAGMENT) {
32733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!emit_ps_preamble( emit ))
32743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return FALSE;
32753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->key.fkey.light_twoside) {
32773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!emit_light_twoside( emit ))
32783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
32793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (emit->emit_frontface) {
32813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!emit_frontface( emit ))
32823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return FALSE;
32833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
32842f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      if (emit->inverted_texcoords) {
32852f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul         if (!emit_inverted_texcoords( emit ))
32862f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul            return FALSE;
32872f40e4aac7ab79deb06ff6ab9ae03a896d7a9169Brian Paul      }
32883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
32893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return TRUE;
32913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
32923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
32933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
32943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                       const struct tgsi_token *tokens )
32953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
32963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct tgsi_parse_context parse;
32973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean ret = TRUE;
32983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean helpers_emitted = FALSE;
32993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned line_nr = 0;
33003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_init( &parse, tokens );
33023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit->internal_imm_count = 0;
33033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (emit->unit == PIPE_SHADER_VERTEX) {
33053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = emit_vs_preamble( emit );
33063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!ret)
33073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         goto done;
33083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   pre_parse_tokens(emit, tokens);
33113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   while (!tgsi_parse_end_of_tokens( &parse )) {
33133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      tgsi_parse_token( &parse );
33143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      switch (parse.FullToken.Token.Type) {
33163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_IMMEDIATE:
33173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = svga_emit_immediate( emit, &parse.FullToken.FullImmediate );
33183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_DECLARATION:
332394b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul         ret = svga_translate_decl_sm30( emit, &parse.FullToken.FullDeclaration );
33243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
3327bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
33283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      case TGSI_TOKEN_TYPE_INSTRUCTION:
33293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!helpers_emitted) {
33303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            if (!svga_shader_emit_helpers( emit ))
33313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               goto done;
33323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            helpers_emitted = TRUE;
33333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         }
3334bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul         ret = svga_emit_instruction( emit,
33353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      line_nr++,
33363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                      &parse.FullToken.FullInstruction );
33373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (!ret)
33383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            goto done;
33393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      default:
33413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         break;
33423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
3343bbe92dc6081e5b7106ae8c8fe716d0f5f90f54ceBrian Paul
33443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      reset_temp_regs( emit );
33453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to terminate the current subroutine.  Note that the
33483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * hardware doesn't tolerate shaders without sub-routines
33493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * terminating with RET+END.
33503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
33513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!emit->in_main_func) {
33523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = emit_instruction( emit, inst_token( SVGA3DOP_RET ) );
33533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (!ret)
33543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         goto done;
33553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
33563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3357a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell   assert(emit->dynamic_branching_level == 0);
3358a9cdae2ae07ee4a465f29eb0bff1e1e494345c69Keith Whitwell
33593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Need to terminate the whole shader:
33603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
33613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
33623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (!ret)
33633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      goto done;
33643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzdone:
33663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   tgsi_parse_free( &parse );
33673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return ret;
33683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
3369