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