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_compiler.h" 283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_shader_tokens.h" 293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_defines.h" 303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "tgsi/tgsi_parse.h" 313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "tgsi/tgsi_dump.h" 323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "tgsi/tgsi_scan.h" 3358ea42b7db72586563914dea6fed9656caaf7678Brian Paul#include "util/u_math.h" 343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h" 35cdb445f3a9285e2d8f042a07021ade78b94e0156José Fonseca#include "util/u_bitmask.h" 363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 37178407f33c413cbe7434597b2129abde90041b6bJosé Fonseca#include "svgadump/svga_shader_dump.h" 383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_context.h" 403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_tgsi.h" 413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_tgsi_emit.h" 423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_debug.h" 433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_hw_reg.h" 453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga3d_shaderdefs.h" 463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Sinkhole used only in error conditions. 493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic char err_buf[128]; 513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#if 0 533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void svga_destroy_shader_emitter( struct svga_shader_emitter *emit ) 543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (emit->buf != err_buf) 563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(emit->buf); 573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#endif 593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_shader_expand( struct svga_shader_emitter *emit ) 623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz char *new_buf; 643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned newsize = emit->size * 2; 653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(emit->buf != err_buf) 673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz new_buf = REALLOC(emit->buf, emit->size, newsize); 683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz else 693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz new_buf = NULL; 703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (new_buf == NULL) { 723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->ptr = err_buf; 733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->buf = err_buf; 743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->size = sizeof(err_buf); 753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return FALSE; 763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->size = newsize; 793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->ptr = new_buf + (emit->ptr - emit->buf); 803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->buf = new_buf; 813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return TRUE; 823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic INLINE boolean reserve( struct svga_shader_emitter *emit, 853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned nr_dwords ) 863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) { 883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (!svga_shader_expand( emit )) 893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return FALSE; 903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return TRUE; 933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean svga_shader_emit_dword( struct svga_shader_emitter *emit, 963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned dword ) 973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (!reserve(emit, 1)) 993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return FALSE; 1003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *(unsigned *)emit->ptr = dword; 1023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->ptr += sizeof dword; 1033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return TRUE; 1043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean svga_shader_emit_dwords( struct svga_shader_emitter *emit, 1073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz const unsigned *dwords, 1083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned nr ) 1093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (!reserve(emit, nr)) 1113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return FALSE; 1123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memcpy( emit->ptr, dwords, nr * sizeof *dwords ); 1143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->ptr += nr * sizeof *dwords; 1153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return TRUE; 1163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzboolean svga_shader_emit_opcode( struct svga_shader_emitter *emit, 1193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned opcode ) 1203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dShaderInstToken *here; 1223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (!reserve(emit, 1)) 1243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return FALSE; 1253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz here = (SVGA3dShaderInstToken *)emit->ptr; 1273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz here->value = opcode; 1283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (emit->insn_offset) { 1303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dShaderInstToken *prev = (SVGA3dShaderInstToken *)(emit->buf + 1313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->insn_offset); 1323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz prev->size = (here - prev) - 1; 1333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 1343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->insn_offset = emit->ptr - emit->buf; 1363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit->ptr += sizeof(unsigned); 1373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return TRUE; 1383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic boolean svga_shader_emit_header( struct svga_shader_emitter *emit ) 1423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 1433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz SVGA3dShaderVersion header; 1443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memset( &header, 0, sizeof header ); 1463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz switch (emit->unit) { 1483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz case PIPE_SHADER_FRAGMENT: 14994b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul header.value = SVGA3D_PS_30; 1503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz break; 1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz case PIPE_SHADER_VERTEX: 15294b219b9e2c20711078b1628cf1fa599a29bf67fBrian Paul header.value = SVGA3D_VS_30; 1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz break; 1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return svga_shader_emit_dword( emit, header.value ); 1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 16058ea42b7db72586563914dea6fed9656caaf7678Brian Paul/** 16158ea42b7db72586563914dea6fed9656caaf7678Brian Paul * Use the shader info to generate a bitmask indicating which generic 16258ea42b7db72586563914dea6fed9656caaf7678Brian Paul * inputs are used by the shader. A set bit indicates that GENERIC[i] 16358ea42b7db72586563914dea6fed9656caaf7678Brian Paul * is used. 16458ea42b7db72586563914dea6fed9656caaf7678Brian Paul */ 16558ea42b7db72586563914dea6fed9656caaf7678Brian Paulunsigned 16658ea42b7db72586563914dea6fed9656caaf7678Brian Paulsvga_get_generic_inputs_mask(const struct tgsi_shader_info *info) 16758ea42b7db72586563914dea6fed9656caaf7678Brian Paul{ 16858ea42b7db72586563914dea6fed9656caaf7678Brian Paul unsigned i, mask = 0x0; 16958ea42b7db72586563914dea6fed9656caaf7678Brian Paul 17058ea42b7db72586563914dea6fed9656caaf7678Brian Paul for (i = 0; i < info->num_inputs; i++) { 17158ea42b7db72586563914dea6fed9656caaf7678Brian Paul if (info->input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { 17258ea42b7db72586563914dea6fed9656caaf7678Brian Paul unsigned j = info->input_semantic_index[i]; 17358ea42b7db72586563914dea6fed9656caaf7678Brian Paul assert(j < sizeof(mask) * 8); 17458ea42b7db72586563914dea6fed9656caaf7678Brian Paul mask |= 1 << j; 17558ea42b7db72586563914dea6fed9656caaf7678Brian Paul } 17658ea42b7db72586563914dea6fed9656caaf7678Brian Paul } 1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 17858ea42b7db72586563914dea6fed9656caaf7678Brian Paul return mask; 17958ea42b7db72586563914dea6fed9656caaf7678Brian Paul} 18058ea42b7db72586563914dea6fed9656caaf7678Brian Paul 18158ea42b7db72586563914dea6fed9656caaf7678Brian Paul 18258ea42b7db72586563914dea6fed9656caaf7678Brian Paul/** 18358ea42b7db72586563914dea6fed9656caaf7678Brian Paul * Given a mask of used generic variables (as returned by the above functions) 18458ea42b7db72586563914dea6fed9656caaf7678Brian Paul * fill in a table which maps those indexes to small integers. 18558ea42b7db72586563914dea6fed9656caaf7678Brian Paul * This table is used by the remap_generic_index() function in 18658ea42b7db72586563914dea6fed9656caaf7678Brian Paul * svga_tgsi_decl_sm30.c 18758ea42b7db72586563914dea6fed9656caaf7678Brian Paul * Example: if generics_mask = binary(1010) it means that GENERIC[1] and 18858ea42b7db72586563914dea6fed9656caaf7678Brian Paul * GENERIC[3] are used. The remap_table will contain: 18958ea42b7db72586563914dea6fed9656caaf7678Brian Paul * table[1] = 0; 19058ea42b7db72586563914dea6fed9656caaf7678Brian Paul * table[3] = 1; 19158ea42b7db72586563914dea6fed9656caaf7678Brian Paul * The remaining table entries will be filled in with the next unused 19258ea42b7db72586563914dea6fed9656caaf7678Brian Paul * generic index (in this example, 2). 19358ea42b7db72586563914dea6fed9656caaf7678Brian Paul */ 19458ea42b7db72586563914dea6fed9656caaf7678Brian Paulvoid 19558ea42b7db72586563914dea6fed9656caaf7678Brian Paulsvga_remap_generics(unsigned generics_mask, 19658ea42b7db72586563914dea6fed9656caaf7678Brian Paul int8_t remap_table[MAX_GENERIC_VARYING]) 19758ea42b7db72586563914dea6fed9656caaf7678Brian Paul{ 19858ea42b7db72586563914dea6fed9656caaf7678Brian Paul /* Note texcoord[0] is reserved so start at 1 */ 19958ea42b7db72586563914dea6fed9656caaf7678Brian Paul unsigned count = 1, i; 20058ea42b7db72586563914dea6fed9656caaf7678Brian Paul 20158ea42b7db72586563914dea6fed9656caaf7678Brian Paul for (i = 0; i < MAX_GENERIC_VARYING; i++) { 20258ea42b7db72586563914dea6fed9656caaf7678Brian Paul remap_table[i] = -1; 20358ea42b7db72586563914dea6fed9656caaf7678Brian Paul } 20458ea42b7db72586563914dea6fed9656caaf7678Brian Paul 20558ea42b7db72586563914dea6fed9656caaf7678Brian Paul /* for each bit set in generic_mask */ 20658ea42b7db72586563914dea6fed9656caaf7678Brian Paul while (generics_mask) { 20758ea42b7db72586563914dea6fed9656caaf7678Brian Paul unsigned index = ffs(generics_mask) - 1; 20858ea42b7db72586563914dea6fed9656caaf7678Brian Paul remap_table[index] = count++; 20958ea42b7db72586563914dea6fed9656caaf7678Brian Paul generics_mask &= ~(1 << index); 21058ea42b7db72586563914dea6fed9656caaf7678Brian Paul } 21158ea42b7db72586563914dea6fed9656caaf7678Brian Paul} 21258ea42b7db72586563914dea6fed9656caaf7678Brian Paul 21358ea42b7db72586563914dea6fed9656caaf7678Brian Paul 21458ea42b7db72586563914dea6fed9656caaf7678Brian Paul/** 21558ea42b7db72586563914dea6fed9656caaf7678Brian Paul * Use the generic remap table to map a TGSI generic varying variable 2161ca48b3161449945b769b27c33f88f397f98084aBrian Paul * index to a small integer. If the remapping table doesn't have a 2171ca48b3161449945b769b27c33f88f397f98084aBrian Paul * valid value for the given index (the table entry is -1) it means 2181ca48b3161449945b769b27c33f88f397f98084aBrian Paul * the fragment shader doesn't use that VS output. Just allocate 2191ca48b3161449945b769b27c33f88f397f98084aBrian Paul * the next free value in that case. Alternately, we could cull 2201ca48b3161449945b769b27c33f88f397f98084aBrian Paul * VS instructions that write to register, or replace the register 2211ca48b3161449945b769b27c33f88f397f98084aBrian Paul * with a dummy temp register. 2221ca48b3161449945b769b27c33f88f397f98084aBrian Paul * XXX TODO: we should do one of the later as it would save precious 2231ca48b3161449945b769b27c33f88f397f98084aBrian Paul * texcoord registers. 22458ea42b7db72586563914dea6fed9656caaf7678Brian Paul */ 22558ea42b7db72586563914dea6fed9656caaf7678Brian Paulint 2261ca48b3161449945b769b27c33f88f397f98084aBrian Paulsvga_remap_generic_index(int8_t remap_table[MAX_GENERIC_VARYING], 22758ea42b7db72586563914dea6fed9656caaf7678Brian Paul int generic_index) 22858ea42b7db72586563914dea6fed9656caaf7678Brian Paul{ 22958ea42b7db72586563914dea6fed9656caaf7678Brian Paul assert(generic_index < MAX_GENERIC_VARYING); 23058ea42b7db72586563914dea6fed9656caaf7678Brian Paul 23158ea42b7db72586563914dea6fed9656caaf7678Brian Paul if (generic_index >= MAX_GENERIC_VARYING) { 23258ea42b7db72586563914dea6fed9656caaf7678Brian Paul /* just don't return a random/garbage value */ 23358ea42b7db72586563914dea6fed9656caaf7678Brian Paul generic_index = MAX_GENERIC_VARYING - 1; 23458ea42b7db72586563914dea6fed9656caaf7678Brian Paul } 23558ea42b7db72586563914dea6fed9656caaf7678Brian Paul 2361ca48b3161449945b769b27c33f88f397f98084aBrian Paul if (remap_table[generic_index] == -1) { 2371ca48b3161449945b769b27c33f88f397f98084aBrian Paul /* This is a VS output that has no matching PS input. Find a 2381ca48b3161449945b769b27c33f88f397f98084aBrian Paul * free index. 2391ca48b3161449945b769b27c33f88f397f98084aBrian Paul */ 2401ca48b3161449945b769b27c33f88f397f98084aBrian Paul int i, max = 0; 2411ca48b3161449945b769b27c33f88f397f98084aBrian Paul for (i = 0; i < MAX_GENERIC_VARYING; i++) { 2421ca48b3161449945b769b27c33f88f397f98084aBrian Paul max = MAX2(max, remap_table[i]); 2431ca48b3161449945b769b27c33f88f397f98084aBrian Paul } 2441ca48b3161449945b769b27c33f88f397f98084aBrian Paul remap_table[generic_index] = max + 1; 2451ca48b3161449945b769b27c33f88f397f98084aBrian Paul } 2461ca48b3161449945b769b27c33f88f397f98084aBrian Paul 24758ea42b7db72586563914dea6fed9656caaf7678Brian Paul return remap_table[generic_index]; 24858ea42b7db72586563914dea6fed9656caaf7678Brian Paul} 2493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/* Parse TGSI shader and translate to SVGA/DX9 serialized 2523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * representation. 2533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * In this function SVGA shader is emitted to an in-memory buffer that 2553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * can be dynamically grown. Once we've finished and know how large 2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * it is, it will be copied to a hardware buffer for upload. 2573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */ 2583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic struct svga_shader_result * 2593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_tgsi_translate( const struct svga_shader *shader, 26058ea42b7db72586563914dea6fed9656caaf7678Brian Paul struct svga_compile_key key, 2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned unit ) 2623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 2633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_shader_result *result = NULL; 2643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct svga_shader_emitter emit; 2653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memset(&emit, 0, sizeof(emit)); 2673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.size = 1024; 2693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.buf = MALLOC(emit.size); 2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (emit.buf == NULL) { 2713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz goto fail; 2723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.ptr = emit.buf; 2753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.unit = unit; 2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.key = key; 2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz tgsi_scan_shader( shader->tokens, &emit.info); 2793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1; 2813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (unit == PIPE_SHADER_FRAGMENT) 2833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.imm_start += key.fkey.num_unnormalized_coords; 2843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (unit == PIPE_SHADER_VERTEX) { 2863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.imm_start += key.vkey.need_prescale ? 2 : 0; 2873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz } 2883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 289279492386ffe741c2f5b91919b37068562b6a282Michal Krol emit.nr_hw_float_const = (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1); 2903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1; 292f12f67c00a5a75ec58bef14f3cecda6c4c685727Brian Paul 2939b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul if (emit.nr_hw_temp >= SVGA3D_TEMPREG_MAX) { 2949b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul debug_printf("svga: too many temporary registers (%u)\n", emit.nr_hw_temp); 295f12f67c00a5a75ec58bef14f3cecda6c4c685727Brian Paul goto fail; 2969b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul } 297f12f67c00a5a75ec58bef14f3cecda6c4c685727Brian Paul 2983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz emit.in_main_func = TRUE; 2993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3009b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul if (!svga_shader_emit_header( &emit )) { 3019b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul debug_printf("svga: emit header failed\n"); 3023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz goto fail; 3039b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul } 3043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3059b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul if (!svga_shader_emit_instructions( &emit, shader->tokens )) { 3069b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul debug_printf("svga: emit instructions failed\n"); 3073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz goto fail; 3089b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul } 3099b3d87b0924a3d19b99b2ceb2ae55dd74c9088a7Brian Paul 3103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz result = CALLOC_STRUCT(svga_shader_result); 3113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if (result == NULL) 3123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz goto fail; 3133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz result->shader = shader; 3153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz result->tokens = (const unsigned *)emit.buf; 3163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); 3173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memcpy(&result->key, &key, sizeof key); 318cdb445f3a9285e2d8f042a07021ade78b94e0156José Fonseca result->id = UTIL_BITMASK_INVALID_INDEX; 3193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3206dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca if (SVGA_DEBUG & DEBUG_TGSI) 3216dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca { 3226dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca debug_printf( "#####################################\n" ); 3236dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca debug_printf( "Shader %u below\n", shader->id ); 3246dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca tgsi_dump( shader->tokens, 0 ); 3256dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca if (SVGA_DEBUG & DEBUG_TGSI) { 3266dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca debug_printf( "Shader %u compiled below\n", shader->id ); 3276dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca svga_shader_dump( result->tokens, 3286dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca result->nr_tokens , 3296dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca FALSE ); 3306dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca } 3316dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca debug_printf( "#####################################\n" ); 3326dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca } 3336dd9676a8fc43062a7017f2951e0f032889fac9eJosé Fonseca 3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return result; 3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzfail: 3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(result); 3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(emit.buf); 3393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 3403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_shader_result * 3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_translate_fragment_program( const struct svga_fragment_shader *fs, 3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz const struct svga_fs_compile_key *fkey ) 3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 34958ea42b7db72586563914dea6fed9656caaf7678Brian Paul struct svga_compile_key key; 35058ea42b7db72586563914dea6fed9656caaf7678Brian Paul 351f37f1a72095653d4806280e5ef74373781c55184Brian Paul memset(&key, 0, sizeof(key)); 352f37f1a72095653d4806280e5ef74373781c55184Brian Paul 3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memcpy(&key.fkey, fkey, sizeof *fkey); 3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 35558ea42b7db72586563914dea6fed9656caaf7678Brian Paul memcpy(key.generic_remap_table, fs->generic_remap_table, 35658ea42b7db72586563914dea6fed9656caaf7678Brian Paul sizeof(fs->generic_remap_table)); 35758ea42b7db72586563914dea6fed9656caaf7678Brian Paul 3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return svga_tgsi_translate( &fs->base, 3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz key, 3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz PIPE_SHADER_FRAGMENT ); 3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_shader_result * 3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzsvga_translate_vertex_program( const struct svga_vertex_shader *vs, 3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz const struct svga_vs_compile_key *vkey ) 3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 36758ea42b7db72586563914dea6fed9656caaf7678Brian Paul struct svga_compile_key key; 36858ea42b7db72586563914dea6fed9656caaf7678Brian Paul 369f37f1a72095653d4806280e5ef74373781c55184Brian Paul memset(&key, 0, sizeof(key)); 370f37f1a72095653d4806280e5ef74373781c55184Brian Paul 3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz memcpy(&key.vkey, vkey, sizeof *vkey); 3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 37358ea42b7db72586563914dea6fed9656caaf7678Brian Paul /* Note: we could alternately store the remap table in the vkey but 37458ea42b7db72586563914dea6fed9656caaf7678Brian Paul * that would make it larger. We just regenerate it here instead. 37558ea42b7db72586563914dea6fed9656caaf7678Brian Paul */ 37658ea42b7db72586563914dea6fed9656caaf7678Brian Paul svga_remap_generics(vkey->fs_generic_inputs, key.generic_remap_table); 37758ea42b7db72586563914dea6fed9656caaf7678Brian Paul 3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return svga_tgsi_translate( &vs->base, 3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz key, 3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz PIPE_SHADER_VERTEX ); 3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvoid svga_destroy_shader_result( struct svga_shader_result *result ) 3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE((unsigned *)result->tokens); 3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(result); 3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 390