st_glsl_to_tgsi.cpp revision 4c8b6a286887628e5fc35306189a4c4a83c482ea
1f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 2f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 3f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 4f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Copyright © 2010 Intel Corporation 5f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Copyright © 2011 Bryan Cain 6f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 7f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Permission is hereby granted, free of charge, to any person obtaining a 8f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * copy of this software and associated documentation files (the "Software"), 9f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * to deal in the Software without restriction, including without limitation 10f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and/or sell copies of the Software, and to permit persons to whom the 12f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Software is furnished to do so, subject to the following conditions: 13f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 14f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The above copyright notice and this permission notice (including the next 15f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * paragraph) shall be included in all copies or substantial portions of the 16f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Software. 17f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 18f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * DEALINGS IN THE SOFTWARE. 25f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 26f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 27f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 28f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \file glsl_to_tgsi.cpp 29f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Translate GLSL IR to TGSI. 31f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 32f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 33f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include <stdio.h> 34f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/compiler.h" 35f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ir.h" 36f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ir_visitor.h" 37f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ir_print_visitor.h" 38f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ir_expression_flattening.h" 39f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "glsl_types.h" 40f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "glsl_parser_extras.h" 41f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "../glsl/program.h" 42f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ir_optimization.h" 43f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "ast.h" 44f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 45f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" { 46f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/mtypes.h" 47f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/shaderapi.h" 48f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/shaderobj.h" 49f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/uniforms.h" 50f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/hash_table.h" 51f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_instruction.h" 52f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_optimize.h" 53f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_print.h" 54f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/program.h" 55f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_uniform.h" 56f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_parameter.h" 57f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/sampler.h" 58f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 59f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "pipe/p_compiler.h" 60f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "pipe/p_context.h" 61f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "pipe/p_screen.h" 62f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "pipe/p_shader_tokens.h" 63f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "pipe/p_state.h" 64f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "util/u_math.h" 65f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "tgsi/tgsi_ureg.h" 6656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain#include "tgsi/tgsi_info.h" 67f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "st_context.h" 68f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "st_program.h" 69f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "st_glsl_to_tgsi.h" 70f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "st_mesa_to_tgsi.h" 7156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 72f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 73f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ 74f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_ENV_PARAM) | \ 75f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_STATE_VAR) | \ 76f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_NAMED_PARAM) | \ 77f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_CONSTANT) | \ 78f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_UNIFORM)) 79f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 80f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_src_reg; 81f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_dst_reg; 82f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 83f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int swizzle_for_size(int size); 84f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 85f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 8656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * This struct is a corresponding struct to TGSI ureg_src. 87f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 88f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_src_reg { 89f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 90f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg(gl_register_file file, int index, const glsl_type *type) 91f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 92f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = file; 93f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = index; 94f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 95f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = swizzle_for_size(type->vector_elements); 96f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 97f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = SWIZZLE_XYZW; 98f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 99b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type ? type->base_type : GLSL_TYPE_ERROR; 100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 103b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg(gl_register_file file, int index, int type) 104c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain { 105b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type; 106c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->file = file; 107c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->index = index; 108c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->swizzle = SWIZZLE_XYZW; 109c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->negate = 0; 110c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->reladdr = NULL; 111c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 112c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg() 114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 115b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = GLSL_TYPE_ERROR; 116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = PROGRAM_UNDEFINED; 117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = 0; 119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain explicit st_src_reg(st_dst_reg reg); 124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; /**< PROGRAM_* from Mesa */ 126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int negate; /**< NEGATE_XYZW mask from mesa */ 129b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Register index should be offset by the integer in this reg. */ 131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reladdr; 132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_dst_reg { 135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 136b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg(gl_register_file file, int writemask, int type) 137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = file; 139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = writemask; 141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 143b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type; 144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg() 147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 148b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = GLSL_TYPE_ERROR; 149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = PROGRAM_UNDEFINED; 150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = 0; 152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain explicit st_dst_reg(st_src_reg reg); 157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; /**< PROGRAM_* from Mesa */ 159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint cond_mask:4; 162b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Register index should be offset by the integer in this reg. */ 164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reladdr; 165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_src_reg::st_src_reg(st_dst_reg reg) 168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 169b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = reg.type; 170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = reg.file; 171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = reg.index; 172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = SWIZZLE_XYZW; 173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_dst_reg::st_dst_reg(st_src_reg reg) 178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 179b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = reg.type; 180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = reg.file; 181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = reg.index; 182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = WRITEMASK_XYZW; 183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = reg.reladdr; 185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass glsl_to_tgsi_instruction : public exec_node { 188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Callers of this ralloc-based new need not call delete. It's 190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static void* operator new(size_t size, void *ctx) 192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *node; 194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain node = rzalloc_size(ctx, size); 196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(node != NULL); 197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return node; 199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 20156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain unsigned op; 202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst; 203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src[3]; 204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Pointer to the ir source this tree came from for debugging */ 205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir; 206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean cond_update; 207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool saturate; 208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int sampler; /**< sampler index */ 209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int tex_target; /**< One of TEXTURE_*_INDEX */ 210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean tex_shadow; 21141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int dead_mask; /**< Used in dead code elimination */ 212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 21356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */ 214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass variable_storage : public exec_node { 217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage(ir_variable *var, gl_register_file file, int index) 219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain : file(file), index(index), var(var) 220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* empty */ 222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; 225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; 226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var; /* variable that maps to this, if any */ 227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass function_entry : public exec_node { 230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_function_signature *sig; 232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * identifier of this function signature used by the program. 235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * At the point that Mesa instructions for function calls are 237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generated, we don't know the address of the first instruction of 238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the function body. So we make the BranchTarget that is called a 239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * small integer and rewrite them during set_branchtargets(). 240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int sig_id; 242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Pointer to first instruction of the function body. 245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Set during function body emits after main() is processed. 247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *bgn_inst; 249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Index of the first instruction of the function body in actual 252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Mesa IR. 253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Set after convertion from glsl_to_tgsi_instruction to prog_instruction. 255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int inst; 257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Storage for the return value. */ 259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg return_reg; 260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass glsl_to_tgsi_visitor : public ir_visitor { 263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor(); 265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ~glsl_to_tgsi_visitor(); 266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *current_function; 268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_context *ctx; 270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog; 271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program; 272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_compiler_options *options; 273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int next_temp; 27544867da3543ca54ef245695cef72a6e305451d93Bryan Cain 276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int num_address_regs; 27744867da3543ca54ef245695cef72a6e305451d93Bryan Cain int samplers_used; 278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool indirect_addr_temps; 279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool indirect_addr_consts; 280b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 281b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int glsl_version; 282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *find_variable_storage(ir_variable *var); 284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *get_function_signature(ir_function_signature *sig); 286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg get_temp(const glsl_type *type); 288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr); 289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg st_src_reg_for_float(float val); 291b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_int(int val); 292b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_type(int type, int val); 293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \name Visit methods 296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * As typical for the visitor pattern, there must be one \c visit method for 298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each concrete subclass of \c ir_instruction. Virtual base classes within 299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the hierarchy should not have \c visit methods. 300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@{*/ 302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_variable *); 303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop *); 304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop_jump *); 305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function_signature *); 306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function *); 307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_expression *); 308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_swizzle *); 309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_variable *); 310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_array *); 311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_record *); 312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_assignment *); 313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_constant *); 314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_call *); 315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_return *); 316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_discard *); 317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_texture *); 318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_if *); 319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@}*/ 320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result; 322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of variable_storage */ 324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list variables; 325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of function_entry */ 327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list function_signatures; 328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int next_signature_id; 329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of glsl_to_tgsi_instruction */ 331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list instructions; 332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 33356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op); 334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 33556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 33856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 34156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2); 344b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 345b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain unsigned get_opcode(ir_instruction *ir, unsigned op, 346b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 347b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1); 348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit the correct dot-product instruction for the type of arguments 351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void emit_dp(ir_instruction *ir, 353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, 355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src1, 356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned elements); 357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 35856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 36156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 364b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); 365b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 36656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scs(ir_instruction *ir, unsigned op, 367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, const st_src_reg &src); 368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean try_emit_mad(ir_expression *ir, 370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int mul_operand); 371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean try_emit_sat(ir_expression *ir); 372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void emit_swz(ir_expression *ir); 374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool process_move_condition(ir_rvalue *ir); 376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 377c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain void remove_output_reads(gl_register_file type); 37829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain void simplify_cmp(void); 379c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void rename_temp_register(int index, int new_index); 381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_read(int index); 382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_write(int index); 383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_read(int index); 384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_write(int index); 385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void copy_propagate(void); 387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void eliminate_dead_code(void); 38841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int eliminate_dead_code_advanced(void); 389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void merge_registers(void); 390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void renumber_registers(void); 391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *mem_ctx; 393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 395552cc48fca9b932fceb3d8fa7f9d0067f46b67c2Bryan Cainstatic st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); 396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 397b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); 398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 399b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); 400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); 403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) 406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_list args; 408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_start(args, fmt); 409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_vasprintf_append(&prog->InfoLog, fmt, args); 410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_end(args); 411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_FALSE; 413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainswizzle_for_size(int size) 417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size_swizzles[4] = { 419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((size >= 1) && (size <= 4)); 426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size_swizzles[size - 1]; 427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 42956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic bool 43056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainis_tex_instruction(unsigned opcode) 43156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 43256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 43356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex; 43456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 43556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 43656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 43756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_dst_regs(unsigned opcode) 43856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 43956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 44056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->num_dst; 44156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 44256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 44356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 44456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_src_regs(unsigned opcode) 44556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 44656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 44756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex ? info->num_src - 1 : info->num_src; 44856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 44956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 45156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2) 454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); 456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int num_reladdr = 0, i; 457b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 458b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op = get_opcode(ir, op, dst, src0, src1); 459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If we have to do relative addressing, we want to load the ARL 461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * reg directly for one of the regs, and preload the other reladdr 462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sources into temps. 463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += dst.reladdr != NULL; 465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src0.reladdr != NULL; 466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src1.reladdr != NULL; 467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src2.reladdr != NULL; 468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src2, &num_reladdr); 470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src1, &num_reladdr); 471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src0, &num_reladdr); 472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 474b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *dst.reladdr); 475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr--; 476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(num_reladdr == 0); 478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->op = op; 480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst = dst; 481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[0] = src0; 482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[1] = src1; 483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[2] = src2; 484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->ir = ir; 48541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dead_mask = 0; 486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->function = NULL; 488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 48956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (op == TGSI_OPCODE_ARL) 490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->num_address_regs = 1; 491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update indirect addressing status used by TGSI */ 493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch(dst.file) { 495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i<3; i++) { 512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(inst->src[i].reladdr) { 51316d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain switch(inst->src[i].file) { 514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(inst); 533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return inst; 535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 53956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1) 541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, src1, undef_src); 543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 54656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(dst.writemask != 0); 550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, undef_src, undef_src); 551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 55456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) 555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 559b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain/** 560b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * Determines whether to use an integer, unsigned integer, or float opcode 561b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * based on the operands and input opcode, then emits the result. 562b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * 563b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * TODO: type checking for remaining TGSI opcodes 564b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain */ 565b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainunsigned 566b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, 567b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 568b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1) 569b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 570b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type = GLSL_TYPE_FLOAT; 571b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 572b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) 573b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain type = GLSL_TYPE_FLOAT; 574b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else if (glsl_version >= 130) 575b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain type = src0.type; 576b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 577b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case4(c, f, i, u) \ 578b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case TGSI_OPCODE_##c: \ 579b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \ 580b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \ 581b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else op = TGSI_OPCODE_##f; \ 582b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 583b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case3(f, i, u) case4(f, f, i, u) 584b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2fi(f, i) case4(f, f, i, i) 585b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2iu(i, u) case4(i, LAST, i, u) 586b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 587b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain switch(op) { 588b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(ADD, UADD); 589b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MUL, UMUL); 590b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MAD, UMAD); 591b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(DIV, IDIV, UDIV); 592b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MAX, IMAX, UMAX); 593b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MIN, IMIN, UMIN); 594b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(MOD, UMOD); 595b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 596b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SEQ, USEQ); 597b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SNE, USNE); 598b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SGE, ISGE, USGE); 599b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SLT, ISLT, USLT); 600b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 601b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(SHL, SHL); 602b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(ISHR, USHR); 603b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(NOT, NOT); 604b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(AND, AND); 605b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(OR, OR); 606b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(XOR, XOR); 607b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 608b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain default: break; 609b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 610b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 611b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(op != TGSI_OPCODE_LAST); 612b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return op; 613b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 614b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, 617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1, 618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned elements) 619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 62056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain static const unsigned dot_opcodes[] = { 62156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 62856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emits TGSI scalar opcodes to produce unique answers across channels. 629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 63056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Some TGSI opcodes are scalar-only, like ARB_fp/vp. The src X 631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel determines the result across all channels. So to do a vec4 632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this operation, we want to emit a scalar per source channel used 633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * to produce dest channels. 634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 63656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg orig_src0, st_src_reg orig_src1) 639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 64356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI RCP is a scalar operation splatting results to all channels, 644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * dst channels. 646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint this_mask = (1 << i); 649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = orig_src0; 651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src1 = orig_src1; 652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (done_mask & this_mask) 654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (j = i + 1; j < 4; j++) { 659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz && 665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src1.swizzle, j) == src1_swiz) { 666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1_swiz, src1_swiz); 673f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 674f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, op, dst, src0, src1); 675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 677f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 68156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg undef = undef_src; 685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain undef.swizzle = SWIZZLE_XXXX; 687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src0, undef); 689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 691b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainvoid 692b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, 693b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, st_src_reg src0) 694b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 695b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg tmp = get_temp(glsl_type::float_type); 696b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 697b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (src0.type == GLSL_TYPE_INT) 698f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain emit(NULL, TGSI_OPCODE_I2F, st_dst_reg(tmp), src0); 699b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else if (src0.type == GLSL_TYPE_UINT) 700f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain emit(NULL, TGSI_OPCODE_U2F, st_dst_reg(tmp), src0); 701b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 702b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain tmp = src0; 703b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 704f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain emit(NULL, TGSI_OPCODE_ARL, dst, tmp); 705b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 706b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 70856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emit an TGSI_OPCODE_SCS instruction 709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 71056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * The \c SCS opcode functions a bit differently than the other TGSI opcodes. 71156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Instead of splatting its result across all four components of the 71256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * destination, it writes one value to the \c x component and another value to 71356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the \c y component. 714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param ir IR instruction being processed 71656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending 71756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * on which value is desired. 718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param dst Destination register 719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param src Source register 720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 72256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, 723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const st_src_reg &src) 725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Vertex programs cannot use the SCS opcode. 727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src); 730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 73356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1; 734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const unsigned scs_mask = (1U << component); 735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp; 737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 73856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS); 739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are compnents in the destination that differ from the component 741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * that will be written by the SCS instrution, we'll need a temporary. 742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (scs_mask != unsigned(dst.writemask)) { 744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp = get_temp(glsl_type::vec4_type); 745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < 4; i++) { 748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned this_mask = (1U << i); 749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = src; 750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((done_mask & this_mask) != 0) 752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The source swizzle specified which component of the source generates 755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sine / cosine for the current component in the destination. The SCS 756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction requires that this value be swizzle to the X component. 757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Replace the current swizzle with a swizzle that puts the source in 758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the X component. 759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned src0_swiz = GET_SWZ(src.swizzle, i); 761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned j = i + 1; j < 4; j++) { 765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz) { 771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this_mask != scs_mask) { 776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp); 778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction. 780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 78156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0); 782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Move the result of the SCS instruction to the desired location in 785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the destination. 786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp.swizzle = MAKE_SWIZZLE4(component, component, 788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain component, component); 78956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp); 790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction to write directly to the destination. 793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 79456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0); 795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct st_src_reg 803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::st_src_reg_for_float(float val) 804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 805b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src(PROGRAM_CONSTANT, -1, GLSL_TYPE_FLOAT); 8066d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain union gl_constant_value uval; 807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 8086d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain uval.f = val; 809b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters, 810b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain &uval, 1, GL_FLOAT, &src.swizzle); 811b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 812b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return src; 813b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 814b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 815b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstruct st_src_reg 816b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_int(int val) 817b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 818b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src(PROGRAM_CONSTANT, -1, GLSL_TYPE_INT); 819b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain union gl_constant_value uval; 820b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 821b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(glsl_version >= 130); 822b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 823b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain uval.i = val; 824b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters, 825b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain &uval, 1, GL_INT, &src.swizzle); 826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 830b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstruct st_src_reg 831b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) 832b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 833b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) 834b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : 835b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg_for_int(val); 836b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 837b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return st_src_reg_for_float(val); 838b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 839b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caintype_size(const struct glsl_type *type) 842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size; 845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (type->base_type) { 847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_matrix()) { 852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type->matrix_columns; 853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Regardless of size of vector, it gets a vec4. This is bad 855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * packing for things like floats, but otherwise arrays become a 856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * mess. Hopefully a later pass over the code can pack scalars 857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * down if appropriate. 858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_ARRAY: 862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type->length > 0); 863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type_size(type->fields.array) * type->length; 864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_STRUCT: 865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size = 0; 866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type->length; i++) { 867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size += type_size(type->fields.structure[i].type); 868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size; 870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_SAMPLER: 871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Samplers take up one slot in UNIFORMS[], but they're baked in 872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * at link time. 873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 0; 878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * In the initial pass of codegen, we assign temporary numbers to 883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * intermediate results. (not SSA -- variable assignments will reuse 884b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * storage). 885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_src_reg 887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_temp(const glsl_type *type) 888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle[4]; 891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 893b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain src.type = glsl_version >= 130 ? type->base_type : GLSL_TYPE_FLOAT; 894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.file = PROGRAM_TEMPORARY; 895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index = next_temp; 896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = NULL; 897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(type); 898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array() || type->is_record()) { 900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type->vector_elements; i++) 903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = i; 904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (; i < 4; i++) 905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = type->vector_elements - 1; 906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[2], swizzle[3]); 908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.negate = 0; 910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvariable_storage * 915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) 916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry; 919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->variables) { 921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (variable_storage *)iter.get(); 922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->var == var) 924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_variable *ir) 932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "gl_FragCoord") == 0) { 934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->OriginUpperLeft = ir->origin_upper_left; 937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->PixelCenterInteger = ir->pixel_center_integer; 938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (strcmp(ir->name, "gl_FragDepth") == 0) { 940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->depth_layout) { 942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_depth_layout_none: 943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; 944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_depth_layout_any: 946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; 947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_depth_layout_greater: 949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; 950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_depth_layout_less: 952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; 953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_depth_layout_unchanged: 955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; 956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_state_slot *const slots = ir->state_slots; 966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->state_slots != NULL); 967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Check if this statevar's setup in the STATE file exactly 969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * matches how we'll want to reference it as a 970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * struct/array/whatever. If not, then we need to move it into 971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * temporary storage and hope that it'll get copy-propagated 972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * out. 973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->num_state_slots; i++) { 975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (slots[i].swizzle != SWIZZLE_XYZW) { 976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct variable_storage *storage; 981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst; 982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i == ir->num_state_slots) { 983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We'll set the index later. */ 984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = undef_dst; 988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The variable_storage constructor allocates slots based on the size 990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of the type. However, this had better match the number of state 991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * elements that we're going to copy into the new temporary. 992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((int) ir->num_state_slots == type_size(ir->type)); 994f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 997f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(ir->type); 999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1000b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, 1001b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_version >= 130 ? ir->type->base_type : GLSL_TYPE_FLOAT)); 1002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < ir->num_state_slots; i++) { 1006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index = _mesa_add_state_reference(this->prog->Parameters, 1007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index *)slots[i].tokens); 1008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_STATE_VAR) { 1010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->index == -1) { 1011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage->index = index; 1012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index == storage->index + (int)i); 1014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1016b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src(PROGRAM_STATE_VAR, index, 1017b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_version >= 130 ? ir->type->base_type : GLSL_TYPE_FLOAT); 1018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = slots[i].swizzle; 101956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, dst, src); 1020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* even a float takes up a whole vec4 reg in a struct/array. */ 1021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index++; 1022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_TEMPORARY && 1026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index != storage->index + (int) ir->num_state_slots) { 1027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(this->shader_program, 1028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", 1029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->name, dst.index - storage->index, 1030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type_size(ir->type)); 1031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop *ir) 1037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_variable *counter = NULL; 1039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->counter != NULL) 1041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter = new(ir) ir_dereference_variable(ir->counter); 1042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->from != NULL) { 1044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->counter != NULL); 1045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); 1047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 105256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BGNLOOP); 1053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->to) { 1055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir->cmp, glsl_type::bool_type, 1057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->to); 1058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_if *if_stmt = new(ir) ir_if(e); 1059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); 1061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->then_instructions.push_tail(brk); 1063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->accept(this); 1065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete if_stmt; 1067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete brk; 1069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->body_instructions, this); 1072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->increment) { 1074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir_binop_add, counter->type, 1076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->increment); 1077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); 1079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 108556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_ENDLOOP); 1086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop_jump *ir) 1090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->mode) { 1092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_break: 109356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BRK); 1094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_continue: 109656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_CONT); 1097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function_signature *ir) 1104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 1106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (void)ir; 1107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function *ir) 1111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Ignore function bodies other than main() -- we shouldn't see calls to 1113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * them since they should all be inlined before we get to glsl_to_tgsi. 1114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "main") == 0) { 1116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_function_signature *sig; 1117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list empty; 1118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig = ir->matching_signature(&empty); 1120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(sig); 1122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->body) { 1124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir = (ir_instruction *)iter.get(); 1125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(this); 1127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean 1132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 1133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int nonmul_operand = 1 - mul_operand; 1135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg a, b, c; 11363bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain st_dst_reg result_dst; 1137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *expr = ir->operands[mul_operand]->as_expression(); 1139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!expr || expr->operation != ir_binop_mul) 1140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[0]->accept(this); 1143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a = this->result; 1144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[1]->accept(this); 1145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain b = this->result; 1146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[nonmul_operand]->accept(this); 1147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain c = this->result; 1148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = get_temp(ir->type); 11503bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst = st_dst_reg(this->result); 11513bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 11523bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c); 1153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean 1158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir) 1159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Saturates were only introduced to vertex programs in 1161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * NV_vertex_program3, so don't give them to drivers in the VP. 1162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 1164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 1167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sat_src) 1168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sat_src->accept(this); 1171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src = this->result; 1172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = get_temp(ir->type); 11743bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain st_dst_reg result_dst = st_dst_reg(this->result); 11753bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 11773bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain inst = emit(ir, TGSI_OPCODE_MOV, result_dst, src); 1178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->saturate = true; 1179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, 1185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reg, int *num_reladdr) 1186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!reg->reladdr) 1188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1190b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *reg->reladdr); 1191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (*num_reladdr != 1) { 1193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::vec4_type); 1194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 119556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg); 1196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain *reg = temp; 1197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (*num_reladdr)--; 1200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_expression *ir) 1204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int operand; 1206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg op[Elements(ir->operands)]; 1207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result_src; 1208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst; 1209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 121056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c) 1211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operation == ir_binop_add) { 1213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 1)) 1214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 0)) 1216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_sat(ir)) 1219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 122156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->operation == ir_quadop_vector) 122256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(!"ir_quadop_vector should have been lowered"); 1223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (operand = 0; operand < ir->get_num_operands(); operand++) { 1225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(this); 1227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->result.file == PROGRAM_UNDEFINED) { 1228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_print_visitor v; 1229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to get tree for expression operand:\n"); 1230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(&v); 1231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[operand] = this->result; 1234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Matrix expression operands should have been broken down to vector 1236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operations already. 1237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->operands[operand]->type->is_matrix()); 1239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int vector_elements = ir->operands[0]->type->vector_elements; 1242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[1]) { 1243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain vector_elements = MAX2(vector_elements, 1244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->vector_elements); 1245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 1250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 1251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = get_temp(ir->type); 1253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* convenience for the emit functions below. */ 1254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 1255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Limit writes to the channels that will be used by result_src later. 1256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This does limit this temp's use as a temporary for multi-instruction 1257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sequences. 1258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->operation) { 1262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_logic_not: 1263b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], st_src_reg_for_type(result_dst.type, 0)); 1264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_neg: 1266b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(result_dst.type == GLSL_TYPE_FLOAT || result_dst.type == GLSL_TYPE_INT); 1267b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_INT) 1268b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 1269b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else { 1270b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op[0].negate = ~op[0].negate; 1271b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain result_src = op[0]; 1272b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_abs: 1275b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(result_dst.type == GLSL_TYPE_FLOAT); 127656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]); 1277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sign: 127956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]); 1280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rcp: 128256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]); 1283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp2: 128656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]); 1287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp: 1289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log: 1290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"not reached: should be handled by ir_explog_to_explog2"); 1291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log2: 129356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]); 1294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin: 129656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos: 129956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin_reduced: 130256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos_reduced: 130556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdx: 130956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]); 1310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdy: 13123b0858f1aed83e2d90449f042d625c86ac7b93edBryan Cain op[0].negate = ~op[0].negate; 131356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_DDY, result_dst, op[0]); 1314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_noise: { 1317a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain /* At some point, a motivated person could add a better 1318a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * implementation of noise. Currently not even the nvidia 1319a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * binary drivers do anything more than this. In any case, the 1320a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * place to do this is in the GL state tracker, not the poor 1321a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * driver. 1322a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain */ 132356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5)); 1324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_add: 132856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 1329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_sub: 133156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]); 1332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mul: 133556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_div: 1338b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1339b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1340b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1341b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]); 1342b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mod: 1344b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1345b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1346b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1347b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]); 1348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 135156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]); 1352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 135456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SGT, result_dst, op[0], op[1]); 1355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 135756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SLE, result_dst, op[0], op[1]); 1358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 136056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]); 1361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_equal: 136356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_nequal: 136656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_all_equal: 1369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "==" operator producing a scalar boolean. */ 1370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 1372b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg temp = get_temp(glsl_version >= 130 ? 13731141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1374b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 1375b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 137656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 137856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, result_src, st_src_reg_for_float(0.0)); 1379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 138056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_any_nequal: 1384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "!=" operator producing a scalar boolean. */ 1385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 1387b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg temp = get_temp(glsl_version >= 130 ? 13881141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1389b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 1390b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 139156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 139356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); 1394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 139556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_any: 1400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, op[0], op[0], 1402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[0]->type->vector_elements); 140356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); 1404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_xor: 140756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_or: 1411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This could be a saturated add and skip the SNE. */ 141256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 141356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0)); 1414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_and: 1417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 141856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_dot: 1422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type == ir->operands[1]->type); 1424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, op[0], op[1], 1425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[0]->type->vector_elements); 1426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sqrt: 1429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* sqrt(x) = x * rsq(x). */ 143056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 143156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); 1432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For incoming channels <= 0, set the result to 0. */ 1433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0].negate = ~op[0].negate; 143456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_CMP, result_dst, 1435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0], result_src, st_src_reg_for_float(0.0)); 1436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rsq: 143856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 1439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2f: 1441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_b2f: 1442b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1443b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]); 1444b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1445b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_b2i: 1447b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain /* Booleans are stored as integers (or floats in GLSL 1.20 and lower). */ 1448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = op[0]; 1449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2i: 1451b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) 1452b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]); 1453b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1454b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2b: 1457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2b: 1458b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], 1459b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg_for_type(result_dst.type, 0)); 1460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_trunc: 146256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_ceil: 1465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0].negate = ~op[0].negate; 146656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]); 1467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src.negate = ~result_src.negate; 1468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_floor: 147056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]); 1471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_fract: 147356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]); 1474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_min: 147756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]); 1478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_max: 148056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]); 1481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_pow: 148356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]); 1484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_bit_not: 1487b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1488b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 1489b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1490b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_u2f: 1492b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1493b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]); 1494b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1495b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lshift: 1497b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1498b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_SHL, result_dst, op[0]); 1499b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1500b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_rshift: 1502b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1503b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0]); 1504b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1505b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_and: 1507b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1508b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0]); 1509b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1510b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_xor: 1512b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1513b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_XOR, result_dst, op[0]); 1514b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1515b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_or: 1517b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) { 1518b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, op[0]); 1519b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1520b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_round_even: 1522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"GLSL 1.30 features unsupported"); 1523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_quadop_vector: 1526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This operation should have already been handled. 1527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 1529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 1533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_swizzle *ir) 1538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 1541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle[4]; 1542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Note that this is only swizzles in expressions, not those on the left 1544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * hand side of an assignment, which do write masking. See ir_assignment 1545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for that. 1546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->val->accept(this); 1549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(src.file != PROGRAM_UNDEFINED); 1551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 1553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i < ir->type->vector_elements) { 1554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (i) { 1555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 0: 1556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 1557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 1: 1559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 1560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 2: 1562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 1563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 3: 1565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 1566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last 1570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel out. 1571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = swizzle[ir->type->vector_elements - 1]; 1573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 1577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 1579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) 1583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry = find_variable_storage(ir->var); 1585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var = ir->var; 1586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (var->mode) { 1589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_uniform: 1590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_in: 1595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_inout: 1596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The linker assigns locations for varyings and attributes, 1597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * including deprecated builtins (like gl_Color), user-assign 1598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic attributes (glBindVertexLocation), and 1599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * user-defined varyings. 1600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: We would hit this path for function arguments. Fix! 1602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_INPUT, 1606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 1608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location >= VERT_ATTRIB_GENERIC0) { 1609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_add_attribute(this->prog->Attributes, 1610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->name, 1611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_sizeof_glsl_type(var->type->gl_type), 1612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->type->gl_type, 1613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location - VERT_ATTRIB_GENERIC0); 1614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_out: 1617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_OUTPUT, 1620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_system_value: 1623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_SYSTEM_VALUE, 1625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_auto: 1628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_temporary: 1629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 1631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(var->type); 1634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to make storage for %s\n", var->name); 1639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = st_src_reg(entry->file, entry->index, var->type); 1644b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain if (glsl_version <= 120) 1645b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain this->result.type = GLSL_TYPE_FLOAT; 1646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_array *ir) 1650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *index; 1652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int element_size = type_size(ir->type); 1654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index = ir->array_index->constant_expression_value(); 1656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array->accept(this); 1658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index) { 1661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index += index->value.i[0] * element_size; 1662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg array_base = this->result; 1664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Variable index array dereference. It eats the "vec4" of the 1665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * base of the array and an index that offsets the Mesa register 1666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * index. 1667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_index->accept(this); 1669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg index_reg; 1671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_size == 1) { 1673f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index_reg = this->result; 1674f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index_reg = get_temp(glsl_type::float_type); 1676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 167756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg), 1678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result, st_src_reg_for_float(element_size)); 1679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = ralloc(mem_ctx, st_src_reg); 1682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 1683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 1686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 1687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = swizzle_for_size(ir->type->vector_elements); 1688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 1689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 1690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1691f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 1692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_record *ir) 1696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 1698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *struct_type = ir->record->type; 1699f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int offset = 0; 1700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->record->accept(this); 1702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < struct_type->length; i++) { 1704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 1705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain offset += type_size(struct_type->fields.structure[i].type); 1707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 1710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 1711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 1712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 1713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = SWIZZLE_NOOP; 1714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.index += offset; 1716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 1719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * We want to be careful in assignment setup to hit the actual storage 1720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instead of potentially using a temporary like we might with the 1721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * ir_dereference handler. 1722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic st_dst_reg 1724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v) 1725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The LHS must be a dereference. If the LHS is a variable indexed array 1727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * access of a vector, it must be separated into a series conditional moves 1728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before reaching this point (see ir_vec_index_to_cond_assign). 1729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->as_dereference()); 1731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_array *deref_array = ir->as_dereference_array(); 1732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (deref_array) { 1733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!deref_array->array->type->is_vector()); 1734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use the rvalue deref handler for the most part. We'll ignore 1737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * swizzles in it and write swizzles using writemask, though. 1738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(v); 1740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return st_dst_reg(v->result); 1741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 1744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Process the condition of a conditional assignment 1745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Examines the condition of a conditional assignment to generate the optimal 1747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * first operand of a \c CMP instruction. If the condition is a relational 1748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 1749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * used as the source for the \c CMP instruction. Otherwise the comparison 1750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * is processed to a boolean result, and the boolean result is used as the 1751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operand to the CMP instruction. 1752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainbool 1754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) 1755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *src_ir = ir; 1757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool negate = true; 1758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool switch_order = false; 1759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *const expr = ir->as_expression(); 1761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((expr != NULL) && (expr->get_num_operands() == 2)) { 1762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool zero_on_left = false; 1763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (expr->operands[0]->is_zero()) { 1765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[1]; 1766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = true; 1767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (expr->operands[1]->is_zero()) { 1768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[0]; 1769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = false; 1770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* a is - 0 + - 0 + 1773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a < 0) T F F ( a < 0) T F F 1774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 < a) F F T (-a < 0) F F T 1775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 1776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 1777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a > 0) F F T (-a < 0) F F T 1778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 > a) T F F ( a < 0) T F F 1779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 1780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 1781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Note that exchanging the order of 0 and 'a' in the comparison simply 1783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * means that the value of 'a' should be negated. 1784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_ir != ir) { 1786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (expr->operation) { 1787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 1788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 1789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 1790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 1793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 1794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 1795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 1798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 1799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 1800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 1803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 1804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 1805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 1808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This isn't the right kind of comparison afterall, so make sure 1809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the whole condition is visited. 1810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = ir; 1812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir->accept(this); 1818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 181956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 1820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * condition we produced is 0.0 or 1.0. By flipping the sign, we can 182156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * choose which value TGSI_OPCODE_CMP produces without an extra instruction 1822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * computing the condition. 1823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (negate) 1825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 1826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return switch_order; 1828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_assignment *ir) 1832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 1834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 1835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 1836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->rhs->accept(this); 1838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r = this->result; 1839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = get_assignment_lhs(ir->lhs, this); 1841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This should really set to the correct maximal writemask for each 1843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: component written (in the loops below). This case can only 1844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: occur for matrices, arrays, and structures. 1845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->write_mask == 0) { 1847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 1848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 1849194732fd7299481dd57815f46a594d155260ce17Bryan Cain } else if (ir->lhs->type->is_scalar() && 1850194732fd7299481dd57815f46a594d155260ce17Bryan Cain ir->lhs->variable_referenced()->mode == ir_var_out) { 1851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 1852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: W component of fragment shader output zero, work correctly. 1853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 1855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzles[4]; 1857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int first_enabled_chan = 0; 1858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int rhs_chan = 0; 1859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = ir->write_mask; 1861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 1863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) { 1864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_enabled_chan = GET_SWZ(r.swizzle, i); 1865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Swizzle a small RHS vector into the channels being written. 1870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * glsl ir treats write_mask as dictating how many channels are 1872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * present on the RHS while Mesa IR treats write_mask as just 1873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * showing which channels of the vec4 RHS get written. 1874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 1876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) 1877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 1878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 1879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = first_enabled_chan; 1880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 1882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[2], swizzles[3]); 1883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(l.file != PROGRAM_UNDEFINED); 1886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(r.file != PROGRAM_UNDEFINED); 1887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 1889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const bool switch_order = this->process_move_condition(ir->condition); 1890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg condition = this->result; 1891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 18938b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain st_src_reg l_src = st_src_reg(l); 18948b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements); 18958b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain 1896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (switch_order) { 18978b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition, l_src, r); 1898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 18998b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition, r, l_src); 1900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 1903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 1904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1905f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain } else if (ir->rhs->as_expression() && 1906f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain this->instructions.get_tail() && 1907f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir && 1908f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain type_size(ir->lhs->type) == 1) { 1909f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain /* To avoid emitting an extra MOV when assigning an expression to a 1910f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain * variable, change the destination register of the last instruction 1911f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain * emitted as part of the expression to the assignment variable. 1912f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain */ 1913f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain glsl_to_tgsi_instruction *inst; 1914f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 1915f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain inst->dst = l; 1916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 191856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 1919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 1920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 1921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_constant *ir) 1928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLfloat stack_vals[4] = { 0 }; 1931b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_constant_value *values = (gl_constant_value *) stack_vals; 1932b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain GLenum gl_type = GL_NONE; 1933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 1934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Unfortunately, 4 floats is all we can get into 1936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * _mesa_add_unnamed_constant. So, make a temp to store an 1937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * aggregate constant and move each constant value into it. If we 1938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * get lucky, copy propagation will eliminate the extra moves. 1939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->base_type == GLSL_TYPE_STRUCT) { 1941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 1942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 1943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, ir->components) { 1945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_value = (ir_constant *)iter.get(); 1946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(field_value->type); 1947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 1949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_value->accept(this); 1951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned int)size; i++) { 195456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 1955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 1957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 1958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 1961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_array()) { 1965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 1966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 1967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(ir->type->fields.array); 1968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 1970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->length; i++) { 1972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_elements[i]->accept(this); 1973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int j = 0; j < size; j++) { 197556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 1976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 1978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 1979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 1982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_matrix()) { 1986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg mat = get_temp(ir->type); 1987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg mat_column = st_dst_reg(mat); 1988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->matrix_columns; i++) { 1990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1991b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements]; 1992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1993b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain src = st_src_reg(PROGRAM_CONSTANT, -1, ir->type->base_type); 1994b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain src.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters, 1995b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain values, 1996b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain ir->type->vector_elements, 1997b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain GL_FLOAT, 1998b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain &src.swizzle); 199956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, mat_column, src); 2000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mat_column.index++; 2002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = mat; 2005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.file = PROGRAM_CONSTANT; 2009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->type->base_type) { 2010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 2011b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = GL_FLOAT; 2012b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2013b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.f[i]; 2014b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 2015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 2017b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = glsl_version >= 130 ? GL_UNSIGNED_INT : GL_FLOAT; 2018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2019b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) 2020b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].u = ir->value.u[i]; 2021b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2022b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.u[i]; 2023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 2026b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = glsl_version >= 130 ? GL_INT : GL_FLOAT; 2027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2028b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) 2029b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].i = ir->value.i[i]; 2030b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2031b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.i[i]; 2032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 2035b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = glsl_version >= 130 ? GL_BOOL : GL_FLOAT; 2036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2037b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (glsl_version >= 130) 2038b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].b = ir->value.b[i]; 2039b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2040b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.b[i]; 2041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Non-float/uint/int/bool constant"); 2045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = st_src_reg(PROGRAM_CONSTANT, -1, ir->type); 2048b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->result.index = _mesa_add_typed_unnamed_constant(this->prog->Parameters, 2049b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values, ir->type->vector_elements, gl_type, 2050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &this->result.swizzle); 2051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfunction_entry * 2054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) 2055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry; 2057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->function_signatures) { 2059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (function_entry *)iter.get(); 2060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->sig == sig) 2062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = ralloc(mem_ctx, function_entry); 2066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig = sig; 2067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig_id = this->next_signature_id++; 2068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst = NULL; 2069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Allocate storage for all the parameters. */ 2071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->parameters) { 2072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)iter.get(); 2073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage; 2074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = find_variable_storage(param); 2076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!storage); 2077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 2080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 2081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(param->type); 2083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sig->return_type->is_void()) { 2086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = get_temp(sig->return_type); 2087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = undef_src; 2089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->function_signatures.push_tail(entry); 2092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_call *ir) 2097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *call_inst; 2099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_function_signature *sig = ir->get_callee(); 2100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = get_function_signature(sig); 2101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process in parameters. */ 2104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list_iterator sig_iter = sig->parameters.iterator(); 2105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_in || 2110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.file = storage->file; 2119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index = storage->index; 2120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.reladdr = NULL; 2121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.cond_mask = COND_TR; 2123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 212556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit call instruction */ 213656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain call_inst = emit(ir, TGSI_OPCODE_CAL); 2137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain call_inst->function = entry; 2138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process out parameters. */ 2140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter = sig->parameters.iterator(); 2141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_out || 2146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 2151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.file = storage->file; 2152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index = storage->index; 2153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.reladdr = NULL; 2154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = SWIZZLE_NOOP; 2155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.negate = 0; 2156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l = st_dst_reg(this->result); 2159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 216156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process return value. */ 2172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = entry->return_reg; 2173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_texture *ir) 2177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result_src, coord, lod_info, projector, dx, dy; 2179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst, coord_dst; 2180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = NULL; 218156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain unsigned opcode = TGSI_OPCODE_NOP; 2182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->coordinate->accept(this); 2184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Put our coords in a temp. We'll need to modify them for shadow, 2186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * projection, or LOD, so the only case we'd use it as is is if 2187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * we're doing plain old texturing. Mesa IR optimization should 2188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * handle cleaning up our mess in that case. 2189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord = get_temp(glsl_type::vec4_type); 2191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst = st_dst_reg(coord); 219256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 2195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->projector->accept(this); 2196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain projector = this->result; 2197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 2200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 2201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = get_temp(glsl_type::vec4_type); 2203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 2204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->op) { 2206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_tex: 220756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TEX; 2208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txb: 221056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXB; 2211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.bias->accept(this); 2212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txl: 221556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXL; 2216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.lod->accept(this); 2217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txd: 222056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXD; 2221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdx->accept(this); 2222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dx = this->result; 2223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdy->accept(this); 2224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dy = this->result; 2225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2226bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain case ir_txf: /* TODO: use TGSI_OPCODE_TXF here */ 2227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"GLSL 1.30 features unsupported"); 2228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 223256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TEX) { 2233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the projector in as the last component of the coord. */ 2234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 223556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, projector); 2236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 223756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXP; 2238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg coord_w = coord; 2240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_w.swizzle = SWIZZLE_WWWW; 2241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For the other TEX opcodes there's no projective version 224356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * since the last slot is taken up by LOD info. Do the 2244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * projective divide now. 2245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 224756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RCP, coord_dst, projector); 2248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* In the case where we have to project the coordinates "by hand," 225056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the shadow comparator value must also be projected. 2251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp_src = coord; 2253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) { 2254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 2258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_src = get_temp(glsl_type::vec4_type); 2260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp_src); 2261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_Z; 226356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); 2264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_XY; 226656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord); 2267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZ; 227056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w); 2271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord.swizzle = SWIZZLE_XYZW; 2274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 227756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the shadow 227856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * comparator was put in the correct place (and projected) by the code, 2279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * above, that handles by-hand projection. 2280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 228156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->shadow_comparitor && (!ir->projector || opcode == TGSI_OPCODE_TXP)) { 2282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 2286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_Z; 228756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 229156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB) { 229256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI stores LOD or LOD bias in the last channel of the coords. */ 2293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 229456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info); 2295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 229856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TXD) 2299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord, dx, dy); 2300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord); 2302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) 2304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_shadow = GL_TRUE; 2305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->shader_program, 2308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->prog); 2309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *sampler_type = ir->sampler->type; 2311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (sampler_type->sampler_dimensionality) { 2313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_1D: 2314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_2D: 2318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_3D: 2322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_3D_INDEX; 2323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_CUBE: 2325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_CUBE_INDEX; 2326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_RECT: 2328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_RECT_INDEX; 2329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_BUF: 2331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"FINISHME: Implement ARB_texture_buffer_object"); 2332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 2335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 2338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_return *ir) 2342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->get_value()) { 2344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(current_function); 2348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->get_value()->accept(this); 2350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = st_dst_reg(current_function->return_reg); 2353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(current_function->sig->return_type); i++) { 235556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 236156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RET); 2362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_discard *ir) 2366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 2368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 2370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 237256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KIL, undef_dst, this->result); 2373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 237456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KILP); 2375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->UsesKill = GL_TRUE; 2378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_if *ir) 2382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *cond_inst, *if_inst, *else_inst = NULL; 2384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *prev_inst; 2385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prev_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(this->result.file != PROGRAM_UNDEFINED); 2390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->options->EmitCondCodes) { 2392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we actually generated any instruction for generating 2395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the condition. If not, then cook up a move to a temp so we 2396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have something to set cond_update on. 2397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (cond_inst == prev_inst) { 2399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::bool_type); 240056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain cond_inst = emit(ir->condition, TGSI_OPCODE_MOV, st_dst_reg(temp), result); 2401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst->cond_update = GL_TRUE; 2403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 240456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF); 2405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_inst->dst.cond_mask = COND_NE; 2406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 240756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result); 2408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(if_inst); 2411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->then_instructions, this); 2413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!ir->else_instructions.is_empty()) { 241556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else_inst = emit(ir->condition, TGSI_OPCODE_ELSE); 2416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->else_instructions, this); 2417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 241956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); 2420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::glsl_to_tgsi_visitor() 2423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result.file = PROGRAM_UNDEFINED; 2425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp = 1; 2426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_signature_id = 1; 2427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain current_function = NULL; 2428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_address_regs = 0; 2429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_temps = false; 2430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_consts = false; 2431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mem_ctx = ralloc_context(NULL); 2432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::~glsl_to_tgsi_visitor() 2435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(mem_ctx); 2437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v) 2440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete v; 2442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Count resources used by the given gpu program (number of texture 2447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * samplers, etc). 2448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 24505768ed6429937940bd48f5de4f8383273952880aBryan Caincount_resources(glsl_to_tgsi_visitor *v, gl_program *prog) 2451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 245244867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used = 0; 2453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 245444867da3543ca54ef245695cef72a6e305451d93Bryan Cain foreach_iter(exec_list_iterator, iter, v->instructions) { 245544867da3543ca54ef245695cef72a6e305451d93Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 245756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (is_tex_instruction(inst->op)) { 245844867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used |= 1 << inst->sampler; 24595768ed6429937940bd48f5de4f8383273952880aBryan Cain 24605768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->SamplerTargets[inst->sampler] = 24615768ed6429937940bd48f5de4f8383273952880aBryan Cain (gl_texture_index)inst->tex_target; 24625768ed6429937940bd48f5de4f8383273952880aBryan Cain if (inst->tex_shadow) { 24635768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->ShadowSamplers |= 1 << inst->sampler; 24645768ed6429937940bd48f5de4f8383273952880aBryan Cain } 2465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 24675768ed6429937940bd48f5de4f8383273952880aBryan Cain 24685768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->SamplersUsed = v->samplers_used; 24695768ed6429937940bd48f5de4f8383273952880aBryan Cain _mesa_update_shader_textures_used(prog); 2470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Check if the given vertex/fragment/shader program is within the 2475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * resource limits of the context (number of texture units, etc). 2476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * If any of those checks fail, record a linker error. 2477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * XXX more checks are needed... 2479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caincheck_resources(const struct gl_context *ctx, 2482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 248344867da3543ca54ef245695cef72a6e305451d93Bryan Cain glsl_to_tgsi_visitor *prog, 248444867da3543ca54ef245695cef72a6e305451d93Bryan Cain struct gl_program *proginfo) 2485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 248644867da3543ca54ef245695cef72a6e305451d93Bryan Cain switch (proginfo->Target) { 2487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_PROGRAM_ARB: 248844867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (_mesa_bitcount(prog->samplers_used) > 2489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ctx->Const.MaxVertexTextureImageUnits) { 2490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many vertex shader texture samplers"); 2491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 249244867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (proginfo->Parameters->NumParameters > MAX_UNIFORMS) { 2493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many vertex shader constants"); 2494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case MESA_GEOMETRY_PROGRAM: 249744867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (_mesa_bitcount(prog->samplers_used) > 2498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ctx->Const.MaxGeometryTextureImageUnits) { 2499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many geometry shader texture samplers"); 2500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 250144867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (proginfo->Parameters->NumParameters > 2502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAX_GEOMETRY_UNIFORM_COMPONENTS / 4) { 2503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many geometry shader constants"); 2504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_PROGRAM_ARB: 250744867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (_mesa_bitcount(prog->samplers_used) > 2508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ctx->Const.MaxTextureImageUnits) { 2509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many fragment shader texture samplers"); 2510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 251144867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (proginfo->Parameters->NumParameters > MAX_UNIFORMS) { 2512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Too many fragment shader constants"); 2513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_problem(ctx, "unexpected program type in check_resources()"); 2517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct uniform_sort { 2523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_uniform *u; 2524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int pos; 2525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 2526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* The shader_program->Uniforms list is almost sorted in increasing 2528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * uniform->{Frag,Vert}Pos locations, but not quite when there are 2529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * uniforms shared between targets. We need to add parameters in 2530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * increasing order for the targets. 2531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 2533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainsort_uniforms(const void *a, const void *b) 2534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct uniform_sort *u1 = (struct uniform_sort *)a; 2536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct uniform_sort *u2 = (struct uniform_sort *)b; 2537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return u1->pos - u2->pos; 2539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Add the uniforms to the parameters. The linker chose locations 2542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in our parameters lists (which weren't created yet), which the 2543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * uniforms code will use to poke values into our parameters list 2544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * when uniforms are updated. 2545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainadd_uniforms_to_parameters_list(struct gl_shader_program *shader_program, 2548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader, 2549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog) 2550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 2552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int next_sampler = 0, num_uniforms = 0; 2553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct uniform_sort *sorted_uniforms; 2554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sorted_uniforms = ralloc_array(NULL, struct uniform_sort, 2556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader_program->Uniforms->NumUniforms); 2557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { 2559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; 2560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int parameter_index = -1; 2561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 2563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 2564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain parameter_index = uniform->VertPos; 2565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 2567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain parameter_index = uniform->FragPos; 2568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 2570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain parameter_index = uniform->GeomPos; 2571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Only add uniforms used in our target. */ 2575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (parameter_index != -1) { 2576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sorted_uniforms[num_uniforms].pos = parameter_index; 2577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sorted_uniforms[num_uniforms].u = uniform; 2578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_uniforms++; 2579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort), 2583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sort_uniforms); 2584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < num_uniforms; i++) { 2586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_uniform *uniform = sorted_uniforms[i].u; 2587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int parameter_index = sorted_uniforms[i].pos; 2588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *type = uniform->Type; 2589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int size; 2590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_vector() || 2592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type->is_scalar()) { 2593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size = type->vector_elements; 2594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size = type_size(type) * 4; 2596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; 2599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_sampler() || 2600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (type->is_array() && type->fields.array->is_sampler())) { 2601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain file = PROGRAM_SAMPLER; 2602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain file = PROGRAM_UNIFORM; 2604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, 2607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uniform->Name); 2608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index < 0) { 2610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index = _mesa_add_parameter(prog->Parameters, file, 2611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uniform->Name, size, type->gl_type, 2612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain NULL, NULL, 0x0); 2613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Sampler uniform values are stored in prog->SamplerUnits, 2615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and the entry in that array is selected by this index we 2616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * store in ParameterValues[]. 2617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (file == PROGRAM_SAMPLER) { 2619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int j = 0; j < size / 4; j++) 26206d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain prog->Parameters->ParameterValues[index + j][0].f = next_sampler++; 2621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The location chosen in the Parameters list here (returned 2624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from _mesa_add_uniform) has to match what the linker chose. 2625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index != parameter_index) { 2627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, "Allocation of uniform `%s' to target " 2628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "failed (%d vs %d)\n", 2629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uniform->Name, index, parameter_index); 2630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(sorted_uniforms); 2635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 2639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 2640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *name, const glsl_type *type, 2641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *val) 2642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_record()) { 2644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_constant; 2645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)val->components.get_head(); 2647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < type->length; i++) { 2649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *field_type = type->fields.structure[i].type; 2650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 2651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type->fields.structure[i].name); 2652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 2653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_type, field_constant); 2654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)field_constant->next; 2655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loc = _mesa_get_uniform_location(ctx, shader_program, name); 2660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (loc == -1) { 2662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, 2663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "Couldn't find uniform for initializer %s\n", name); 2664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 2668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *element; 2669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *element_type; 2670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array()) { 2671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val->array_elements[i]; 2672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type->fields.array; 2673f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2674f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val; 2675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type; 2676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2677f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *values; 2679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->base_type == GLSL_TYPE_BOOL) { 2681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *conv = ralloc_array(mem_ctx, int, element_type->components()); 2682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int j = 0; j < element_type->components(); j++) { 2683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain conv[j] = element->value.b[j]; 2684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = (void *)conv; 2686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = glsl_type::get_instance(GLSL_TYPE_INT, 2687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1); 2689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = &element->value; 2691f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->is_matrix()) { 2694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform_matrix(ctx, shader_program, 2695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->matrix_columns, 2696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loc, 1, GL_FALSE, (GLfloat *)values); 2698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loc += element_type->matrix_columns; 2699f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 2701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values, element_type->gl_type); 2702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loc += type_size(element_type); 2703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainset_uniform_initializers(struct gl_context *ctx, 2709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program) 2710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *mem_ctx = NULL; 2712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 2714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader = shader_program->_LinkedShaders[i]; 2715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shader == NULL) 2717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 2718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *shader->ir) { 2720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir = (ir_instruction *)iter.get(); 2721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var = ir->as_variable(); 2722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!var || var->mode != ir_var_uniform || !var->constant_value) 2724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 2725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!mem_ctx) 2727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mem_ctx = ralloc_context(NULL); 2728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, 2730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->type, var->constant_value); 2731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(mem_ctx); 2735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2737c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain/* 2738c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * Scan/rewrite program to remove reads of custom (output) registers. 2739c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING 2740c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * (for vertex shaders). 2741c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * In GLSL shaders, varying vars can be read and written. 2742c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * On some hardware, trying to read an output register causes trouble. 2743c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * So, rewrite the program to use a temporary register in this case. 2744c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * 2745c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain * Based on _mesa_remove_output_reads from programopt.c. 2746c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain */ 2747c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cainvoid 2748c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cainglsl_to_tgsi_visitor::remove_output_reads(gl_register_file type) 2749c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain{ 2750c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLuint i; 2751c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLint outputMap[VERT_RESULT_MAX]; 2752b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain GLint outputTypes[VERT_RESULT_MAX]; 2753c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLuint numVaryingReads = 0; 2754c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLboolean usedTemps[MAX_PROGRAM_TEMPS]; 2755c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLuint firstTemp = 0; 2756c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2757c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain _mesa_find_used_registers(prog, PROGRAM_TEMPORARY, 2758c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain usedTemps, MAX_PROGRAM_TEMPS); 2759c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2760c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); 2761c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); 2762c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2763c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain for (i = 0; i < VERT_RESULT_MAX; i++) 2764c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain outputMap[i] = -1; 2765c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2766c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* look for instructions which read from varying vars */ 2767c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2768c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 276956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const GLuint numSrc = num_inst_src_regs(inst->op); 2770c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain GLuint j; 2771c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain for (j = 0; j < numSrc; j++) { 2772c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (inst->src[j].file == type) { 2773c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* replace the read with a temp reg */ 2774c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain const GLuint var = inst->src[j].index; 2775c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (outputMap[var] == -1) { 2776c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain numVaryingReads++; 2777c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain outputMap[var] = _mesa_find_free_register(usedTemps, 2778c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain MAX_PROGRAM_TEMPS, 2779c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain firstTemp); 2780b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain outputTypes[var] = inst->src[j].type; 2781c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain firstTemp = outputMap[var] + 1; 2782c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2783c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain inst->src[j].file = PROGRAM_TEMPORARY; 2784c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain inst->src[j].index = outputMap[var]; 2785c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2786c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2787c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2788c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2789c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (numVaryingReads == 0) 2790c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain return; /* nothing to be done */ 2791c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2792c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* look for instructions which write to the varying vars identified above */ 2793c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2794c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2795c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (inst->dst.file == type && outputMap[inst->dst.index] >= 0) { 2796c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* change inst to write to the temp reg, instead of the varying */ 2797c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain inst->dst.file = PROGRAM_TEMPORARY; 2798c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain inst->dst.index = outputMap[inst->dst.index]; 2799c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2800c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2801c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 2802c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* insert new MOV instructions at the end */ 2803c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain for (i = 0; i < VERT_RESULT_MAX; i++) { 2804c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (outputMap[i] >= 0) { 2805c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* MOV VAR[i], TEMP[tmp]; */ 2806b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src = st_src_reg(PROGRAM_TEMPORARY, outputMap[i], outputTypes[i]); 2807b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst = st_dst_reg(type, WRITEMASK_XYZW, outputTypes[i]); 2808c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain dst.index = i; 280956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain this->emit(NULL, TGSI_OPCODE_MOV, dst, src); 2810c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2811c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 2812c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain} 2813c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 281429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 281529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which 281629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * are read from the given src in this instruction 281729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 281829d21417e38aed0f0710d3692df320728aef90b1Bryan Cainstatic int 281929d21417e38aed0f0710d3692df320728aef90b1Bryan Cainget_src_arg_mask(st_dst_reg dst, st_src_reg src) 282029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 282129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain int read_mask = 0, comp; 282229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 282329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Now, given the src swizzle and the written channels, find which 282429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * components are actually read 282529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 282629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain for (comp = 0; comp < 4; ++comp) { 282729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain const unsigned coord = GET_SWZ(src.swizzle, comp); 282829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain ASSERT(coord < 4); 282929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W) 283029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain read_mask |= 1 << coord; 283129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 283229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 283329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain return read_mask; 283429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 283529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 283629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 283729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP 283829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * instruction is the first instruction to write to register T0. There are 283929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * several lowering passes done in GLSL IR (e.g. branches and 284029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * relative addressing) that create a large number of conditional assignments 284129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * that ir_to_mesa converts to CMP instructions like the one mentioned above. 284229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 284329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Here is why this conversion is safe: 284429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * CMP T0, T1 T2 T0 can be expanded to: 284529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * if (T1 < 0.0) 284629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T2; 284729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * else 284829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0; 284929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 285029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same 285129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * as the original program. If (T1 < 0.0) evaluates to false, executing 285229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized. 285329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2 285429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * because any instruction that was going to read from T0 after this was going 285529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * to read a garbage value anyway. 285629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 285729d21417e38aed0f0710d3692df320728aef90b1Bryan Cainvoid 285829d21417e38aed0f0710d3692df320728aef90b1Bryan Cainglsl_to_tgsi_visitor::simplify_cmp(void) 285929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 286029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned tempWrites[MAX_PROGRAM_TEMPS]; 286129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned outputWrites[MAX_PROGRAM_OUTPUTS]; 286229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 286329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain memset(tempWrites, 0, sizeof(tempWrites)); 286429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain memset(outputWrites, 0, sizeof(outputWrites)); 286529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 286629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 286729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 286829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned prevWriteMask = 0; 286929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 287029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Give up if we encounter relative addressing or flow control. */ 287129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.reladdr || 287229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tgsi_get_opcode_info(inst->op)->is_branch || 287329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_BGNSUB || 287429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_CONT || 287529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_END || 287629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_ENDSUB || 287729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_RET) { 287829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain return; 287929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 288029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 288129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) { 288229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain assert(inst->dst.index < MAX_PROGRAM_OUTPUTS); 288329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = outputWrites[inst->dst.index]; 288429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain outputWrites[inst->dst.index] |= inst->dst.writemask; 288529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY) { 288629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain assert(inst->dst.index < MAX_PROGRAM_TEMPS); 288729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = tempWrites[inst->dst.index]; 288829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tempWrites[inst->dst.index] |= inst->dst.writemask; 288929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 289029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 289129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* For a CMP to be considered a conditional write, the destination 289229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * register and source register two must be the same. */ 289329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->op == TGSI_OPCODE_CMP 289429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && !(inst->dst.writemask & prevWriteMask) 289529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].file == inst->dst.file 289629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].index == inst->dst.index 289729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) { 289829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 289929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op = TGSI_OPCODE_MOV; 290029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->src[0] = inst->src[1]; 290129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 290229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 290329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 290429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 2905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Replaces all references to a temporary register index with another index. */ 2906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) 2908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned j; 2912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 291356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 2914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 2915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 2916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index = new_index; 2917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 2921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.index = new_index; 2922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 2927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_read(int index) 2928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 2930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 2931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 2932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 293656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 2937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 2938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 2939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 2940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 294356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 2944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 2945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 294656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 2947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 2948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 2949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 2951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 2953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 2956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 2959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_write(int index) 2960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 2962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 2963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 2964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 2969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 2970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 297256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 2973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 2974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 297556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 2976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 2977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 2978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 2980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 2982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 2985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 2988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_read(int index) 2989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 2991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that reads the temporary */ 2992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 2993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2994f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 2995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 299756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 2998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 2999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 300456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 300656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_write(int index) 3020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that writes to the temporary */ 3023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) 3029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 303156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 303356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY register 3047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channels for copy propagation and updates following instructions to 3048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * use the original versions. 3049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production before this pass: 3052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 3056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after: 3058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * which allows for dead code elimination on TEMP[1]'s writes. 3064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::copy_propagate(void) 3067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx, 3069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *, 3070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp * 4); 3071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 3072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int level = 0; 3073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 3078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || inst->dst.index < this->next_temp); 3079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* First, do any copy propagation possible into the src regs. */ 3081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < 3; r++) { 3082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *first = NULL; 3083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool good = true; 3084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int acp_base = inst->src[r].index * 4; 3085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[r].file != PROGRAM_TEMPORARY || 3087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].reladdr) 3088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we can find entries in the ACP consisting of MOVs 3091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from the same src register for all the swizzled channels 3092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this src register reference. 3093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan]; 3097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!copy_chan) { 3099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(acp_level[acp_base + src_chan] <= level); 3104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!first) { 3106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first = copy_chan; 3107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 3108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (first->src[0].file != copy_chan->src[0].file || 3109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first->src[0].index != copy_chan->src[0].index) { 3110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (good) { 3117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We've now validated that we can copy-propagate to 3118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * replace this src register reference. Do it. 3119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].file = first->src[0].file; 3121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].index = first->src[0].index; 3122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle = 0; 3124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan]; 3127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 3128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (3 * i)); 3129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].swizzle = swizzle; 3131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (inst->op) { 313556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 313656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 3137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* End of a basic block, clear the ACP entirely. */ 3138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 314156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 3142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ++level; 3143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 314556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDIF: 314656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 3147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear all channels written inside the block from the ACP, but 3148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * leaving those that were not touched. 3149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp_level[4 * r + c] >= level) 3156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 315956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_ENDIF) 3160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain --level; 3161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Continuing the block, clear any written channels from 3165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the ACP. 3166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 3168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any temporary might be written, so no copy propagation 3169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * across this instruction. 3170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_OUTPUT && 3173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.reladdr) { 3174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any output might be written, so no copy propagation 3175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from outputs across this instruction. 3176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 3183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY || 3187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_OUTPUT) { 3188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as dst. */ 3189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY) { 3190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << c)) { 3192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + c] = NULL; 3193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as src. */ 3198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 3204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == inst->dst.file && 3206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c]->src[0].index == inst->dst.index && 3207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask & (1 << src_chan)) 3208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If this is a copy, add it to the ACP. */ 321856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_MOV && 3219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_TEMPORARY && 3220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->dst.reladdr && 3221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->saturate && 3222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].reladdr && 3223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].negate) { 3224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << i)) { 3226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + i] = inst; 3227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp_level[4 * inst->dst.index + i] = level; 3228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp_level); 3234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp); 3235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Tracks available PROGRAM_TEMPORARY registers for dead code elimination. 3239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production after copy propagation but 3242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before this pass: 3243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after this pass: 3249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB) 3253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: doesn't eliminate all dead code inside of loops; it steps around them 3254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::eliminate_dead_code(void) 3257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 3259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last_read = get_last_temp_read(i); 3262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int j = 0; 3263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && 3268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j > last_read) 3269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain iter.remove(); 3271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete inst; 3272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j++; 3275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 327941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain/* 328041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead 328141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * code elimination. This is less primitive than eliminate_dead_code(), as it 328241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is per-channel and can detect consecutive writes without a read between them 328341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * as dead code. However, there is some dead code that can be eliminated by 328441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * eliminate_dead_code() but not this function - for example, this function 328541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * cannot eliminate an instruction writing to a register that is never read and 328641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is the only instruction writing to that register. 328741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * 328841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 328941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * will occur. 329041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 329141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainint 329241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainglsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) 329341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain{ 329441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx, 329541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *, 329641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain this->next_temp * 4); 329741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 329841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int level = 0; 329941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int removed = 0; 330041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 330141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 330241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 330341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 330441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 330541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain || inst->dst.index < this->next_temp); 330641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 330741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain switch (inst->op) { 330841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_BGNLOOP: 330941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDLOOP: 331041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* End of a basic block, clear the write array entirely. 331141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * FIXME: This keeps us from killing dead code when the writes are 331241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * on either side of a loop, even when the register isn't touched 331341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * inside the loop. 331441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 331541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 331641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 331741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 331841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDIF: 331941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain --level; 332041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 332141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 332241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ELSE: 332341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Clear all channels written inside the preceding if block from the 332441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * write array, but leave those that were not touched. 332541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * 332641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * FIXME: This destroys opportunities to remove dead code inside of 332741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * IF blocks that are followed by an ELSE block. 332841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 332941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int r = 0; r < this->next_temp; r++) { 333041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 333141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!writes[4 * r + c]) 333241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 333341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 333441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (write_level[4 * r + c] >= level) 333541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * r + c] = NULL; 333641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 333741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 333841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 333941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 33404c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain case TGSI_OPCODE_IF: 33414c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain ++level; 33424c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain /* fallthrough to default case to mark the condition as read */ 33434c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain 334441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain default: 334541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Continuing the block, clear any channels from the write array that 334641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * are read by this instruction. 334741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 334841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int i = 0; i < 4; i++) { 334941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ 335041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Any temporary might be read, so no dead code elimination 335141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * across this instruction. 335241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 335341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 335441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else if (inst->src[i].file == PROGRAM_TEMPORARY) { 335541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Clear where it's used as src. */ 335641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0); 335741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1); 335841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2); 335941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3); 336041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 336141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 336241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (src_chans & (1 << c)) { 336341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->src[i].index + c] = NULL; 336441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 336541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 336641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 336741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 336841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 336941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 337041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 337141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* If this instruction writes to a temporary, add it to the write array. 337241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * If there is already an instruction in the write array for one or more 337341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * of the channels, flag that channel write as dead. 337441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 337541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && 337641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->dst.reladdr && 337741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->saturate) { 337841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 337941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.writemask & (1 << c)) { 338041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (writes[4 * inst->dst.index + c]) { 338141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (write_level[4 * inst->dst.index + c] < level) 338241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 338341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain else 338441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c]->dead_mask |= (1 << c); 338541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 338641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c] = inst; 338741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain write_level[4 * inst->dst.index + c] = level; 338841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 338941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 339041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 339141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 339241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 339371cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain /* Anything still in the write array at this point is dead code. */ 339471cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int r = 0; r < this->next_temp; r++) { 339571cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int c = 0; c < 4; c++) { 339671cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain glsl_to_tgsi_instruction *inst = writes[4 * r + c]; 339771cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain if (inst) 339871cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain inst->dead_mask |= (1 << c); 339971cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 340071cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 340171cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain 340241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Now actually remove the instructions that are completely dead and update 340341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * the writemask of other instructions with dead channels. 340441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 340541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 340641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 340741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 340841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!inst->dead_mask || !inst->dst.writemask) 340941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 341041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain else if (inst->dead_mask == inst->dst.writemask) { 341141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain iter.remove(); 341241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain delete inst; 341341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain removed++; 341441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else 341541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dst.writemask &= ~(inst->dead_mask); 341641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 341741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 341841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(write_level); 341941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(writes); 342041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 342141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain return removed; 342241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain} 342341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 3424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Merges temporary registers together where possible to reduce the number of 3425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * registers needed to run a program. 3426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Produces optimal code only after copy propagation and dead code elimination 3428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have been run. */ 3429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::merge_registers(void) 3431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp); 3433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp); 3434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 3435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Read the indices of the last read and first write to each temp register 3437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * into an array so that we don't have to traverse the instruction list as 3438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * much. */ 3439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = get_last_temp_read(i); 3441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[i] = get_first_temp_write(i); 3442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Start looking for registers with non-overlapping usages that can be 3445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * merged together. */ 3446556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (i=0; i < this->next_temp; i++) { 3447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[i] < 0 || first_writes[i] < 0) continue; 3449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3450556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (j=0; j < this->next_temp; j++) { 3451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[j] < 0 || first_writes[j] < 0) continue; 3453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We can merge the two registers if the first write to j is after or 3455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in the same instruction as the last read from i. Note that the 3456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register at index i will always be used earlier or at the same time 3457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * as the register at index j. */ 3458556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain if (first_writes[i] <= first_writes[j] && 3459556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain last_reads[i] <= first_writes[j]) 3460556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain { 3461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(j, i); /* Replace all references to j with i.*/ 3462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update the first_writes and last_reads arrays with the new 3464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * values for the merged register index, and mark the newly unused 3465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register index as such. */ 3466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = last_reads[j]; 3467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[j] = -1; 3468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[j] = -1; 3469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(last_reads); 3474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(first_writes); 3475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Reassign indices to temporary registers by reusing unused indices created 3478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * by optimization passes. */ 3479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::renumber_registers(void) 3481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int new_index = 0; 3484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (get_first_temp_read(i) < 0) continue; 3487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i != new_index) 3488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(i, new_index); 3489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new_index++; 3490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp = new_index; 3493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ------------------------- TGSI conversion stuff -------------------------- */ 3496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct label { 3497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned branch_target; 3498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned token; 3499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Intermediate state used during shader translation. 3503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct st_translate { 3505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg; 3506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst temps[MAX_PROGRAM_TEMPS]; 3508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src *constants; 3509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; 3510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; 3511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst address[1]; 3512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src samplers[PIPE_MAX_SAMPLERS]; 3513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src systemValues[SYSTEM_VALUE_MAX]; 3514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Extra info for handling point size clamping in vertex shader */ 3516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst pointSizeResult; /**< Actual point size output register */ 3517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src pointSizeConst; /**< Point size range constant register */ 3518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLint pointSizeOutIndex; /**< Temp point size output register */ 3519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean prevInstWrotePointSize; 3520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *inputMapping; 3522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *outputMapping; 3523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For every instruction that contains a label (eg CALL), keep 3525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * details so that we can go back afterwards and emit the correct 3526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * tgsi instruction number for each label. 3527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct label *labels; 3529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_size; 3530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_count; 3531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Keep a record of the tgsi instruction number that each mesa 3533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction starts at, will be used to fix up labels after 3534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * translation. 3535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned *insn; 3537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_size; 3538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_count; 3539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ 3541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean error; 3543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ 3546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { 3547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_FACE, 3548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_INSTANCEID 3549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Make note of a branch to a label in the TGSI code. 3553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * After we've emitted all instructions, we'll go over the list 3554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of labels built here and patch the TGSI code with the actual 3555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * location of each label. 3556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic unsigned *get_label( struct st_translate *t, 3558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned branch_target ) 3559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 3561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels_count + 1 >= t->labels_size) { 3563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); 3564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels = (struct label *)realloc(t->labels, 3565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels_size * sizeof t->labels[0]); 3566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels == NULL) { 3567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static unsigned dummy; 3568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &dummy; 3570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i = t->labels_count++; 3574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels[i].branch_target = branch_target; 3575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &t->labels[i].token; 3576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Called prior to emitting the TGSI code for each Mesa instruction. 3580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Allocate additional space for instructions if needed. 3581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Update the insn[] array so the next Mesa instruction points to 3582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the next TGSI instruction. 3583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void set_insn_start( struct st_translate *t, 3585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned start ) 3586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn_count + 1 >= t->insn_size) { 3588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); 3589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn = (unsigned *)realloc(t->insn, t->insn_size * sizeof t->insn[0]); 3590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn == NULL) { 3591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 3593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn[t->insn_count++] = start; 3597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Map a Mesa dst register to a TGSI ureg_dst register. 3601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 3603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caindst_register( struct st_translate *t, 3604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file, 3605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint index ) 3606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch( file ) { 3608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 3609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 3610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 3612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 3613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->temps[index] = ureg_DECL_temporary( t->ureg ); 3614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->temps[index]; 3616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 3618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->procType == TGSI_PROCESSOR_VERTEX && index == VERT_RESULT_PSIZ) 3619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->prevInstWrotePointSize = GL_TRUE; 3620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->procType == TGSI_PROCESSOR_VERTEX) 3622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < VERT_RESULT_MAX); 3623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (t->procType == TGSI_PROCESSOR_FRAGMENT) 3624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < FRAG_RESULT_MAX); 3625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < GEOM_RESULT_MAX); 3627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 3629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->outputs[t->outputMapping[index]]; 3631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 3633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->address[index]; 3634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_assert( 0 ); 3637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 3638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Map a Mesa src register to a TGSI ureg_src register. 3643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 3645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainsrc_register( struct st_translate *t, 3646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file, 3647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint index ) 3648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch( file ) { 3650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 3651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 3652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 3654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 3655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < Elements(t->temps)); 3656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 3657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->temps[index] = ureg_DECL_temporary( t->ureg ); 3658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->temps[index]); 3659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 3661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 3662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 3663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 3664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 3665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 3666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 3667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: /* ie, immediate */ 3668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index < 0) 3669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_DECL_constant( t->ureg, 0 ); 3670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 3672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3673f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_INPUT: 3674f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->inputMapping[index] < Elements(t->inputs)); 3675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->inputs[t->inputMapping[index]]; 3676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3677f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 3678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 3679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ 3680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 3682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->address[index]); 3683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_SYSTEM_VALUE: 3685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < Elements(t->systemValues)); 3686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->systemValues[index]; 3687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_assert( 0 ); 3690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 3691f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 369556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_dst register from an st_dst_reg. 3696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 3698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caintranslate_dst( struct st_translate *t, 369956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const st_dst_reg *dst_reg, 3700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean saturate ) 3701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst dst = dst_register( t, 3703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst_reg->file, 3704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst_reg->index ); 3705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = ureg_writemask( dst, 3707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst_reg->writemask ); 3708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (saturate) 3710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = ureg_saturate( dst ); 3711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst_reg->reladdr != NULL) 3713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); 3714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return dst; 3716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 371956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_src register from an st_src_reg. 3720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 3722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caintranslate_src( struct st_translate *t, 3723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const st_src_reg *src_reg ) 3724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src src = src_register( t, src_reg->file, src_reg->index ); 3726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = ureg_swizzle( src, 3728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ( src_reg->swizzle, 0 ) & 0x3, 3729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ( src_reg->swizzle, 1 ) & 0x3, 3730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ( src_reg->swizzle, 2 ) & 0x3, 3731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ( src_reg->swizzle, 3 ) & 0x3); 3732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((src_reg->negate & 0xf) == NEGATE_XYZW) 3734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = ureg_negate(src); 3735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->reladdr != NULL) { 3737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Normally ureg_src_indirect() would be used here, but a stupid compiler 3738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * bug in g++ makes ureg_src_indirect (an inline C function) erroneously 3739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * set the bit for src.Negate. So we have to do the operation manually 3740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * here to work around the compiler's problems. */ 3741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/ 3742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src addr = ureg_src(t->address[0]); 3743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Indirect = 1; 3744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectFile = addr.File; 3745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectIndex = addr.Index; 3746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectSwizzle = addr.SwizzleX; 3747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->file != PROGRAM_INPUT && 3749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_reg->file != PROGRAM_OUTPUT) { 3750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If src_reg->index was negative, it was set to zero in 3751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * src_register(). Reassign it now. But don't do this 3752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for input/output regs since they get remapped while 3753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * const buffers don't. 3754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Index = src_reg->index; 3756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 3760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 3763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caincompile_tgsi_instruction(struct st_translate *t, 3764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct glsl_to_tgsi_instruction *inst) 3765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 3767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint i; 3768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst dst[1]; 3769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src src[4]; 3770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_dst; 3771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_src; 3772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 377356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain num_dst = num_inst_dst_regs( inst->op ); 377456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain num_src = num_inst_src_regs( inst->op ); 3775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (num_dst) 3777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst[0] = translate_dst( t, 3778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &inst->dst, 377956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->saturate); 3780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < num_src; i++) 3782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src[i] = translate_src( t, &inst->src[i] ); 3783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch( inst->op ) { 378556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 378656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_CAL: 378756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 378856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 378956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 3790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_assert(num_dst == 0); 3791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_label_insn( ureg, 379256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->op, 3793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src, num_src, 3794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain get_label( t, 379556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0 )); 3796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 3797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 379856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TEX: 379956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXB: 380056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXD: 380156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXL: 380256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXP: 3803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src[num_src++] = t->samplers[inst->sampler]; 3804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_tex_insn( ureg, 380556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->op, 3806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst, num_dst, 3807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain translate_texture_target( inst->tex_target, 3808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_shadow ), 3809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src, num_src ); 3810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 3811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 381256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_SCS: 3813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY ); 3814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_insn( ureg, 381556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->op, 3816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst, num_dst, 3817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src, num_src ); 3818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_insn( ureg, 382256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst->op, 3823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst, num_dst, 3824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src, num_src ); 3825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit the TGSI instructions to adjust the WPOS pixel center convention 3831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Basically, add (adjX, adjY) to the fragment position. 3832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 3834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainemit_adjusted_wpos( struct st_translate *t, 3835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *program, 3836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLfloat adjX, GLfloat adjY) 3837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 3839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); 3840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 3841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Note that we bias X and Y and pass Z and W through unchanged. 3843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The shader might also use gl_FragCoord.w and .z. 3844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_ADD(ureg, wpos_temp, wpos_input, 3846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_imm4f(ureg, adjX, adjY, 0.0f, 0.0f)); 3847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 3849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit the TGSI instructions for inverting the WPOS y coordinate. 3854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This code is unavoidable because it also depends on whether 3855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). 3856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 3858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainemit_wpos_inversion( struct st_translate *t, 3859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *program, 3860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean invert) 3861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 3863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment program uses fragment position input. 3865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Need to replace instances of INPUT[WPOS] with temp T 3866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * where T = INPUT[WPOS] by y is inverted. 3867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static const gl_state_index wposTransformState[STATE_LENGTH] 3869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 3870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; 3871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX: note we are modifying the incoming shader here! Need to 3873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * do this before emitting the constant decls below, or this 3874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will be missed: 3875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, 3877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wposTransformState); 3878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); 3880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst wpos_temp; 3881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 3882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MOV wpos_temp, input[wpos] 3884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (wpos_input.File == TGSI_FILE_TEMPORARY) 3886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wpos_temp = ureg_dst(wpos_input); 3887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 3888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wpos_temp = ureg_DECL_temporary( ureg ); 3889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_MOV( ureg, wpos_temp, wpos_input ); 3890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (invert) { 3893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy 3894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_MAD( ureg, 3896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 3897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wpos_input, 3898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_scalar(wpostrans, 0), 3899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_scalar(wpostrans, 1)); 3900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 3901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww 3902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_MAD( ureg, 3904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 3905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wpos_input, 3906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_scalar(wpostrans, 2), 3907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_scalar(wpostrans, 3)); 3908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use wpos_temp as position input from here on: 3911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 3913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit fragment position/ooordinate code. 3918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 3920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainemit_wpos(struct st_context *st, 3921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_translate *t, 3922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *program, 3923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg) 3924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_fragment_program *fp = 3926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (const struct gl_fragment_program *) program; 3927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct pipe_screen *pscreen = st->pipe->screen; 3928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean invert = FALSE; 3929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->OriginUpperLeft) { 3931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in upper-left */ 3932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { 3933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin */ 3934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { 3936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin, need to invert Y */ 3937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 3938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 3939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 3942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 3944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in lower-left */ 3945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) 3946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin */ 3947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 3948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) 3949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin, need to invert Y */ 3950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 3951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 3953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->PixelCenterInteger) { 3956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center integer */ 3957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) 3958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer */ 3959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 3960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) 3961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer, need to bias X,Y */ 3962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_adjusted_wpos(t, program, 0.5f, invert ? 0.5f : -0.5f); 3963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 3965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 3967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center half integer */ 3968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 3969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer */ 3970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 3972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer, need to bias X,Y */ 3973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 3974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_adjusted_wpos(t, program, 0.5f, invert ? -0.5f : 0.5f); 3975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 3978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* we invert after adjustment so that we avoid the MOV to temporary, 3981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and reuse the adjustment ADD instead */ 3982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_wpos_inversion(t, program, invert); 3983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3986bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. 3987bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * TGSI uses +1 for front, -1 for back. 3988bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * This function converts the TGSI value to the GL value. Simply clamping/ 3989bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * saturating the value to [0,1] does the job. 3990bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain */ 3991bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 3992bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_face_var(struct st_translate *t) 3993bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 3994bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 3995bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst face_temp = ureg_DECL_temporary(ureg); 3996bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; 3997bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 3998bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* MOV_SAT face_temp, input[face] */ 3999bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain face_temp = ureg_saturate(face_temp); 4000bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, face_temp, face_input); 4001bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4002bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* Use face_temp as face input from here on: */ 4003bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); 4004bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4005bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4006bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 4007bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_edgeflags(struct st_translate *t) 4008bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 4009bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 4010bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; 4011bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; 4012bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4013bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, edge_dst, edge_src); 4014bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4015bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4016bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain/** 4017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format. 4018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param program the program to translate 4019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numInputs number of input registers used 4020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputMapping maps Mesa fragment program inputs to TGSI generic 4021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * input indexes 4022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticName the TGSI_SEMANTIC flag for each input 4023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticIndex the semantic index (ex: which texcoord) for 4024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each input 4025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input 4026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numOutputs number of output registers used 4027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputMapping maps Mesa fragment program outputs to TGSI 4028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic outputs 4029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticName the TGSI_SEMANTIC flag for each output 4030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticIndex the semantic index (ex: which texcoord) for 4031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each output 4032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 4033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY 4034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" enum pipe_error 4036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_translate_program( 4037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_context *ctx, 4038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uint procType, 4039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg, 4040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor *program, 4041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *proginfo, 4042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numInputs, 4043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint inputMapping[], 4044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticName[], 4045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticIndex[], 4046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint interpMode[], 4047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numOutputs, 4048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint outputMapping[], 4049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticName[], 4050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticIndex[], 4051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean passthrough_edgeflags ) 4052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_translate translate, *t; 4054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 4055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain enum pipe_error ret = PIPE_OK; 4056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numInputs <= Elements(t->inputs)); 4058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numOutputs <= Elements(t->outputs)); 4059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t = &translate; 4061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(t, 0, sizeof *t); 4062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->procType = procType; 4064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputMapping = inputMapping; 4065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputMapping = outputMapping; 4066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->ureg = ureg; 4067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->pointSizeOutIndex = -1; 4068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->prevInstWrotePointSize = GL_FALSE; 4069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare input attributes. 4072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (procType == TGSI_PROCESSOR_FRAGMENT) { 4074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_fs_input(ureg, 4076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticName[i], 4077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticIndex[i], 4078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain interpMode[i]); 4079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->InputsRead & FRAG_BIT_WPOS) { 4082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Must do this after setting up t->inputs, and before 4083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * emitting constant references, below: 4084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_wpos(st_context(ctx), t, proginfo, ureg); 4086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4088bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (proginfo->InputsRead & FRAG_BIT_FACE) 4089bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_face_var(t); 4090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare output attributes. 4093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (outputSemanticName[i]) { 4096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_POSITION: 4097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_DECL_output( ureg, 4098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_POSITION, /* Z / Depth */ 4099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticIndex[i] ); 4100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_writemask( t->outputs[i], 4102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_WRITEMASK_Z ); 4103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_STENCIL: 4105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_DECL_output( ureg, 4106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_STENCIL, /* Stencil */ 4107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticIndex[i] ); 4108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_writemask( t->outputs[i], 4109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_WRITEMASK_Y ); 4110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_COLOR: 4112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_DECL_output( ureg, 4113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_COLOR, 4114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticIndex[i] ); 4115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_assert(0); 4118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return PIPE_ERROR_BAD_INPUT; 4119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (procType == TGSI_PROCESSOR_GEOMETRY) { 4123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_gs_input(ureg, 4125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i, 4126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticName[i], 4127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticIndex[i]); 4128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_DECL_output( ureg, 4132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticName[i], 4133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticIndex[i] ); 4134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(procType == TGSI_PROCESSOR_VERTEX); 4138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_vs_input(ureg, i); 4141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = ureg_DECL_output( ureg, 4145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticName[i], 4146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain outputSemanticIndex[i] ); 4147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((outputSemanticName[i] == TGSI_SEMANTIC_PSIZE) && proginfo->Id) { 4148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Writing to the point size result register requires special 4149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * handling to implement clamping. 4150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static const gl_state_index pointSizeClampState[STATE_LENGTH] 4152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain = { STATE_INTERNAL, STATE_POINT_SIZE_IMPL_CLAMP, (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; 4153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX: note we are modifying the incoming shader here! Need to 4154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * do this before emitting the constant decls below, or this 4155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will be missed. 4156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned pointSizeClampConst = 4158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_add_state_reference(proginfo->Parameters, 4159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain pointSizeClampState); 4160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst psizregtemp = ureg_DECL_temporary( ureg ); 4161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->pointSizeConst = ureg_DECL_constant( ureg, pointSizeClampConst ); 4162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->pointSizeResult = t->outputs[i]; 4163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->pointSizeOutIndex = i; 4164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputs[i] = psizregtemp; 4165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4167bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (passthrough_edgeflags) 4168bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_edgeflags(t); 4169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare address register. 4172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->num_address_regs > 0) { 4174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_assert( program->num_address_regs == 1 ); 4175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->address[0] = ureg_DECL_address( ureg ); 4176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare misc input registers 4179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 4181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLbitfield sysInputs = proginfo->SystemValuesRead; 4182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned numSys = 0; 4183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; sysInputs; i++) { 4184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (sysInputs & (1 << i)) { 4185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned semName = mesa_sysval_to_semantic[i]; 4186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); 4187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain numSys++; 4188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sysInputs &= ~(1 << i); 4189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_temps) { 4194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If temps are accessed with indirect addressing, declare temporaries 4195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in sequential order. Else, we declare them on demand elsewhere. 4196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (Note: the number of temporaries is equal to program->next_temp) 4197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned)program->next_temp; i++) { 4199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ 4200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->temps[i] = ureg_DECL_temporary( t->ureg ); 4201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit constants and immediates. Mesa uses a single index space 4205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for these, so we put all the translated regs in t->constants. 4206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * XXX: this entire if block depends on proginfo->Parameters from Mesa IR 4207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->Parameters) { 4209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->constants = (struct ureg_src *)CALLOC( proginfo->Parameters->NumParameters * sizeof t->constants[0] ); 4210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->constants == NULL) { 4211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ret = PIPE_ERROR_OUT_OF_MEMORY; 4212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain goto out; 4213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < proginfo->Parameters->NumParameters; i++) { 4216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (proginfo->Parameters->Parameters[i].Type) { 4217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 4218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 4219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 4220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 4221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 4222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->constants[i] = ureg_DECL_constant( ureg, i ); 4223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit immediates only when there's no indirect addressing of 4226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the const buffer. 4227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: Be smarter and recognize param arrays: 4228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * indirect addressing is only valid within the referenced 4229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * array. 4230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 4232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_consts) 4233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->constants[i] = ureg_DECL_constant( ureg, i ); 4234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4235b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain switch(proginfo->Parameters->Parameters[i].DataType) 4236b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain { 4237b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_FLOAT: 4238b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_FLOAT_VEC2: 4239b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_FLOAT_VEC3: 4240b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_FLOAT_VEC4: 4241b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain t->constants[i] = ureg_DECL_immediate(ureg, (float *)proginfo->Parameters->ParameterValues[i], 4); 4242b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 4243b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_INT: 4244b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_INT_VEC2: 4245b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_INT_VEC3: 4246b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_INT_VEC4: 4247b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain t->constants[i] = ureg_DECL_immediate_int(ureg, (int *)proginfo->Parameters->ParameterValues[i], 4); 4248b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 4249b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_UNSIGNED_INT: 4250b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_UNSIGNED_INT_VEC2: 4251b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_UNSIGNED_INT_VEC3: 4252b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_UNSIGNED_INT_VEC4: 4253b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_BOOL: 4254b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_BOOL_VEC2: 4255b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_BOOL_VEC3: 4256b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case GL_BOOL_VEC4: 4257b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain t->constants[i] = ureg_DECL_immediate_uint(ureg, (unsigned *)proginfo->Parameters->ParameterValues[i], 4); 4258b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 4259b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain default: 4260b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"should not get here"); 4261b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 4262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* texture samplers */ 4270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 427144867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (program->samplers_used & (1 << i)) { 4272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->samplers[i] = ureg_DECL_sampler( ureg, i ); 4273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit each instruction in turn: 4277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, program->instructions) { 4279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_insn_start( t, ureg_get_instruction_number( ureg )); 4280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain compile_tgsi_instruction( t, (glsl_to_tgsi_instruction *)iter.get() ); 4281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->prevInstWrotePointSize && proginfo->Id) { 4283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The previous instruction wrote to the (fake) vertex point size 4284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * result register. Now we need to clamp that value to the min/max 4285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * point size range, putting the result into the real point size 4286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register. 4287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Note that we can't do this easily at the end of program due to 4288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * possible early return. 4289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_insn_start( t, ureg_get_instruction_number( ureg )); 4291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_MAX( t->ureg, 4292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_writemask(t->outputs[t->pointSizeOutIndex], WRITEMASK_X), 4293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_src(t->outputs[t->pointSizeOutIndex]), 4294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_swizzle(t->pointSizeConst, 1,1,1,1)); 4295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_MIN( t->ureg, ureg_writemask(t->pointSizeResult, WRITEMASK_X), 4296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_src(t->outputs[t->pointSizeOutIndex]), 4297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_swizzle(t->pointSizeConst, 2,2,2,2)); 4298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->prevInstWrotePointSize = GL_FALSE; 4300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fix up all emitted labels: 4303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < t->labels_count; i++) { 4305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_fixup_label( ureg, 4306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels[i].token, 4307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn[t->labels[i].branch_target] ); 4308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainout: 4311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain FREE(t->insn); 4312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain FREE(t->labels); 4313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain FREE(t->constants); 4314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->error) { 4316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain debug_printf("%s: translate error flag set\n", __FUNCTION__); 4317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ret; 4320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ----------------------------- End TGSI code ------------------------------ */ 4322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 432444867da3543ca54ef245695cef72a6e305451d93Bryan Cain * Convert a shader's GLSL IR into a Mesa gl_program, although without 432544867da3543ca54ef245695cef72a6e305451d93Bryan Cain * generating Mesa IR. 4326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct gl_program * 4328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_mesa_program(struct gl_context *ctx, 4329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 4330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader) 4331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor(); 4333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog; 4334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLenum target; 4335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *target_string; 4336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean progress; 4337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_compiler_options *options = 4338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 4339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_VERTEX_PROGRAM_ARB; 4343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "vertex"; 4344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_FRAGMENT_PROGRAM_ARB; 4347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "fragment"; 4348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_GEOMETRY_PROGRAM_NV; 4351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "geometry"; 4352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(shader->ir); 4359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 4361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!prog) 4362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Parameters = _mesa_new_parameter_list(); 4364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Varying = _mesa_new_parameter_list(); 4365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Attributes = _mesa_new_parameter_list(); 4366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->ctx = ctx; 4367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->prog = prog; 4368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->shader_program = shader_program; 4369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->options = options; 4370b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain v->glsl_version = ctx->Const.GLSLVersion; 4371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain add_uniforms_to_parameters_list(shader_program, shader, prog); 4373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 437456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Emit intermediate IR for main(). */ 4375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(shader->ir, v); 4376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Now emit bodies for any functions that were used. */ 4378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 4379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_FALSE; 4380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, v->function_signatures) { 4382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = (function_entry *)iter.get(); 4383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry->bgn_inst) { 4385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->current_function = entry; 4386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 438756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB); 4388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst->function = entry; 4389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&entry->sig->body, v); 4391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *last; 4393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (glsl_to_tgsi_instruction *)v->instructions.get_tail(); 439456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (last->op != TGSI_OPCODE_RET) 439556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_RET); 4396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *end; 439856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain end = v->emit(NULL, TGSI_OPCODE_ENDSUB); 4399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain end->function = entry; 4400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_TRUE; 4402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 4405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#if 0 4407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Print out some information (for debugging purposes) used by the 4408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * optimization passes. */ 4409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < v->next_temp; i++) { 4410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fr = v->get_first_temp_read(i); 4411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fw = v->get_first_temp_write(i); 4412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lr = v->get_last_temp_read(i); 4413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lw = v->get_last_temp_write(i); 4414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw); 4416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(fw <= fr); 4417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#endif 4419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4420c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain /* Remove reads to output registers, and to varyings in vertex shaders. */ 4421c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain v->remove_output_reads(PROGRAM_OUTPUT); 4422c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain if (target == GL_VERTEX_PROGRAM_ARB) 4423c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain v->remove_output_reads(PROGRAM_VARYING); 442429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 442529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Perform the simplify_cmp optimization, which is required by r300g. */ 442629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain v->simplify_cmp(); 4427c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 4428b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. 4429b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain * FIXME: These passes to optimize temporary registers don't work when there 443016d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * is indirect addressing of the temporary register space. We need proper 443116d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * array support so that we don't have to give up these passes in every 443216d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * shader that uses arrays. 443316d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain */ 443416d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain if (!v->indirect_addr_temps) { 4435b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain v->copy_propagate(); 443641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain while (v->eliminate_dead_code_advanced()); 443716d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->eliminate_dead_code(); 44388c50f18b29637470539d05ccc32b0cae0092aeacEmil Velikov v->merge_registers(); 443916d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->renumber_registers(); 444016d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain } 444156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 444256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Write the END instruction. */ 444356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_END); 4444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ctx->Shader.Flags & GLSL_DUMP) { 4446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("GLSL IR for linked %s program %d:\n", target_string, 4448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader_program->Name); 4449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_print_ir(shader->ir, NULL); 4450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 445444867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->Instructions = NULL; 445544867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->NumInstructions = 0; 4456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do_set_program_inouts(shader->ir, prog); 44585768ed6429937940bd48f5de4f8383273952880aBryan Cain count_resources(v, prog); 4459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 446044867da3543ca54ef245695cef72a6e305451d93Bryan Cain check_resources(ctx, shader_program, v, prog); 4461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &shader->Program, prog); 4463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_vertex_program *stvp; 4465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_fragment_program *stfp; 4466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_geometry_program *stgp; 4467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp = (struct st_vertex_program *)prog; 4471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp->glsl_to_tgsi = v; 4472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp = (struct st_fragment_program *)prog; 4475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp->glsl_to_tgsi = v; 4476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp = (struct st_geometry_program *)prog; 4479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp->glsl_to_tgsi = v; 4480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return prog; 4487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" { 4490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader * 4492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 4493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader; 4495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || 4496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type == GL_GEOMETRY_SHADER_ARB); 4497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader = rzalloc(NULL, struct gl_shader); 4498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shader) { 4499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Type = type; 4500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Name = name; 4501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader(ctx, shader); 4502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shader; 4504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader_program * 4507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader_program(struct gl_context *ctx, GLuint name) 4508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shProg; 4510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg = rzalloc(NULL, struct gl_shader_program); 4511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shProg) { 4512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg->Name = name; 4513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader_program(ctx, shProg); 4514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shProg; 4516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Link a shader. 4520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Called via ctx->Driver.LinkShader() 452156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * This actually involves converting GLSL IR into an intermediate TGSI-like IR 452256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * with code lowering and other optimizations. 4523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean 4525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 4526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(prog->LinkStatus); 4528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 4531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 4532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool progress; 4534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list *ir = prog->_LinkedShaders[i]->ir; 4535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_shader_compiler_options *options = 4536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 4537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 4539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = false; 4540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Lowering */ 4542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do_mat_op_to_vec(ir); 4543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2 4544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain | LOG_TO_LOG2 4545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain | ((options->EmitNoPow) ? POW_TO_EXP2 : 0))); 4546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 4548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_common_optimization(ir, true, options->MaxUnrollIterations) || progress; 4550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_quadop_vector(ir, true) || progress; 4552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoIfs) { 4554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_discard(ir) || progress; 4555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_if_to_cond_assign(ir) || progress; 4556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoNoise) 4559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_noise(ir) || progress; 4560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are forms of indirect addressing that the driver 4562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * cannot handle, perform the lowering pass. 4563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 4565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 4566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = 4567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lower_variable_index_to_cond_assign(ir, 4568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectInput, 4569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectOutput, 4570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectTemp, 4571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectUniform) 4572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || progress; 4573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_vec_index_to_cond_assign(ir) || progress; 4575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 4576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(ir); 4578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *linked_prog; 4582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 4584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 4585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 4587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (linked_prog) { 4589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool ok = true; 4590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (prog->_LinkedShaders[i]->Type) { 4592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_vertprog(ctx, &prog->VertexProgram, 4594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (struct gl_vertex_program *)linked_prog); 4595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 4596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain linked_prog); 4597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 4600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (struct gl_fragment_program *)linked_prog); 4601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 4602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain linked_prog); 4603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_geomprog(ctx, &prog->GeometryProgram, 4606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (struct gl_geometry_program *)linked_prog); 4607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ok = ctx->Driver.ProgramStringNotify(ctx, GL_GEOMETRY_PROGRAM_NV, 4608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain linked_prog); 4609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!ok) { 4612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_FALSE; 4613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &linked_prog, NULL); 4617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_TRUE; 4620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Link a GLSL shader program. Called via glLinkProgram(). 4625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 4627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 4628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 4630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_clear_shader_program_data(ctx, prog); 4632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_TRUE; 4634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < prog->NumShaders; i++) { 4636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!prog->Shaders[i]->CompileStatus) { 4637f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(prog, "linking with uncompiled shader"); 4638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_FALSE; 4639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Varying = _mesa_new_parameter_list(); 4643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 4644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 4645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL); 4646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->LinkStatus) { 4648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain link_shaders(ctx, prog); 4649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->LinkStatus) { 4652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!ctx->Driver.LinkShader(ctx, prog)) { 4653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_FALSE; 4654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_uniform_initializers(ctx, prog); 4658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ctx->Shader.Flags & GLSL_DUMP) { 4660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!prog->LinkStatus) { 4661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("GLSL shader program %d failed to link\n", prog->Name); 4662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->InfoLog && prog->InfoLog[0] != 0) { 4665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("GLSL shader program %d info log:\n", prog->Name); 4666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("%s\n", prog->InfoLog); 4667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} /* extern "C" */ 4672