1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/********************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008-2009 VMware, Inc. All rights reserved. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * obtaining a copy of this software and associated documentation 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * files (the "Software"), to deal in the Software without 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * restriction, including without limitation the rights to use, copy, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * modify, merge, publish, distribute, sublicense, and/or sell copies 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software, and to permit persons to whom the Software is 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * furnished to do so, subject to the following conditions: 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * included in all copies or substantial portions of the Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************/ 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_scan.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_bitmask.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svgadump/svga_shader_dump.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_context.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_tgsi.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_tgsi_emit.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_debug.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_hw_reg.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga3d_shaderdefs.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Sinkhole used only in error conditions. 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic char err_buf[128]; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void svga_destroy_shader_emitter( struct svga_shader_emitter *emit ) 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit->buf != err_buf) 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(emit->buf); 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean svga_shader_expand( struct svga_shader_emitter *emit ) 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char *new_buf; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned newsize = emit->size * 2; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(emit->buf != err_buf) 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_buf = REALLOC(emit->buf, emit->size, newsize); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_buf = NULL; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_buf == NULL) { 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->ptr = err_buf; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->buf = err_buf; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->size = sizeof(err_buf); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->size = newsize; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->ptr = new_buf + (emit->ptr - emit->buf); 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->buf = new_buf; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean reserve( struct svga_shader_emitter *emit, 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned nr_dwords ) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit->ptr - emit->buf + nr_dwords * sizeof(unsigned) >= emit->size) { 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!svga_shader_expand( emit )) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean svga_shader_emit_dword( struct svga_shader_emitter *emit, 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned dword ) 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reserve(emit, 1)) 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *(unsigned *)emit->ptr = dword; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->ptr += sizeof dword; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean svga_shader_emit_dwords( struct svga_shader_emitter *emit, 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned *dwords, 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned nr ) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reserve(emit, nr)) 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy( emit->ptr, dwords, nr * sizeof *dwords ); 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->ptr += nr * sizeof *dwords; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean svga_shader_emit_opcode( struct svga_shader_emitter *emit, 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned opcode ) 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA3dShaderInstToken *here; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reserve(emit, 1)) 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org here = (SVGA3dShaderInstToken *)emit->ptr; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org here->value = opcode; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit->insn_offset) { 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA3dShaderInstToken *prev = (SVGA3dShaderInstToken *)(emit->buf + 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->insn_offset); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev->size = (here - prev) - 1; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->insn_offset = emit->ptr - emit->buf; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit->ptr += sizeof(unsigned); 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean svga_shader_emit_header( struct svga_shader_emitter *emit ) 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA3dShaderVersion header; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset( &header, 0, sizeof header ); 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (emit->unit) { 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_SHADER_FRAGMENT: 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.value = SVGA3D_PS_30; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_SHADER_VERTEX: 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org header.value = SVGA3D_VS_30; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return svga_shader_emit_dword( emit, header.value ); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Use the shader info to generate a bitmask indicating which generic 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inputs are used by the shader. A set bit indicates that GENERIC[i] 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is used. 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_get_generic_inputs_mask(const struct tgsi_shader_info *info) 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i, mask = 0x0; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < info->num_inputs; i++) { 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned j = info->input_semantic_index[i]; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(j < sizeof(mask) * 8); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mask |= 1 << j; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return mask; 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Given a mask of used generic variables (as returned by the above functions) 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * fill in a table which maps those indexes to small integers. 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This table is used by the remap_generic_index() function in 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_tgsi_decl_sm30.c 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Example: if generics_mask = binary(1010) it means that GENERIC[1] and 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GENERIC[3] are used. The remap_table will contain: 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * table[1] = 0; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * table[3] = 1; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The remaining table entries will be filled in with the next unused 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generic index (in this example, 2). 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_remap_generics(unsigned generics_mask, 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int8_t remap_table[MAX_GENERIC_VARYING]) 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note texcoord[0] is reserved so start at 1 */ 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count = 1, i; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < MAX_GENERIC_VARYING; i++) { 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remap_table[i] = -1; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* for each bit set in generic_mask */ 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (generics_mask) { 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index = ffs(generics_mask) - 1; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remap_table[index] = count++; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org generics_mask &= ~(1 << index); 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Use the generic remap table to map a TGSI generic varying variable 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * index to a small integer. If the remapping table doesn't have a 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * valid value for the given index (the table entry is -1) it means 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the fragment shader doesn't use that VS output. Just allocate 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the next free value in that case. Alternately, we could cull 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * VS instructions that write to register, or replace the register 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * with a dummy temp register. 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX TODO: we should do one of the later as it would save precious 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * texcoord registers. 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_remap_generic_index(int8_t remap_table[MAX_GENERIC_VARYING], 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int generic_index) 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(generic_index < MAX_GENERIC_VARYING); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (generic_index >= MAX_GENERIC_VARYING) { 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* just don't return a random/garbage value */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org generic_index = MAX_GENERIC_VARYING - 1; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (remap_table[generic_index] == -1) { 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This is a VS output that has no matching PS input. Find a 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * free index. 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i, max = 0; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < MAX_GENERIC_VARYING; i++) { 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max = MAX2(max, remap_table[i]); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remap_table[generic_index] = max + 1; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return remap_table[generic_index]; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Parse TGSI shader and translate to SVGA/DX9 serialized 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * representation. 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In this function SVGA shader is emitted to an in-memory buffer that 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * can be dynamically grown. Once we've finished and know how large 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it is, it will be copied to a hardware buffer for upload. 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct svga_shader_result * 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_tgsi_translate( const struct svga_shader *shader, 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_compile_key key, 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned unit ) 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_shader_result *result = NULL; 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_shader_emitter emit; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&emit, 0, sizeof(emit)); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.size = 1024; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.buf = MALLOC(emit.size); 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit.buf == NULL) { 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.ptr = emit.buf; 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.unit = unit; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.key = key; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_scan_shader( shader->tokens, &emit.info); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.imm_start = emit.info.file_max[TGSI_FILE_CONSTANT] + 1; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (unit == PIPE_SHADER_FRAGMENT) 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.imm_start += key.fkey.num_unnormalized_coords; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (unit == PIPE_SHADER_VERTEX) { 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.imm_start += key.vkey.need_prescale ? 2 : 0; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.nr_hw_float_const = (emit.imm_start + emit.info.file_max[TGSI_FILE_IMMEDIATE] + 1); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.nr_hw_temp = emit.info.file_max[TGSI_FILE_TEMPORARY] + 1; 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit.nr_hw_temp >= SVGA3D_TEMPREG_MAX) { 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("svga: too many temporary registers (%u)\n", emit.nr_hw_temp); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit.in_main_func = TRUE; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!svga_shader_emit_header( &emit )) { 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("svga: emit header failed\n"); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!svga_shader_emit_instructions( &emit, shader->tokens )) { 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("svga: emit instructions failed\n"); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result = CALLOC_STRUCT(svga_shader_result); 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result == NULL) 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->shader = shader; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->tokens = (const unsigned *)emit.buf; 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->nr_tokens = (emit.ptr - emit.buf) / sizeof(unsigned); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&result->key, &key, sizeof key); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->id = UTIL_BITMASK_INVALID_INDEX; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SVGA_DEBUG & DEBUG_TGSI) 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf( "#####################################\n" ); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf( "Shader %u below\n", shader->id ); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_dump( shader->tokens, 0 ); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SVGA_DEBUG & DEBUG_TGSI) { 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf( "Shader %u compiled below\n", shader->id ); 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_shader_dump( result->tokens, 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result->nr_tokens , 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FALSE ); 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf( "#####################################\n" ); 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return result; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail: 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(result); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(emit.buf); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct svga_shader_result * 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_translate_fragment_program( const struct svga_fragment_shader *fs, 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct svga_fs_compile_key *fkey ) 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_compile_key key; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&key, 0, sizeof(key)); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&key.fkey, fkey, sizeof *fkey); 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(key.generic_remap_table, fs->generic_remap_table, 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof(fs->generic_remap_table)); 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return svga_tgsi_translate( &fs->base, 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key, 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PIPE_SHADER_FRAGMENT ); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct svga_shader_result * 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_translate_vertex_program( const struct svga_vertex_shader *vs, 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct svga_vs_compile_key *vkey ) 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_compile_key key; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&key, 0, sizeof(key)); 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&key.vkey, vkey, sizeof *vkey); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note: we could alternately store the remap table in the vkey but 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that would make it larger. We just regenerate it here instead. 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_remap_generics(vkey->fs_generic_inputs, key.generic_remap_table); 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return svga_tgsi_translate( &vs->base, 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key, 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PIPE_SHADER_VERTEX ); 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid svga_destroy_shader_result( struct svga_shader_result *result ) 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE((unsigned *)result->tokens); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(result); 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 390