st_glsl_to_tgsi.cpp revision 105f307d90de92d088116516957e37267d9fe115
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 Cain#include "main/mtypes.h" 46f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "main/shaderobj.h" 47f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/hash_table.h" 48bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick 49bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanickextern "C" { 50bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/shaderapi.h" 51bbbb8345ab9df2d634dc2a34d257ee2cbf930292Ian Romanick#include "main/uniforms.h" 52f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_instruction.h" 53f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_optimize.h" 54f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/prog_print.h" 55f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#include "program/program.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 737732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain#define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX 74f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ 75f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_ENV_PARAM) | \ 76f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_STATE_VAR) | \ 77f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_NAMED_PARAM) | \ 78f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_CONSTANT) | \ 79f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (1 << PROGRAM_UNIFORM)) 80f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 81794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca/** 82794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca * Maximum number of temporary registers. 83794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca * 84794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca * It is too big for stack allocated arrays -- it will cause stack overflow on 85794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca * Windows and likely Mac OS X. 86794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca */ 8733e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain#define MAX_TEMPS 4096 8833e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain 892083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie/* will be 4 for GLSL 4.00 */ 902083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie#define MAX_GLSL_TEXTURE_OFFSET 1 912083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 92f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_src_reg; 93f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_dst_reg; 94f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 95f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int swizzle_for_size(int size); 96f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 97f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 9856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * This struct is a corresponding struct to TGSI ureg_src. 99f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_src_reg { 101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg(gl_register_file file, int index, const glsl_type *type) 103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = file; 105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = index; 106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = swizzle_for_size(type->vector_elements); 108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = SWIZZLE_XYZW; 110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 111b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type ? type->base_type : GLSL_TYPE_ERROR; 112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 115b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg(gl_register_file file, int index, int type) 116c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain { 117b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type; 118c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->file = file; 119c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->index = index; 120c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->swizzle = SWIZZLE_XYZW; 121c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->negate = 0; 122c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain this->reladdr = NULL; 123c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain } 124c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg() 126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 127b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = GLSL_TYPE_ERROR; 128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = PROGRAM_UNDEFINED; 129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = 0; 131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain explicit st_src_reg(st_dst_reg reg); 136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; /**< PROGRAM_* from Mesa */ 138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int negate; /**< NEGATE_XYZW mask from mesa */ 141b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Register index should be offset by the integer in this reg. */ 143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reladdr; 144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass st_dst_reg { 147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 148b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg(gl_register_file file, int writemask, int type) 149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = file; 151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = writemask; 153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 155b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = type; 156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg() 159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 160b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = GLSL_TYPE_ERROR; 161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = PROGRAM_UNDEFINED; 162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = 0; 163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = 0; 164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = NULL; 166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain explicit st_dst_reg(st_src_reg reg); 169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; /**< PROGRAM_* from Mesa */ 171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint cond_mask:4; 174b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Register index should be offset by the integer in this reg. */ 176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reladdr; 177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_src_reg::st_src_reg(st_dst_reg reg) 180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 181b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = reg.type; 182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = reg.file; 183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = reg.index; 184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->swizzle = SWIZZLE_XYZW; 185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->negate = 0; 186189e9f12c7d3a82d7dd28695935a83e4319bb267Bryan Cain this->reladdr = reg.reladdr; 187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_dst_reg::st_dst_reg(st_src_reg reg) 190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 191b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain this->type = reg.type; 192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->file = reg.file; 193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->index = reg.index; 194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->writemask = WRITEMASK_XYZW; 195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->cond_mask = COND_TR; 196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->reladdr = reg.reladdr; 197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass glsl_to_tgsi_instruction : public exec_node { 200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Callers of this ralloc-based new need not call delete. It's 202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static void* operator new(size_t size, void *ctx) 204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *node; 206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain node = rzalloc_size(ctx, size); 208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(node != NULL); 209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return node; 211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 21356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain unsigned op; 214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst; 215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src[3]; 216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Pointer to the ir source this tree came from for debugging */ 217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir; 218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean cond_update; 219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool saturate; 220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int sampler; /**< sampler index */ 221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int tex_target; /**< One of TEXTURE_*_INDEX */ 222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLboolean tex_shadow; 2232083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; 2242083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie unsigned tex_offset_num_offset; 22541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int dead_mask; /**< Used in dead code elimination */ 226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 22756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */ 228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass variable_storage : public exec_node { 231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage(ir_variable *var, gl_register_file file, int index) 233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain : file(file), index(index), var(var) 234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* empty */ 236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain gl_register_file file; 239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index; 240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var; /* variable that maps to this, if any */ 241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2433354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainclass immediate_storage : public exec_node { 2443354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainpublic: 2453354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain immediate_storage(gl_constant_value *values, int size, int type) 2463354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain { 2473354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain memcpy(this->values, values, size * sizeof(gl_constant_value)); 2483354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->size = size; 2493354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->type = type; 2503354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 2513354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 2523354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_constant_value values[4]; 2533354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int size; /**< Number of components (1-4) */ 2543354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int type; /**< GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */ 2553354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain}; 2563354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass function_entry : public exec_node { 258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_function_signature *sig; 260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * identifier of this function signature used by the program. 263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 264f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * At the point that TGSI instructions for function calls are 265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generated, we don't know the address of the first instruction of 266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the function body. So we make the BranchTarget that is called a 267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * small integer and rewrite them during set_branchtargets(). 268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int sig_id; 270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Pointer to first instruction of the function body. 273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Set during function body emits after main() is processed. 275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *bgn_inst; 277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 279f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Index of the first instruction of the function body in actual TGSI. 280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 281f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Set after conversion from glsl_to_tgsi_instruction to TGSI. 282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int inst; 284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** Storage for the return value. */ 286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg return_reg; 287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainclass glsl_to_tgsi_visitor : public ir_visitor { 290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainpublic: 291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor(); 292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ~glsl_to_tgsi_visitor(); 293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *current_function; 295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_context *ctx; 297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog; 298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program; 299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_compiler_options *options; 300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int next_temp; 30244867da3543ca54ef245695cef72a6e305451d93Bryan Cain 303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int num_address_regs; 30444867da3543ca54ef245695cef72a6e305451d93Bryan Cain int samplers_used; 305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool indirect_addr_temps; 306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool indirect_addr_consts; 30759be691638200797583bce39a83f641d30d97492Bryan Cain int num_clip_distances; 308b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 309b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int glsl_version; 31001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke bool native_integers; 311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *find_variable_storage(ir_variable *var); 313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3143354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int add_constant(gl_register_file file, gl_constant_value values[4], 3153354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int size, int datatype, GLuint *swizzle_out); 3163354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *get_function_signature(ir_function_signature *sig); 318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg get_temp(const glsl_type *type); 320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr); 321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg st_src_reg_for_float(float val); 323b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_int(int val); 324b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_type(int type, int val); 325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \name Visit methods 328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * As typical for the visitor pattern, there must be one \c visit method for 330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each concrete subclass of \c ir_instruction. Virtual base classes within 331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the hierarchy should not have \c visit methods. 332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@{*/ 334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_variable *); 335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop *); 336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop_jump *); 337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function_signature *); 338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function *); 339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_expression *); 340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_swizzle *); 341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_variable *); 342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_array *); 343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_record *); 344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_assignment *); 345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_constant *); 346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_call *); 347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_return *); 348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_discard *); 349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_texture *); 350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_if *); 351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@}*/ 352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result; 354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of variable_storage */ 356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list variables; 357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3583354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /** List of immediate_storage */ 3593354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain exec_list immediates; 360fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul unsigned num_immediates; 3613354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of function_entry */ 363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list function_signatures; 364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int next_signature_id; 365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of glsl_to_tgsi_instruction */ 367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list instructions; 368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 36956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op); 370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2); 380b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 381b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain unsigned get_opcode(ir_instruction *ir, unsigned op, 382b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 383b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1); 384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit the correct dot-product instruction for the type of arguments 387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 388c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir, 389c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_dst_reg dst, 390c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_src_reg src0, 391c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_src_reg src1, 392c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain unsigned elements); 393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 39456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 39756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4000dc575c6f6157867accf749a06ec745617ea64acBryan Cain void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst); 4010dc575c6f6157867accf749a06ec745617ea64acBryan Cain 402b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); 403b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 40456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scs(ir_instruction *ir, unsigned op, 405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, const st_src_reg &src); 406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 40779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_mad(ir_expression *ir, 40879a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch int mul_operand); 4095379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain bool try_emit_mad_for_and_not(ir_expression *ir, 4105379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain int mul_operand); 41179a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_sat(ir_expression *ir); 412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void emit_swz(ir_expression *ir); 414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool process_move_condition(ir_rvalue *ir); 416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 41729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain void simplify_cmp(void); 418c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void rename_temp_register(int index, int new_index); 420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_read(int index); 421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_write(int index); 422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_read(int index); 423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_write(int index); 424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void copy_propagate(void); 426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void eliminate_dead_code(void); 42741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int eliminate_dead_code_advanced(void); 428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void merge_registers(void); 429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void renumber_registers(void); 430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *mem_ctx; 432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 434552cc48fca9b932fceb3d8fa7f9d0067f46b67c2Bryan Cainstatic st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); 435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 436b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); 437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 438b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); 439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); 442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) 445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_list args; 447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_start(args, fmt); 448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_vasprintf_append(&prog->InfoLog, fmt, args); 449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_end(args); 450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_FALSE; 452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainswizzle_for_size(int size) 456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size_swizzles[4] = { 458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((size >= 1) && (size <= 4)); 465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size_swizzles[size - 1]; 466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 46856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic bool 46956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainis_tex_instruction(unsigned opcode) 47056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 47156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 47256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex; 47356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 47456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 47556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 47656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_dst_regs(unsigned opcode) 47756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 47856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 47956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->num_dst; 48056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 48156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 48256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 48356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_src_regs(unsigned opcode) 48456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 48556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 48656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex ? info->num_src - 1 : info->num_src; 48756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 48856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 49056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2) 493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); 495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int num_reladdr = 0, i; 496b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 497b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op = get_opcode(ir, op, dst, src0, src1); 498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If we have to do relative addressing, we want to load the ARL 500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * reg directly for one of the regs, and preload the other reladdr 501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sources into temps. 502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += dst.reladdr != NULL; 504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src0.reladdr != NULL; 505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src1.reladdr != NULL; 506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src2.reladdr != NULL; 507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src2, &num_reladdr); 509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src1, &num_reladdr); 510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src0, &num_reladdr); 511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 513b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *dst.reladdr); 514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr--; 515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(num_reladdr == 0); 517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->op = op; 519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst = dst; 520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[0] = src0; 521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[1] = src1; 522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[2] = src2; 523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->ir = ir; 52441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dead_mask = 0; 525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->function = NULL; 527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 52810dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL) 529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->num_address_regs = 1; 530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update indirect addressing status used by TGSI */ 532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch(dst.file) { 534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 5457732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 5467732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"immediates should not have indirect addressing"); 5477732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain break; 548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i<3; i++) { 554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(inst->src[i].reladdr) { 55516d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain switch(inst->src[i].file) { 556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 5677732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 5687732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"immediates should not have indirect addressing"); 5697732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain break; 570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(inst); 5780dc575c6f6157867accf749a06ec745617ea64acBryan Cain 5790dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 5800dc575c6f6157867accf749a06ec745617ea64acBryan Cain try_emit_float_set(ir, op, dst); 5810dc575c6f6157867accf749a06ec745617ea64acBryan Cain 582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return inst; 583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 58756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1) 589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, src1, undef_src); 591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 59456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(dst.writemask != 0); 598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, undef_src, undef_src); 599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 60256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) 603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 6070dc575c6f6157867accf749a06ec745617ea64acBryan Cain /** 6080dc575c6f6157867accf749a06ec745617ea64acBryan Cain * Emits the code to convert the result of float SET instructions to integers. 6090dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 6100dc575c6f6157867accf749a06ec745617ea64acBryan Cainvoid 6110dc575c6f6157867accf749a06ec745617ea64acBryan Cainglsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op, 6120dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_dst_reg dst) 6130dc575c6f6157867accf749a06ec745617ea64acBryan Cain{ 6140dc575c6f6157867accf749a06ec745617ea64acBryan Cain if ((op == TGSI_OPCODE_SEQ || 6150dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SNE || 6160dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SGE || 6170dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SLT)) 6180dc575c6f6157867accf749a06ec745617ea64acBryan Cain { 6190dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg src = st_src_reg(dst); 6200dc575c6f6157867accf749a06ec745617ea64acBryan Cain src.negate = ~src.negate; 6210dc575c6f6157867accf749a06ec745617ea64acBryan Cain dst.type = GLSL_TYPE_FLOAT; 6220dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_F2I, dst, src); 6230dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 6240dc575c6f6157867accf749a06ec745617ea64acBryan Cain} 6250dc575c6f6157867accf749a06ec745617ea64acBryan Cain 626b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain/** 627b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * Determines whether to use an integer, unsigned integer, or float opcode 628b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * based on the operands and input opcode, then emits the result. 629b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain */ 630b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainunsigned 631b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, 632b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 633b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1) 634b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 635b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type = GLSL_TYPE_FLOAT; 636b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 637b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) 638b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain type = GLSL_TYPE_FLOAT; 63901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke else if (native_integers) 6400dc575c6f6157867accf749a06ec745617ea64acBryan Cain type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type; 641b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 642b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case4(c, f, i, u) \ 643b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case TGSI_OPCODE_##c: \ 644b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \ 645b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \ 646b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else op = TGSI_OPCODE_##f; \ 647b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 648b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case3(f, i, u) case4(f, f, i, u) 649b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2fi(f, i) case4(f, f, i, i) 650b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2iu(i, u) case4(i, LAST, i, u) 651b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 652b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain switch(op) { 653b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(ADD, UADD); 654b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MUL, UMUL); 655b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MAD, UMAD); 656b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(DIV, IDIV, UDIV); 657b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MAX, IMAX, UMAX); 658b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MIN, IMIN, UMIN); 659b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(MOD, UMOD); 660b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 661b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SEQ, USEQ); 662b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SNE, USNE); 663b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SGE, ISGE, USGE); 664b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SLT, ISLT, USLT); 665b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 666b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(ISHR, USHR); 667cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie 668cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie case2fi(SSG, ISSG); 669cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie case3(ABS, IABS, IABS); 670b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 671b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain default: break; 672b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 673b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 674b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(op != TGSI_OPCODE_LAST); 675b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return op; 676b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 677b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 678c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cainglsl_to_tgsi_instruction * 679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, 680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1, 681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned elements) 682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 68356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain static const unsigned dot_opcodes[] = { 68456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 687c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 69156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emits TGSI scalar opcodes to produce unique answers across channels. 692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 69356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Some TGSI opcodes are scalar-only, like ARB_fp/vp. The src X 694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel determines the result across all channels. So to do a vec4 695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this operation, we want to emit a scalar per source channel used 696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * to produce dest channels. 697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 69956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg orig_src0, st_src_reg orig_src1) 702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 70656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI RCP is a scalar operation splatting results to all channels, 707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * dst channels. 709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint this_mask = (1 << i); 712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = orig_src0; 714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src1 = orig_src1; 715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (done_mask & this_mask) 717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (j = i + 1; j < 4; j++) { 722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz && 728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src1.swizzle, j) == src1_swiz) { 729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1_swiz, src1_swiz); 736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, op, dst, src0, src1); 738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 74456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg undef = undef_src; 748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain undef.swizzle = SWIZZLE_XXXX; 750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src0, undef); 752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 754b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainvoid 755b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, 756b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, st_src_reg src0) 757b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 75810dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain int op = TGSI_OPCODE_ARL; 75910dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain 76010dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) 76110dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain op = TGSI_OPCODE_UARL; 76210dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain 76310dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain emit(NULL, op, dst, src0); 764b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 765b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 76756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emit an TGSI_OPCODE_SCS instruction 768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 76956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * The \c SCS opcode functions a bit differently than the other TGSI opcodes. 77056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Instead of splatting its result across all four components of the 77156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * destination, it writes one value to the \c x component and another value to 77256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the \c y component. 773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param ir IR instruction being processed 77556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending 77656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * on which value is desired. 777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param dst Destination register 778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param src Source register 779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 78156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, 782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const st_src_reg &src) 784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Vertex programs cannot use the SCS opcode. 786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src); 789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 79256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1; 793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const unsigned scs_mask = (1U << component); 794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp; 796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 79756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS); 798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are compnents in the destination that differ from the component 800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * that will be written by the SCS instrution, we'll need a temporary. 801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (scs_mask != unsigned(dst.writemask)) { 803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp = get_temp(glsl_type::vec4_type); 804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < 4; i++) { 807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned this_mask = (1U << i); 808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = src; 809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((done_mask & this_mask) != 0) 811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The source swizzle specified which component of the source generates 814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sine / cosine for the current component in the destination. The SCS 815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction requires that this value be swizzle to the X component. 816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Replace the current swizzle with a swizzle that puts the source in 817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the X component. 818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned src0_swiz = GET_SWZ(src.swizzle, i); 820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned j = i + 1; j < 4; j++) { 824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz) { 830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this_mask != scs_mask) { 835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp); 837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction. 839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 84056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0); 841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Move the result of the SCS instruction to the desired location in 844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the destination. 845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp.swizzle = MAKE_SWIZZLE4(component, component, 847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain component, component); 84856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp); 849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction to write directly to the destination. 852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 85356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0); 854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 8613354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainint 8623354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainglsl_to_tgsi_visitor::add_constant(gl_register_file file, 8633354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_constant_value values[4], int size, int datatype, 8643354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain GLuint *swizzle_out) 8653354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain{ 8663354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain if (file == PROGRAM_CONSTANT) { 8673354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values, 8683354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain size, datatype, swizzle_out); 8693354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } else { 8703354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int index = 0; 8713354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain immediate_storage *entry; 8723354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain assert(file == PROGRAM_IMMEDIATE); 8733354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8743354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /* Search immediate storage to see if we already have an identical 8753354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain * immediate that we can use instead of adding a duplicate entry. 8763354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain */ 8773354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain foreach_iter(exec_list_iterator, iter, this->immediates) { 8783354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry = (immediate_storage *)iter.get(); 8793354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8803354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain if (entry->size == size && 8813354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry->type == datatype && 8823354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain !memcmp(entry->values, values, size * sizeof(gl_constant_value))) { 8833354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return index; 8843354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8853354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain index++; 8863354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8873354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8883354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /* Add this immediate to the list. */ 8893354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry = new(mem_ctx) immediate_storage(values, size, datatype); 8903354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->immediates.push_tail(entry); 8913354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->num_immediates++; 8923354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return index; 8933354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8943354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain} 8953354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8967a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::st_src_reg_for_float(float val) 898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 8997732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT); 9006d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain union gl_constant_value uval; 901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 9026d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain uval.f = val; 9033354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(src.file, &uval, 1, GL_FLOAT, &src.swizzle); 904b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 905b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return src; 906b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 907b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 9087a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 909b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_int(int val) 910b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 9117732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT); 912b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain union gl_constant_value uval; 913b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 91401d81dedc795005ed235856ce762bb1981655716Kenneth Graunke assert(native_integers); 915b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 916b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain uval.i = val; 9173354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle); 918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 9227a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 923b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) 924b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 92501d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 926b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : 927b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg_for_int(val); 928b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 929b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return st_src_reg_for_float(val); 930b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 931b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caintype_size(const struct glsl_type *type) 934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size; 937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (type->base_type) { 939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_matrix()) { 944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type->matrix_columns; 945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Regardless of size of vector, it gets a vec4. This is bad 947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * packing for things like floats, but otherwise arrays become a 948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * mess. Hopefully a later pass over the code can pack scalars 949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * down if appropriate. 950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_ARRAY: 954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type->length > 0); 955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type_size(type->fields.array) * type->length; 956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_STRUCT: 957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size = 0; 958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type->length; i++) { 959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size += type_size(type->fields.structure[i].type); 960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size; 962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_SAMPLER: 963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Samplers take up one slot in UNIFORMS[], but they're baked in 964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * at link time. 965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 0; 970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * In the initial pass of codegen, we assign temporary numbers to 975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * intermediate results. (not SSA -- variable assignments will reuse 976b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * storage). 977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_src_reg 979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_temp(const glsl_type *type) 980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 98301d81dedc795005ed235856ce762bb1981655716Kenneth Graunke src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT; 984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.file = PROGRAM_TEMPORARY; 985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index = next_temp; 986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = NULL; 987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(type); 988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array() || type->is_record()) { 990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 9925164244df02f33d6ad9e0a286f4b6d6af2dfbc75Bryan Cain src.swizzle = swizzle_for_size(type->vector_elements); 993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 994f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.negate = 0; 995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 997f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvariable_storage * 1000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) 1001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry; 1004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->variables) { 1006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (variable_storage *)iter.get(); 1007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->var == var) 1009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 1010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 1013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_variable *ir) 1017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "gl_FragCoord") == 0) { 1019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 1020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->OriginUpperLeft = ir->origin_upper_left; 1022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->PixelCenterInteger = ir->pixel_center_integer; 1023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 1026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 1027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_state_slot *const slots = ir->state_slots; 1028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->state_slots != NULL); 1029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Check if this statevar's setup in the STATE file exactly 1031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * matches how we'll want to reference it as a 1032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * struct/array/whatever. If not, then we need to move it into 1033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * temporary storage and hope that it'll get copy-propagated 1034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * out. 1035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->num_state_slots; i++) { 1037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (slots[i].swizzle != SWIZZLE_XYZW) { 1038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 10427a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunke variable_storage *storage; 1043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst; 1044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i == ir->num_state_slots) { 1045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We'll set the index later. */ 1046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 1047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 1048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = undef_dst; 1050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The variable_storage constructor allocates slots based on the size 1052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of the type. However, this had better match the number of state 1053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * elements that we're going to copy into the new temporary. 1054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((int) ir->num_state_slots == type_size(ir->type)); 1056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 1058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 1059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 1060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(ir->type); 1061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1062b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, 106301d81dedc795005ed235856ce762bb1981655716Kenneth Graunke native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT)); 1064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < ir->num_state_slots; i++) { 1068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index = _mesa_add_state_reference(this->prog->Parameters, 1069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index *)slots[i].tokens); 1070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_STATE_VAR) { 1072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->index == -1) { 1073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage->index = index; 1074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index == storage->index + (int)i); 1076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1078b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src(PROGRAM_STATE_VAR, index, 107901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT); 1080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = slots[i].swizzle; 108156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, dst, src); 1082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* even a float takes up a whole vec4 reg in a struct/array. */ 1083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index++; 1084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_TEMPORARY && 1088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index != storage->index + (int) ir->num_state_slots) { 1089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(this->shader_program, 1090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", 1091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->name, dst.index - storage->index, 1092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type_size(ir->type)); 1093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop *ir) 1099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_variable *counter = NULL; 1101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->counter != NULL) 1103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter = new(ir) ir_dereference_variable(ir->counter); 1104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->from != NULL) { 1106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->counter != NULL); 1107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); 1109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 111456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BGNLOOP); 1115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->to) { 1117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir->cmp, glsl_type::bool_type, 1119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->to); 1120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_if *if_stmt = new(ir) ir_if(e); 1121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); 1123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->then_instructions.push_tail(brk); 1125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->accept(this); 1127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete if_stmt; 1129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete brk; 1131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->body_instructions, this); 1134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->increment) { 1136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir_binop_add, counter->type, 1138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->increment); 1139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); 1141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 114756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_ENDLOOP); 1148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop_jump *ir) 1152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->mode) { 1154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_break: 115556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BRK); 1156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_continue: 115856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_CONT); 1159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function_signature *ir) 1166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 1168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (void)ir; 1169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function *ir) 1173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Ignore function bodies other than main() -- we shouldn't see calls to 1175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * them since they should all be inlined before we get to glsl_to_tgsi. 1176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "main") == 0) { 1178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_function_signature *sig; 1179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list empty; 1180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig = ir->matching_signature(&empty); 1182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(sig); 1184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->body) { 1186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir = (ir_instruction *)iter.get(); 1187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(this); 1189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 119379a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 1194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 1195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int nonmul_operand = 1 - mul_operand; 1197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg a, b, c; 11983bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain st_dst_reg result_dst; 1199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *expr = ir->operands[mul_operand]->as_expression(); 1201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!expr || expr->operation != ir_binop_mul) 1202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[0]->accept(this); 1205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a = this->result; 1206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[1]->accept(this); 1207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain b = this->result; 1208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[nonmul_operand]->accept(this); 1209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain c = this->result; 1210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = get_temp(ir->type); 12123bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst = st_dst_reg(this->result); 12133bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 12143bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c); 1215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 12195379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain/** 12205379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * Emit MAD(a, -b, a) instead of AND(a, NOT(b)) 12215379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12225379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * The logic values are 1.0 for true and 0.0 for false. Logical-and is 12235379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * implemented using multiplication, and logical-or is implemented using 12245379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 12255379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * As result, the logical expression (a & !b) can be rewritten as: 12265379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12275379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a * !b 12285379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a * (1 - b) 12295379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - (a * 1) - (a * b) 12305379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a + -(a * b) 12315379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a + (a * -b) 12325379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12335379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * This final expression can be implemented as a single MAD(a, -b, a) 12345379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * instruction. 12355379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain */ 12365379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cainbool 12375379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cainglsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 12385379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain{ 12395379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain const int other_operand = 1 - try_operand; 12405379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain st_src_reg a, b; 12415379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12425379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain ir_expression *expr = ir->operands[try_operand]->as_expression(); 12435379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (!expr || expr->operation != ir_unop_logic_not) 12445379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return false; 12455379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12465379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain ir->operands[other_operand]->accept(this); 12475379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain a = this->result; 12485379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain expr->operands[0]->accept(this); 12495379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain b = this->result; 12505379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12515379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain b.negate = ~b.negate; 12525379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12535379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain this->result = get_temp(ir->type); 12545379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a); 12555379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12565379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return true; 12575379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain} 12585379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 125979a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 1260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir) 1261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Saturates were only introduced to vertex programs in 1263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * NV_vertex_program3, so don't give them to drivers in the VP. 1264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 1266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 1269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sat_src) 1270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sat_src->accept(this); 1273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src = this->result; 1274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1275b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain /* If we generated an expression instruction into a temporary in 1276b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * processing the saturate's operand, apply the saturate to that 1277b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * instruction. Otherwise, generate a MOV to do the saturate. 1278b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * 1279b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * Note that we have to be careful to only do this optimization if 1280b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * the instruction in question was what generated src->result. For 1281b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * example, ir_dereference_array might generate a MUL instruction 1282b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * to create the reladdr, and return us a src reg using that 1283b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * reladdr. That MUL result is not the value we're trying to 1284b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * saturate. 1285b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain */ 1286b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain ir_expression *sat_src_expr = sat_src->as_expression(); 1287b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 1288b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain sat_src_expr->operation == ir_binop_add || 1289b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain sat_src_expr->operation == ir_binop_dot)) { 1290b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain glsl_to_tgsi_instruction *new_inst; 1291b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain new_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 1292b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain new_inst->saturate = true; 1293b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain } else { 1294b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain this->result = get_temp(ir->type); 1295b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain st_dst_reg result_dst = st_dst_reg(this->result); 1296b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1297b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain glsl_to_tgsi_instruction *inst; 1298b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain inst = emit(ir, TGSI_OPCODE_MOV, result_dst, src); 1299b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain inst->saturate = true; 1300b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain } 1301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, 1307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reg, int *num_reladdr) 1308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!reg->reladdr) 1310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1312b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *reg->reladdr); 1313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (*num_reladdr != 1) { 1315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::vec4_type); 1316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 131756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg); 1318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain *reg = temp; 1319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (*num_reladdr)--; 1322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_expression *ir) 1326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int operand; 1328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg op[Elements(ir->operands)]; 1329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result_src; 1330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst; 1331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 133256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c) 1333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operation == ir_binop_add) { 1335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 1)) 1336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 0)) 1338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 13405379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 13415379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 13425379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain */ 13435379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (ir->operation == ir_binop_logic_and) { 13445379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (try_emit_mad_for_and_not(ir, 1)) 13455379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return; 13465379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (try_emit_mad_for_and_not(ir, 0)) 13475379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return; 13485379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain } 13495379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 1350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_sat(ir)) 1351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 135356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->operation == ir_quadop_vector) 135456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(!"ir_quadop_vector should have been lowered"); 1355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (operand = 0; operand < ir->get_num_operands(); operand++) { 1357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(this); 1359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->result.file == PROGRAM_UNDEFINED) { 1360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_print_visitor v; 1361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to get tree for expression operand:\n"); 1362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(&v); 1363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[operand] = this->result; 1366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Matrix expression operands should have been broken down to vector 1368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operations already. 1369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->operands[operand]->type->is_matrix()); 1371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int vector_elements = ir->operands[0]->type->vector_elements; 1374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[1]) { 1375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain vector_elements = MAX2(vector_elements, 1376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->vector_elements); 1377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 1382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 1383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = get_temp(ir->type); 1385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* convenience for the emit functions below. */ 1386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 1387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Limit writes to the channels that will be used by result_src later. 1388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This does limit this temp's use as a temporary for multi-instruction 1389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sequences. 1390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->operation) { 1394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_logic_not: 13958c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain if (result_dst.type != GLSL_TYPE_FLOAT) 13960dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 13978c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain else { 13988c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 13998c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * older GPUs implement SEQ using multiple instructions (i915 uses two 14008c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * SGE instructions and a MUL instruction). Since our logic values are 14018c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * 0.0 and 1.0, 1-x also implements !x. 14028c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain */ 14038c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain op[0].negate = ~op[0].negate; 14048c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0)); 14058c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain } 1406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_neg: 1408c4529d10bed098b8d3d694f2a333f9afabbabbf9Bryan Cain if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT) 1409b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 1410b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else { 1411b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op[0].negate = ~op[0].negate; 1412b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain result_src = op[0]; 1413b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_abs: 1416cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]); 1417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sign: 141956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]); 1420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rcp: 142256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]); 1423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp2: 142656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]); 1427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp: 1429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log: 1430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"not reached: should be handled by ir_explog_to_explog2"); 1431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log2: 143356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]); 1434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin: 143656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos: 143956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin_reduced: 144256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos_reduced: 144556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdx: 144956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]); 1450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdy: 14523b0858f1aed83e2d90449f042d625c86ac7b93edBryan Cain op[0].negate = ~op[0].negate; 145356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_DDY, result_dst, op[0]); 1454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_noise: { 1457a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain /* At some point, a motivated person could add a better 1458a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * implementation of noise. Currently not even the nvidia 1459a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * binary drivers do anything more than this. In any case, the 1460a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * place to do this is in the GL state tracker, not the poor 1461a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * driver. 1462a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain */ 146356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5)); 1464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_add: 146856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 1469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_sub: 147156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]); 1472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mul: 147556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_div: 1478b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1479b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1480b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1481b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]); 1482b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mod: 1484b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1485b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1486b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1487b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]); 1488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 149156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]); 1492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 14940dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]); 1495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 14970dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]); 1498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 150056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]); 1501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_equal: 150356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_nequal: 150656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_all_equal: 1509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "==" operator producing a scalar boolean. */ 1510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 151201d81dedc795005ed235856ce762bb1981655716Kenneth Graunke st_src_reg temp = get_temp(native_integers ? 15131141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1514b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 15159098953ee6e0699e13e35183c817ecf40363d538Bryan Cain 15166da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (native_integers) { 15176da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 15186da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 15196da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15206da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]); 15216da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15226da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Emit 1-3 AND operations to combine the SEQ results. */ 15236da8c21124152c68fb968b196895f2c881a24280Bryan Cain switch (ir->operands[0]->type->vector_elements) { 15246da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 2: 15256da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15266da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 3: 15276da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15286da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_YYYY; 15296da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_ZZZZ; 15306da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15316da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15326da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 4: 15336da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_X; 15346da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 15356da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 15366da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15376da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15386da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_ZZZZ; 15396da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_WWWW; 15406da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15416da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 15426da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15436da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 15446da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 15456da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2); 15466da8c21124152c68fb968b196895f2c881a24280Bryan Cain } else { 15476da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 15486da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15496da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* After the dot-product, the value will be an integer on the 15506da8c21124152c68fb968b196895f2c881a24280Bryan Cain * range [0,4]. Zero becomes 1.0, and positive values become zero. 15516da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 15526da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 15536da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15549098953ee6e0699e13e35183c817ecf40363d538Bryan Cain /* Negating the result of the dot-product gives values on the range 15559098953ee6e0699e13e35183c817ecf40363d538Bryan Cain * [-4, 0]. Zero becomes 1.0, and negative values become zero. 15569098953ee6e0699e13e35183c817ecf40363d538Bryan Cain * This is achieved using SGE. 15579098953ee6e0699e13e35183c817ecf40363d538Bryan Cain */ 15589098953ee6e0699e13e35183c817ecf40363d538Bryan Cain st_src_reg sge_src = result_src; 15599098953ee6e0699e13e35183c817ecf40363d538Bryan Cain sge_src.negate = ~sge_src.negate; 15609098953ee6e0699e13e35183c817ecf40363d538Bryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0)); 15619098953ee6e0699e13e35183c817ecf40363d538Bryan Cain } 1562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 156356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_any_nequal: 1567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "!=" operator producing a scalar boolean. */ 1568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 157001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke st_src_reg temp = get_temp(native_integers ? 15711141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1572b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 157356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1574f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain 15756da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (native_integers) { 15766da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 15776da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 15786da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15796da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Emit 1-3 OR operations to combine the SNE results. */ 15806da8c21124152c68fb968b196895f2c881a24280Bryan Cain switch (ir->operands[0]->type->vector_elements) { 15816da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 2: 15826da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15836da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 3: 15846da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15856da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_YYYY; 15866da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_ZZZZ; 15876da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 15886da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15896da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 4: 15906da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_X; 15916da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 15926da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 15936da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 15946da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15956da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_ZZZZ; 15966da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_WWWW; 15976da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 15986da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 15996da8c21124152c68fb968b196895f2c881a24280Bryan Cain 16006da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 16016da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 16026da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2); 1603f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain } else { 16046da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* After the dot-product, the value will be an integer on the 16056da8c21124152c68fb968b196895f2c881a24280Bryan Cain * range [0,4]. Zero stays zero, and positive values become 1.0. 16066da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16076da8c21124152c68fb968b196895f2c881a24280Bryan Cain glsl_to_tgsi_instruction *const dp = 16086da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 16096da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 16106da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* The clamping to [0,1] can be done for free in the fragment 16116da8c21124152c68fb968b196895f2c881a24280Bryan Cain * shader with a saturate. 16126da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16136da8c21124152c68fb968b196895f2c881a24280Bryan Cain dp->saturate = true; 16146da8c21124152c68fb968b196895f2c881a24280Bryan Cain } else { 16156da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Negating the result of the dot-product gives values on the range 16166da8c21124152c68fb968b196895f2c881a24280Bryan Cain * [-4, 0]. Zero stays zero, and negative values become 1.0. This 16176da8c21124152c68fb968b196895f2c881a24280Bryan Cain * achieved using SLT. 16186da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16196da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg slt_src = result_src; 16206da8c21124152c68fb968b196895f2c881a24280Bryan Cain slt_src.negate = ~slt_src.negate; 16216da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 16226da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 1623f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain } 1624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 162556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1629a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain case ir_unop_any: { 1630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1631a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain 1632a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* After the dot-product, the value will be an integer on the 1633a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * range [0,4]. Zero stays zero, and positive values become 1.0. 1634a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1635a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain glsl_to_tgsi_instruction *const dp = 1636a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit_dp(ir, result_dst, op[0], op[0], 1637a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain ir->operands[0]->type->vector_elements); 1638a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && 1639a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain result_dst.type == GLSL_TYPE_FLOAT) { 1640a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* The clamping to [0,1] can be done for free in the fragment 1641a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * shader with a saturate. 1642a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1643a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain dp->saturate = true; 1644a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } else if (result_dst.type == GLSL_TYPE_FLOAT) { 1645a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* Negating the result of the dot-product gives values on the range 1646a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1647a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * is achieved using SLT. 1648a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1649a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain st_src_reg slt_src = result_src; 1650a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain slt_src.negate = ~slt_src.negate; 1651a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 1652a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1653a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain else { 1654a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* Use SNE 0 if integers are being used as boolean values. */ 1655a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); 1656a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1658a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_xor: 16610dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 16620dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 16630dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 16640dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1667691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain case ir_binop_logic_or: { 16680dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 16690dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* If integers are used as booleans, we can use an actual "or" 16700dc575c6f6157867accf749a06ec745617ea64acBryan Cain * instruction. 1671691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain */ 16720dc575c6f6157867accf749a06ec745617ea64acBryan Cain assert(native_integers); 16730dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1674691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } else { 16750dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* After the addition, the value will be an integer on the 16760dc575c6f6157867accf749a06ec745617ea64acBryan Cain * range [0,2]. Zero stays zero, and positive values become 1.0. 1677691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain */ 16780dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_to_tgsi_instruction *add = 16790dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 16800dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 16810dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* The clamping to [0,1] can be done for free in the fragment 16820dc575c6f6157867accf749a06ec745617ea64acBryan Cain * shader with a saturate if floats are being used as boolean values. 16830dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 16840dc575c6f6157867accf749a06ec745617ea64acBryan Cain add->saturate = true; 16850dc575c6f6157867accf749a06ec745617ea64acBryan Cain } else { 16860dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Negating the result of the addition gives values on the range 16870dc575c6f6157867accf749a06ec745617ea64acBryan Cain * [-2, 0]. Zero stays zero, and negative values become 1.0. This 16880dc575c6f6157867accf749a06ec745617ea64acBryan Cain * is achieved using SLT. 16890dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 16900dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg slt_src = result_src; 16910dc575c6f6157867accf749a06ec745617ea64acBryan Cain slt_src.negate = ~slt_src.negate; 16920dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 16930dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 1694691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } 1695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1696691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } 1697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_and: 16990dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* If native integers are disabled, the bool args are stored as float 0.0 17000dc575c6f6157867accf749a06ec745617ea64acBryan Cain * or 1.0, so "mul" gives us "and". If they're enabled, just use the 17010dc575c6f6157867accf749a06ec745617ea64acBryan Cain * actual AND opcode. 17020dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17030dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 17040dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 17050dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 17060dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_dot: 1710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type == ir->operands[1]->type); 1712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, op[0], op[1], 1713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[0]->type->vector_elements); 1714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sqrt: 1717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* sqrt(x) = x * rsq(x). */ 171856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 171956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); 1720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For incoming channels <= 0, set the result to 0. */ 1721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0].negate = ~op[0].negate; 172256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_CMP, result_dst, 1723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0], result_src, st_src_reg_for_float(0.0)); 1724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rsq: 172656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 1727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2f: 172901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) { 1730b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]); 1731b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1732b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 17330dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* fallthrough to next case otherwise */ 17340dc575c6f6157867accf749a06ec745617ea64acBryan Cain case ir_unop_b2f: 17350dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 17360dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0)); 17370dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 17380dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 17390dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* fallthrough to next case otherwise */ 17404683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain case ir_unop_i2u: 17414683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain case ir_unop_u2i: 17424683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain /* Converting between signed and unsigned integers is a no-op. */ 1743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = op[0]; 1744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 17450dc575c6f6157867accf749a06ec745617ea64acBryan Cain case ir_unop_b2i: 17460dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 17470dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Booleans are stored as integers using ~0 for true and 0 for false. 17480dc575c6f6157867accf749a06ec745617ea64acBryan Cain * GLSL requires that int(bool) return 1 for true and 0 for false. 17490dc575c6f6157867accf749a06ec745617ea64acBryan Cain * This conversion is done with AND, but it could be done with NEG. 17500dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17510dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1)); 17520dc575c6f6157867accf749a06ec745617ea64acBryan Cain } else { 17530dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Booleans and integers are both stored as floats when native 17540dc575c6f6157867accf749a06ec745617ea64acBryan Cain * integers are disabled. 17550dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17560dc575c6f6157867accf749a06ec745617ea64acBryan Cain result_src = op[0]; 17570dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 17580dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 1759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2i: 176001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 1761b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]); 1762b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1763b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2b: 17660dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 17670dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 1768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2b: 17690dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 17700dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 17710dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 17720dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 1773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_trunc: 177556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_ceil: 1778f7665ca4fc2a7bba8378d44d38059fc5dd536223Christoph Bumiller emit(ir, TGSI_OPCODE_CEIL, result_dst, op[0]); 1779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_floor: 178156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]); 1782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1783fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller case ir_unop_round_even: 1784fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]); 1785fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller break; 1786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_fract: 178756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]); 1788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_min: 179156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]); 1792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_max: 179456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]); 1795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_pow: 179756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]); 1798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_bit_not: 18010dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1802b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 1803b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1804b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_u2f: 180601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) { 1807b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]); 1808b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1809b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lshift: 18110dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1812d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]); 1813b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1814b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_rshift: 18160dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1817d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]); 1818b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1819b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_and: 18210dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1822d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 1823b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1824b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_xor: 18260dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1827d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 1828b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1829b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_or: 18310dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1832d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1833b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1834b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1835fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller 1836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"GLSL 1.30 features unsupported"); 1837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_quadop_vector: 1840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This operation should have already been handled. 1841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 1843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 1847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_swizzle *ir) 1852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 1855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle[4]; 1856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Note that this is only swizzles in expressions, not those on the left 1858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * hand side of an assignment, which do write masking. See ir_assignment 1859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for that. 1860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->val->accept(this); 1863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(src.file != PROGRAM_UNDEFINED); 1865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 1867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i < ir->type->vector_elements) { 1868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (i) { 1869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 0: 1870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 1871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 1: 1873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 1874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 2: 1876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 1877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 3: 1879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 1880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last 1884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel out. 1885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = swizzle[ir->type->vector_elements - 1]; 1887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 1891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 1893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) 1897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry = find_variable_storage(ir->var); 1899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var = ir->var; 1900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (var->mode) { 1903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_uniform: 1904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_in: 1909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_inout: 1910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The linker assigns locations for varyings and attributes, 1911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * including deprecated builtins (like gl_Color), user-assign 1912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic attributes (glBindVertexLocation), and 1913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * user-defined varyings. 1914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: We would hit this path for function arguments. Fix! 1916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_INPUT, 1920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_out: 1923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_OUTPUT, 1926a21df965075f6fa1bf27039490ad65b9f78548e6Dave Airlie var->location + var->index); 1927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_system_value: 1929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_SYSTEM_VALUE, 1931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_auto: 1934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_temporary: 1935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 1937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(var->type); 1940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to make storage for %s\n", var->name); 1945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = st_src_reg(entry->file, entry->index, var->type); 195001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (!native_integers) 1951b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain this->result.type = GLSL_TYPE_FLOAT; 1952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_array *ir) 1956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *index; 1958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int element_size = type_size(ir->type); 1960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index = ir->array_index->constant_expression_value(); 1962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array->accept(this); 1964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index) { 1967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index += index->value.i[0] * element_size; 1968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Variable index array dereference. It eats the "vec4" of the 1970f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * base of the array and an index that offsets the TGSI register 1971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * index. 1972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_index->accept(this); 1974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg index_reg; 1976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_size == 1) { 1978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index_reg = this->result; 1979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 19800dc575c6f6157867accf749a06ec745617ea64acBryan Cain index_reg = get_temp(native_integers ? 19810dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_type::int_type : glsl_type::float_type); 1982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 198356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg), 19840dc575c6f6157867accf749a06ec745617ea64acBryan Cain this->result, st_src_reg_for_type(index_reg.type, element_size)); 1985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 19873e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain /* If there was already a relative address register involved, add the 19883e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain * new and the old together to get the new offset. 19893e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain */ 19903e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain if (src.reladdr != NULL) { 19910dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg accum_reg = get_temp(native_integers ? 19920dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_type::int_type : glsl_type::float_type); 19933e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 19943e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain emit(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg), 19953e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain index_reg, *src.reladdr); 19963e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 19973e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain index_reg = accum_reg; 19983e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain } 19993e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 2000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = ralloc(mem_ctx, st_src_reg); 2001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 2002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 2005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 2006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = swizzle_for_size(ir->type->vector_elements); 2007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 2009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 2011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_record *ir) 2015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 2017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *struct_type = ir->record->type; 2018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int offset = 0; 2019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->record->accept(this); 2021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < struct_type->length; i++) { 2023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 2024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain offset += type_size(struct_type->fields.structure[i].type); 2026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 2029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 2030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 2031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = SWIZZLE_NOOP; 2033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.index += offset; 2035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * We want to be careful in assignment setup to hit the actual storage 2039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instead of potentially using a temporary like we might with the 2040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * ir_dereference handler. 2041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic st_dst_reg 2043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v) 2044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The LHS must be a dereference. If the LHS is a variable indexed array 2046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * access of a vector, it must be separated into a series conditional moves 2047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before reaching this point (see ir_vec_index_to_cond_assign). 2048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->as_dereference()); 2050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_array *deref_array = ir->as_dereference_array(); 2051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (deref_array) { 2052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!deref_array->array->type->is_vector()); 2053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use the rvalue deref handler for the most part. We'll ignore 2056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * swizzles in it and write swizzles using writemask, though. 2057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(v); 2059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return st_dst_reg(v->result); 2060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Process the condition of a conditional assignment 2064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Examines the condition of a conditional assignment to generate the optimal 2066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * first operand of a \c CMP instruction. If the condition is a relational 2067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 2068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * used as the source for the \c CMP instruction. Otherwise the comparison 2069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * is processed to a boolean result, and the boolean result is used as the 2070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operand to the CMP instruction. 2071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainbool 2073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) 2074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *src_ir = ir; 2076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool negate = true; 2077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool switch_order = false; 2078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *const expr = ir->as_expression(); 2080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((expr != NULL) && (expr->get_num_operands() == 2)) { 2081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool zero_on_left = false; 2082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (expr->operands[0]->is_zero()) { 2084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[1]; 2085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = true; 2086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (expr->operands[1]->is_zero()) { 2087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[0]; 2088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = false; 2089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* a is - 0 + - 0 + 2092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a < 0) T F F ( a < 0) T F F 2093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 < a) F F T (-a < 0) F F T 2094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 2095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 2096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a > 0) F F T (-a < 0) F F T 2097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 > a) T F F ( a < 0) T F F 2098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 2099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 2100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Note that exchanging the order of 0 and 'a' in the comparison simply 2102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * means that the value of 'a' should be negated. 2103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_ir != ir) { 2105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (expr->operation) { 2106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 2107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 2108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 2109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 2112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 2113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 2114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 2117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 2118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 2119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 2122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 2123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 2124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This isn't the right kind of comparison afterall, so make sure 2128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the whole condition is visited. 2129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = ir; 2131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir->accept(this); 2137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 213856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 2139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * condition we produced is 0.0 or 1.0. By flipping the sign, we can 214056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * choose which value TGSI_OPCODE_CMP produces without an extra instruction 2141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * computing the condition. 2142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (negate) 2144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 2145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return switch_order; 2147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_assignment *ir) 2151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 2154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->rhs->accept(this); 2157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r = this->result; 2158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = get_assignment_lhs(ir->lhs, this); 2160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This should really set to the correct maximal writemask for each 2162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: component written (in the loops below). This case can only 2163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: occur for matrices, arrays, and structures. 2164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->write_mask == 0) { 2166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 2167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2168194732fd7299481dd57815f46a594d155260ce17Bryan Cain } else if (ir->lhs->type->is_scalar() && 2169194732fd7299481dd57815f46a594d155260ce17Bryan Cain ir->lhs->variable_referenced()->mode == ir_var_out) { 2170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 2171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: W component of fragment shader output zero, work correctly. 2172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzles[4]; 2176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int first_enabled_chan = 0; 2177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int rhs_chan = 0; 2178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = ir->write_mask; 2180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 2182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) { 2183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_enabled_chan = GET_SWZ(r.swizzle, i); 2184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Swizzle a small RHS vector into the channels being written. 2189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * glsl ir treats write_mask as dictating how many channels are 2191f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * present on the RHS while TGSI treats write_mask as just 2192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * showing which channels of the vec4 RHS get written. 2193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 2195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) 2196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 2197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = first_enabled_chan; 2199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 2201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[2], swizzles[3]); 2202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(l.file != PROGRAM_UNDEFINED); 2205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(r.file != PROGRAM_UNDEFINED); 2206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 2208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const bool switch_order = this->process_move_condition(ir->condition); 2209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg condition = this->result; 2210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 22128b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain st_src_reg l_src = st_src_reg(l); 22130dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg condition_temp = condition; 22148b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements); 22158b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain 22160dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 22170dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* This is necessary because TGSI's CMP instruction expects the 22180dc575c6f6157867accf749a06ec745617ea64acBryan Cain * condition to be a float, and we store booleans as integers. 22190dc575c6f6157867accf749a06ec745617ea64acBryan Cain * If TGSI had a UCMP instruction or similar, this extra 22200dc575c6f6157867accf749a06ec745617ea64acBryan Cain * instruction would not be necessary. 22210dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 22220dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition_temp = get_temp(glsl_type::vec4_type); 22230dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition.negate = 0; 22240dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_I2F, st_dst_reg(condition_temp), condition); 22250dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition_temp.swizzle = condition.swizzle; 22260dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 22270dc575c6f6157867accf749a06ec745617ea64acBryan Cain 2228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (switch_order) { 22290dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition_temp, l_src, r); 2230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 22310dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition_temp, r, l_src); 2232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2237f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain } else if (ir->rhs->as_expression() && 2238f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain this->instructions.get_tail() && 2239f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir && 2240e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet type_size(ir->lhs->type) == 1 && 2241e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst.writemask) { 2242f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain /* To avoid emitting an extra MOV when assigning an expression to a 22430da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * variable, emit the last instruction of the expression again, but 22440da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * replace the destination register with the target of the assignment. 22450da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * Dead code elimination will remove the original instruction. 2246f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain */ 2247e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet glsl_to_tgsi_instruction *inst, *new_inst; 2248f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2249e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]); 2250e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet new_inst->saturate = inst->saturate; 22510dc575c6f6157867accf749a06ec745617ea64acBryan Cain inst->dead_mask = inst->dst.writemask; 2252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 225456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_constant *ir) 2264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 2266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLfloat stack_vals[4] = { 0 }; 2267b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_constant_value *values = (gl_constant_value *) stack_vals; 2268b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain GLenum gl_type = GL_NONE; 2269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 22707732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain static int in_array = 0; 22713354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_register_file file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE; 2272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Unfortunately, 4 floats is all we can get into 22747732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * _mesa_add_typed_unnamed_constant. So, make a temp to store an 2275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * aggregate constant and move each constant value into it. If we 2276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * get lucky, copy propagation will eliminate the extra moves. 2277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->base_type == GLSL_TYPE_STRUCT) { 2279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 2280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 2281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, ir->components) { 2283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_value = (ir_constant *)iter.get(); 2284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(field_value->type); 2285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 2287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_value->accept(this); 2289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 2290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned int)size; i++) { 229256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 2293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 2295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 2296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 2299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_array()) { 2303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 2304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 2305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(ir->type->fields.array); 2306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 23087732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain in_array++; 2309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->length; i++) { 2311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_elements[i]->accept(this); 2312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 2313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int j = 0; j < size; j++) { 231456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 2315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 2317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 2318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 23217732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain in_array--; 2322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_matrix()) { 2326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg mat = get_temp(ir->type); 2327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg mat_column = st_dst_reg(mat); 2328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->matrix_columns; i++) { 2330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->type->base_type == GLSL_TYPE_FLOAT); 2331b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements]; 2332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 23337732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain src = st_src_reg(file, -1, ir->type->base_type); 23343354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(file, 23353354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain values, 23363354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain ir->type->vector_elements, 23373354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain GL_FLOAT, 23383354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain &src.swizzle); 233956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, mat_column, src); 2340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mat_column.index++; 2342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = mat; 2345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->type->base_type) { 2349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 2350b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = GL_FLOAT; 2351b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2352b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.f[i]; 2353b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 2354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 235601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT; 2357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 235801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2359b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].u = ir->value.u[i]; 2360b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2361b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.u[i]; 2362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 236501d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_INT : GL_FLOAT; 2366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 236701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2368b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].i = ir->value.i[i]; 2369b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2370b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.i[i]; 2371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 237401d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_BOOL : GL_FLOAT; 2375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 237601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2377673535f6071e512b18ac6da622e15bdc45ebf0a0Bryan Cain values[i].u = ir->value.b[i] ? ~0 : 0; 2378b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2379b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.b[i]; 2380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Non-float/uint/int/bool constant"); 2384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 23867732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain this->result = st_src_reg(file, -1, ir->type); 23873354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->result.index = add_constant(file, 23883354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain values, 23893354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain ir->type->vector_elements, 23903354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_type, 23913354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain &this->result.swizzle); 2392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfunction_entry * 2395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) 2396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry; 2398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->function_signatures) { 2400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (function_entry *)iter.get(); 2401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->sig == sig) 2403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = ralloc(mem_ctx, function_entry); 2407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig = sig; 2408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig_id = this->next_signature_id++; 2409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst = NULL; 2410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Allocate storage for all the parameters. */ 2412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->parameters) { 2413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)iter.get(); 2414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage; 2415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = find_variable_storage(param); 2417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!storage); 2418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 2421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 2422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(param->type); 2424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sig->return_type->is_void()) { 2427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = get_temp(sig->return_type); 2428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = undef_src; 2430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->function_signatures.push_tail(entry); 2433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_call *ir) 2438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *call_inst; 244082065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke ir_function_signature *sig = ir->callee; 2441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = get_function_signature(sig); 2442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process in parameters. */ 2445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list_iterator sig_iter = sig->parameters.iterator(); 2446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_in || 2451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.file = storage->file; 2460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index = storage->index; 2461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.reladdr = NULL; 2462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.cond_mask = COND_TR; 2464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 246656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit call instruction */ 247756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain call_inst = emit(ir, TGSI_OPCODE_CAL); 2478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain call_inst->function = entry; 2479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process out parameters. */ 2481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter = sig->parameters.iterator(); 2482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_out || 2487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 2492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.file = storage->file; 2493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index = storage->index; 2494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.reladdr = NULL; 2495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = SWIZZLE_NOOP; 2496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.negate = 0; 2497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l = st_dst_reg(this->result); 2500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 250256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process return value. */ 2513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = entry->return_reg; 2514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_texture *ir) 2518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 25192083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie st_src_reg result_src, coord, lod_info, projector, dx, dy, offset; 2520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst, coord_dst; 2521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = NULL; 252256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain unsigned opcode = TGSI_OPCODE_NOP; 2523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2524515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie if (ir->coordinate) { 2525515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie ir->coordinate->accept(this); 2526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2527515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie /* Put our coords in a temp. We'll need to modify them for shadow, 2528515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * projection, or LOD, so the only case we'd use it as is is if 2529515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * we're doing plain old texturing. The optimization passes on 2530515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. 2531515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie */ 2532515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie coord = get_temp(glsl_type::vec4_type); 2533515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie coord_dst = st_dst_reg(coord); 2534515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2535515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie } 2536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 2538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->projector->accept(this); 2539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain projector = this->result; 2540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 2543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 2544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = get_temp(glsl_type::vec4_type); 2546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 2547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->op) { 2549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_tex: 255056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TEX; 2551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txb: 255356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXB; 2554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.bias->accept(this); 2555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txl: 255856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXL; 2559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.lod->accept(this); 2560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txd: 256356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXD; 2564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdx->accept(this); 2565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dx = this->result; 2566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdy->accept(this); 2567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dy = this->result; 2568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 25691e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 2570515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie opcode = TGSI_OPCODE_TXQ; 2571515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie ir->lod_info.lod->accept(this); 2572515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie lod_info = this->result; 2573515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie break; 25745f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie case ir_txf: 25755f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie opcode = TGSI_OPCODE_TXF; 25765f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie ir->lod_info.lod->accept(this); 25775f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie lod_info = this->result; 25782083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie if (ir->offset) { 25792083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie ir->offset->accept(this); 25802083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset = this->result; 25812083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 2582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 25859edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák const glsl_type *sampler_type = ir->sampler->type; 25869edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 2587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 258856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TEX) { 2589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the projector in as the last component of the coord. */ 2590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 259156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, projector); 2592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 259356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXP; 2594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg coord_w = coord; 2596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_w.swizzle = SWIZZLE_WWWW; 2597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For the other TEX opcodes there's no projective version 259956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * since the last slot is taken up by LOD info. Do the 2600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * projective divide now. 2601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 260356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RCP, coord_dst, projector); 2604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* In the case where we have to project the coordinates "by hand," 260656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the shadow comparator value must also be projected. 2607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp_src = coord; 2609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) { 2610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 2614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_src = get_temp(glsl_type::vec4_type); 2616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp_src); 2617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 26189edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák /* Projective division not allowed for array samplers. */ 26199edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák assert(!sampler_type->sampler_array); 26209edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 2621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_Z; 262256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); 2623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_XY; 262556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord); 2626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZ; 262956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w); 2630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord.swizzle = SWIZZLE_XYZW; 2633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 263656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the shadow 263756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * comparator was put in the correct place (and projected) by the code, 2638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * above, that handles by-hand projection. 2639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 264056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->shadow_comparitor && (!ir->projector || opcode == TGSI_OPCODE_TXP)) { 2641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 26459edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 26469edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák /* XXX This will need to be updated for cubemap array samplers. */ 26472f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && 26482f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie sampler_type->sampler_array) || 26492f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) { 26509edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák coord_dst.writemask = WRITEMASK_W; 26519edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák } else { 26529edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák coord_dst.writemask = WRITEMASK_Z; 26539edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák } 26549edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 265556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 26595f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || 26605f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie opcode == TGSI_OPCODE_TXF) { 266156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI stores LOD or LOD bias in the last channel of the coords. */ 2662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 266356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info); 2664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 266756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TXD) 2668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord, dx, dy); 2669515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie else if (opcode == TGSI_OPCODE_TXQ) 2670515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie inst = emit(ir, opcode, result_dst, lod_info); 26712083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie else if (opcode == TGSI_OPCODE_TXF) { 26722083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst = emit(ir, opcode, result_dst, coord); 26732083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } else 2674f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord); 2675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) 2677f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_shadow = GL_TRUE; 2678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->shader_program, 2681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->prog); 2682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 26832083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie if (ir->offset) { 26842083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offset_num_offset = 1; 26852083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].Index = offset.index; 26862083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].File = offset.file; 26872083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0); 26882083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1); 26892083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2); 26902083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 26912083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 2692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (sampler_type->sampler_dimensionality) { 2693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_1D: 2694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_2D: 2698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2699f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_3D: 2702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_3D_INDEX; 2703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_CUBE: 2705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_CUBE_INDEX; 2706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_RECT: 2708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_RECT_INDEX; 2709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_BUF: 2711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"FINISHME: Implement ARB_texture_buffer_object"); 2712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 27138cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu case GLSL_SAMPLER_DIM_EXTERNAL: 27148cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu inst->tex_target = TEXTURE_EXTERNAL_INDEX; 27158cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu break; 2716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 2718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 2721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_return *ir) 2725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->get_value()) { 2727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(current_function); 2731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->get_value()->accept(this); 2733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = st_dst_reg(current_function->return_reg); 2736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(current_function->sig->return_type); i++) { 273856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 274456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RET); 2745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_discard *ir) 2749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 2751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 2753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 275556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KIL, undef_dst, this->result); 2756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 275756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KILP); 2758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->UsesKill = GL_TRUE; 2761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_if *ir) 2765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 27666e7942936c5de59f509779b6f7620d80d2fbc21aMarek Olšák glsl_to_tgsi_instruction *cond_inst, *if_inst; 2767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *prev_inst; 2768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prev_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(this->result.file != PROGRAM_UNDEFINED); 2773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->options->EmitCondCodes) { 2775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we actually generated any instruction for generating 2778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the condition. If not, then cook up a move to a temp so we 2779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have something to set cond_update on. 2780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (cond_inst == prev_inst) { 2782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::bool_type); 278356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain cond_inst = emit(ir->condition, TGSI_OPCODE_MOV, st_dst_reg(temp), result); 2784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst->cond_update = GL_TRUE; 2786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 278756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF); 2788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_inst->dst.cond_mask = COND_NE; 2789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 279056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result); 2791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(if_inst); 2794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->then_instructions, this); 2796f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!ir->else_instructions.is_empty()) { 27986e7942936c5de59f509779b6f7620d80d2fbc21aMarek Olšák emit(ir->condition, TGSI_OPCODE_ELSE); 2799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->else_instructions, this); 2800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 280256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); 2803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::glsl_to_tgsi_visitor() 2806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result.file = PROGRAM_UNDEFINED; 2808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp = 1; 2809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_signature_id = 1; 28103354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain num_immediates = 0; 2811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain current_function = NULL; 2812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_address_regs = 0; 2813105f307d90de92d088116516957e37267d9fe115Vinson Lee samplers_used = 0; 2814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_temps = false; 2815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_consts = false; 2816105f307d90de92d088116516957e37267d9fe115Vinson Lee num_clip_distances = 0; 2817105f307d90de92d088116516957e37267d9fe115Vinson Lee glsl_version = 0; 2818105f307d90de92d088116516957e37267d9fe115Vinson Lee native_integers = false; 2819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mem_ctx = ralloc_context(NULL); 282070d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee ctx = NULL; 282170d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee prog = NULL; 282270d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee shader_program = NULL; 282370d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee options = NULL; 2824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::~glsl_to_tgsi_visitor() 2827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(mem_ctx); 2829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v) 2832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete v; 2834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Count resources used by the given gpu program (number of texture 2839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * samplers, etc). 2840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 28425768ed6429937940bd48f5de4f8383273952880aBryan Caincount_resources(glsl_to_tgsi_visitor *v, gl_program *prog) 2843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 284444867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used = 0; 2845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 284644867da3543ca54ef245695cef72a6e305451d93Bryan Cain foreach_iter(exec_list_iterator, iter, v->instructions) { 284744867da3543ca54ef245695cef72a6e305451d93Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 284956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (is_tex_instruction(inst->op)) { 285044867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used |= 1 << inst->sampler; 28515768ed6429937940bd48f5de4f8383273952880aBryan Cain 28525768ed6429937940bd48f5de4f8383273952880aBryan Cain if (inst->tex_shadow) { 28535768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->ShadowSamplers |= 1 << inst->sampler; 28545768ed6429937940bd48f5de4f8383273952880aBryan Cain } 2855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 28575768ed6429937940bd48f5de4f8383273952880aBryan Cain 28585768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->SamplersUsed = v->samplers_used; 28596a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick 28606a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick if (v->shader_program != NULL) 28616a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick _mesa_update_shader_textures_used(v->shader_program, prog); 2862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 2866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 2867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *name, const glsl_type *type, 2868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *val) 2869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_record()) { 2871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_constant; 2872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)val->components.get_head(); 2874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < type->length; i++) { 2876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *field_type = type->fields.structure[i].type; 2877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 2878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type->fields.structure[i].name); 2879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 2880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_type, field_constant); 2881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)field_constant->next; 2882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loc = _mesa_get_uniform_location(ctx, shader_program, name); 2887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (loc == -1) { 2889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, 2890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "Couldn't find uniform for initializer %s\n", name); 2891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 2895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *element; 2896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *element_type; 2897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array()) { 2898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val->array_elements[i]; 2899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type->fields.array; 2900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val; 2902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type; 2903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *values; 2906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->base_type == GLSL_TYPE_BOOL) { 2908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *conv = ralloc_array(mem_ctx, int, element_type->components()); 2909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int j = 0; j < element_type->components(); j++) { 2910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain conv[j] = element->value.b[j]; 2911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = (void *)conv; 2913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = glsl_type::get_instance(GLSL_TYPE_INT, 2914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1); 2916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = &element->value; 2918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->is_matrix()) { 2921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform_matrix(ctx, shader_program, 2922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->matrix_columns, 2923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loc, 1, GL_FALSE, (GLfloat *)values); 2925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 2927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values, element_type->gl_type); 2928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2929719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2930719909698c67c287a393d2380278e7b7495ae018Ian Romanick loc++; 2931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 293429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 293529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which 293629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * are read from the given src in this instruction 293729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 293829d21417e38aed0f0710d3692df320728aef90b1Bryan Cainstatic int 293929d21417e38aed0f0710d3692df320728aef90b1Bryan Cainget_src_arg_mask(st_dst_reg dst, st_src_reg src) 294029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 294129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain int read_mask = 0, comp; 294229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 294329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Now, given the src swizzle and the written channels, find which 294429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * components are actually read 294529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 294629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain for (comp = 0; comp < 4; ++comp) { 294729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain const unsigned coord = GET_SWZ(src.swizzle, comp); 294829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain ASSERT(coord < 4); 294929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W) 295029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain read_mask |= 1 << coord; 295129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 295229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 295329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain return read_mask; 295429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 295529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 295629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 295729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP 295829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * instruction is the first instruction to write to register T0. There are 295929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * several lowering passes done in GLSL IR (e.g. branches and 296029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * relative addressing) that create a large number of conditional assignments 296129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * that ir_to_mesa converts to CMP instructions like the one mentioned above. 296229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 296329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Here is why this conversion is safe: 296429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * CMP T0, T1 T2 T0 can be expanded to: 296529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * if (T1 < 0.0) 296629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T2; 296729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * else 296829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0; 296929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 297029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same 297129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * as the original program. If (T1 < 0.0) evaluates to false, executing 297229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized. 297329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2 297429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * because any instruction that was going to read from T0 after this was going 297529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * to read a garbage value anyway. 297629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 297729d21417e38aed0f0710d3692df320728aef90b1Bryan Cainvoid 297829d21417e38aed0f0710d3692df320728aef90b1Bryan Cainglsl_to_tgsi_visitor::simplify_cmp(void) 297929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 2980794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca unsigned *tempWrites; 298129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned outputWrites[MAX_PROGRAM_OUTPUTS]; 298229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 2983794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca tempWrites = new unsigned[MAX_TEMPS]; 2984794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (!tempWrites) { 2985794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca return; 2986794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 29871d01429c6a1ae679d0cc0cb61db1948fca5ced4cMathias Fröhlich memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS); 298829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain memset(outputWrites, 0, sizeof(outputWrites)); 298929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 299029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 299129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 299229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned prevWriteMask = 0; 299329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 299429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Give up if we encounter relative addressing or flow control. */ 299529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.reladdr || 299629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tgsi_get_opcode_info(inst->op)->is_branch || 299729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_BGNSUB || 299829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_CONT || 299929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_END || 300029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_ENDSUB || 300129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_RET) { 3002794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca break; 300329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 300429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 300529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) { 300629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain assert(inst->dst.index < MAX_PROGRAM_OUTPUTS); 300729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = outputWrites[inst->dst.index]; 300829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain outputWrites[inst->dst.index] |= inst->dst.writemask; 300929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY) { 301033e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain assert(inst->dst.index < MAX_TEMPS); 301129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = tempWrites[inst->dst.index]; 301229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tempWrites[inst->dst.index] |= inst->dst.writemask; 301329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 301429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 301529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* For a CMP to be considered a conditional write, the destination 301629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * register and source register two must be the same. */ 301729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->op == TGSI_OPCODE_CMP 301829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && !(inst->dst.writemask & prevWriteMask) 301929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].file == inst->dst.file 302029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].index == inst->dst.index 302129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) { 302229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 302329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op = TGSI_OPCODE_MOV; 302429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->src[0] = inst->src[1]; 302529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 302629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 3027794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 3028794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca delete [] tempWrites; 302929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 303029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 3031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Replaces all references to a temporary register index with another index. */ 3032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) 3034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned j; 3038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 303956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index = new_index; 3043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.index = new_index; 3048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_read(int index) 3054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 3058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 306256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 3066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 306956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 3070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 3071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 307256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 3074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 3075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 3082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_write(int index) 3086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 3096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 309856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 3099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 3100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 310156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 3103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 3104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 3111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_read(int index) 3115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that reads the temporary */ 3118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 3119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 312356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 313056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 313256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_write(int index) 3146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that writes to the temporary */ 3149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) 3155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 315756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 315956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY register 3173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channels for copy propagation and updates following instructions to 3174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * use the original versions. 3175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production before this pass: 3178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 3182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after: 3184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * which allows for dead code elimination on TEMP[1]'s writes. 3190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::copy_propagate(void) 3193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx, 3195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *, 3196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp * 4); 3197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 3198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int level = 0; 3199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 3204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || inst->dst.index < this->next_temp); 3205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* First, do any copy propagation possible into the src regs. */ 3207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < 3; r++) { 3208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *first = NULL; 3209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool good = true; 3210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int acp_base = inst->src[r].index * 4; 3211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[r].file != PROGRAM_TEMPORARY || 3213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].reladdr) 3214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we can find entries in the ACP consisting of MOVs 3217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from the same src register for all the swizzled channels 3218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this src register reference. 3219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan]; 3223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!copy_chan) { 3225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(acp_level[acp_base + src_chan] <= level); 3230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!first) { 3232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first = copy_chan; 3233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 3234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (first->src[0].file != copy_chan->src[0].file || 3235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first->src[0].index != copy_chan->src[0].index) { 3236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (good) { 3243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We've now validated that we can copy-propagate to 3244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * replace this src register reference. Do it. 3245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].file = first->src[0].file; 3247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].index = first->src[0].index; 3248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle = 0; 3250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan]; 3253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 3254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (3 * i)); 3255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].swizzle = swizzle; 3257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (inst->op) { 326156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 326256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 3263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* End of a basic block, clear the ACP entirely. */ 3264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 326756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 3268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ++level; 3269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 327156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDIF: 327256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 3273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear all channels written inside the block from the ACP, but 3274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * leaving those that were not touched. 3275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp_level[4 * r + c] >= level) 3282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 328556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_ENDIF) 3286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain --level; 3287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Continuing the block, clear any written channels from 3291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the ACP. 3292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 3294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any temporary might be written, so no copy propagation 3295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * across this instruction. 3296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_OUTPUT && 3299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.reladdr) { 3300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any output might be written, so no copy propagation 3301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from outputs across this instruction. 3302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 3309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY || 3313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_OUTPUT) { 3314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as dst. */ 3315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY) { 3316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << c)) { 3318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + c] = NULL; 3319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as src. */ 3324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 3330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == inst->dst.file && 3332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c]->src[0].index == inst->dst.index && 3333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask & (1 << src_chan)) 3334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If this is a copy, add it to the ACP. */ 334456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_MOV && 3345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_TEMPORARY && 3346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->dst.reladdr && 3347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->saturate && 3348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].reladdr && 3349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].negate) { 3350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << i)) { 3352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + i] = inst; 3353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp_level[4 * inst->dst.index + i] = level; 3354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp_level); 3360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp); 3361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Tracks available PROGRAM_TEMPORARY registers for dead code elimination. 3365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production after copy propagation but 3368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before this pass: 3369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after this pass: 3375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB) 3379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: doesn't eliminate all dead code inside of loops; it steps around them 3380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::eliminate_dead_code(void) 3383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 3385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last_read = get_last_temp_read(i); 3388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int j = 0; 3389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && 3394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j > last_read) 3395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain iter.remove(); 3397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete inst; 3398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j++; 3401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 340541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain/* 340641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead 340741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * code elimination. This is less primitive than eliminate_dead_code(), as it 340841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is per-channel and can detect consecutive writes without a read between them 340941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * as dead code. However, there is some dead code that can be eliminated by 341041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * eliminate_dead_code() but not this function - for example, this function 341141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * cannot eliminate an instruction writing to a register that is never read and 341241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is the only instruction writing to that register. 341341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * 341441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 341541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * will occur. 341641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 341741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainint 341841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainglsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) 341941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain{ 342041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx, 342141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *, 342241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain this->next_temp * 4); 342341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 342441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int level = 0; 342541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int removed = 0; 342641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 342741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 342841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 342941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 343041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 343141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain || inst->dst.index < this->next_temp); 343241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 343341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain switch (inst->op) { 343441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_BGNLOOP: 343541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDLOOP: 343609497e020a11cc893d06691751faf57c1e762839Bryan Cain case TGSI_OPCODE_CONT: 343709497e020a11cc893d06691751faf57c1e762839Bryan Cain case TGSI_OPCODE_BRK: 343841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* End of a basic block, clear the write array entirely. 343909497e020a11cc893d06691751faf57c1e762839Bryan Cain * 344009497e020a11cc893d06691751faf57c1e762839Bryan Cain * This keeps us from killing dead code when the writes are 344141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * on either side of a loop, even when the register isn't touched 344209497e020a11cc893d06691751faf57c1e762839Bryan Cain * inside the loop. However, glsl_to_tgsi_visitor doesn't seem to emit 344309497e020a11cc893d06691751faf57c1e762839Bryan Cain * dead code of this type, so it shouldn't make a difference as long as 344409497e020a11cc893d06691751faf57c1e762839Bryan Cain * the dead code elimination pass in the GLSL compiler does its job. 344541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 344641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 344741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 344841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 344941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDIF: 345041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ELSE: 34513b15f5046c36fb2d32a4c5f36e77b74efcb539b2Bryan Cain /* Promote the recorded level of all channels written inside the 34523b15f5046c36fb2d32a4c5f36e77b74efcb539b2Bryan Cain * preceding if or else block to the level above the if/else block. 345341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 345441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int r = 0; r < this->next_temp; r++) { 345541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 345641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!writes[4 * r + c]) 345741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 345841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 345920b0daf82de91fd57b7e8d825786789149f6358dBryan Cain if (write_level[4 * r + c] == level) 346020b0daf82de91fd57b7e8d825786789149f6358dBryan Cain write_level[4 * r + c] = level-1; 346141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 346241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 346320b0daf82de91fd57b7e8d825786789149f6358dBryan Cain 346420b0daf82de91fd57b7e8d825786789149f6358dBryan Cain if(inst->op == TGSI_OPCODE_ENDIF) 346520b0daf82de91fd57b7e8d825786789149f6358dBryan Cain --level; 346620b0daf82de91fd57b7e8d825786789149f6358dBryan Cain 346741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 346841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 34694c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain case TGSI_OPCODE_IF: 34704c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain ++level; 34714c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain /* fallthrough to default case to mark the condition as read */ 34724c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain 347341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain default: 347441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Continuing the block, clear any channels from the write array that 347541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * are read by this instruction. 347641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 3477718b894dbb585af52dd24defb2e8c130216e5485Brian Paul for (unsigned i = 0; i < Elements(inst->src); i++) { 347841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ 347941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Any temporary might be read, so no dead code elimination 348041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * across this instruction. 348141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 348241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 348341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else if (inst->src[i].file == PROGRAM_TEMPORARY) { 348441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Clear where it's used as src. */ 348541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0); 348641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1); 348741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2); 348841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3); 348941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 349041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 349141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (src_chans & (1 << c)) { 349241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->src[i].index + c] = NULL; 349341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 349441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 349541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 349641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 349741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 349841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 349941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 350041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* If this instruction writes to a temporary, add it to the write array. 350141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * If there is already an instruction in the write array for one or more 350241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * of the channels, flag that channel write as dead. 350341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 350441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && 350541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->dst.reladdr && 350641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->saturate) { 350741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 350841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.writemask & (1 << c)) { 350941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (writes[4 * inst->dst.index + c]) { 351041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (write_level[4 * inst->dst.index + c] < level) 351141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 351241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain else 351341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c]->dead_mask |= (1 << c); 351441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 351541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c] = inst; 351641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain write_level[4 * inst->dst.index + c] = level; 351741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 351841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 351941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 352041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 352141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 352271cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain /* Anything still in the write array at this point is dead code. */ 352371cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int r = 0; r < this->next_temp; r++) { 352471cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int c = 0; c < 4; c++) { 352571cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain glsl_to_tgsi_instruction *inst = writes[4 * r + c]; 352671cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain if (inst) 352771cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain inst->dead_mask |= (1 << c); 352871cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 352971cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 353071cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain 353141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Now actually remove the instructions that are completely dead and update 353241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * the writemask of other instructions with dead channels. 353341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 353441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 353541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 353641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 353741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!inst->dead_mask || !inst->dst.writemask) 353841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 3539a9e5528f09a835b66771ba4d3f08ff7fd51e08a6Brian Paul else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { 354041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain iter.remove(); 354141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain delete inst; 354241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain removed++; 354341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else 354441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dst.writemask &= ~(inst->dead_mask); 354541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 354741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(write_level); 354841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(writes); 354941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 355041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain return removed; 355141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain} 355241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 3553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Merges temporary registers together where possible to reduce the number of 3554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * registers needed to run a program. 3555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Produces optimal code only after copy propagation and dead code elimination 3557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have been run. */ 3558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::merge_registers(void) 3560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp); 3562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp); 3563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 3564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Read the indices of the last read and first write to each temp register 3566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * into an array so that we don't have to traverse the instruction list as 3567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * much. */ 3568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = get_last_temp_read(i); 3570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[i] = get_first_temp_write(i); 3571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Start looking for registers with non-overlapping usages that can be 3574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * merged together. */ 3575556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (i=0; i < this->next_temp; i++) { 3576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[i] < 0 || first_writes[i] < 0) continue; 3578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3579556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (j=0; j < this->next_temp; j++) { 3580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[j] < 0 || first_writes[j] < 0) continue; 3582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We can merge the two registers if the first write to j is after or 3584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in the same instruction as the last read from i. Note that the 3585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register at index i will always be used earlier or at the same time 3586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * as the register at index j. */ 3587556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain if (first_writes[i] <= first_writes[j] && 3588556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain last_reads[i] <= first_writes[j]) 3589556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain { 3590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(j, i); /* Replace all references to j with i.*/ 3591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update the first_writes and last_reads arrays with the new 3593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * values for the merged register index, and mark the newly unused 3594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register index as such. */ 3595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = last_reads[j]; 3596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[j] = -1; 3597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[j] = -1; 3598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(last_reads); 3603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(first_writes); 3604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Reassign indices to temporary registers by reusing unused indices created 3607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * by optimization passes. */ 3608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::renumber_registers(void) 3610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int new_index = 0; 3613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (get_first_temp_read(i) < 0) continue; 3616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i != new_index) 3617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(i, new_index); 3618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new_index++; 3619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp = new_index; 3622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3624c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain/** 3625c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Returns a fragment program which implements the current pixel transfer ops. 3626c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Based on get_pixel_transfer_program in st_atom_pixeltransfer.c. 3627c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3628c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainextern "C" void 3629c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainget_pixel_transfer_visitor(struct st_fragment_program *fp, 3630c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_visitor *original, 3631c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain int scale_and_bias, int pixel_maps) 3632c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain{ 3633c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 3634c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct st_context *st = st_context(original->ctx); 3635c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct gl_program *prog = &fp->Base.Base; 3636c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct gl_program_parameter_list *params = _mesa_new_parameter_list(); 3637c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg coord, src0; 3638c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_dst_reg dst0; 3639c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_instruction *inst; 3640c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3641c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 3642c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->ctx = original->ctx; 3643c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->prog = prog; 3644d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin v->shader_program = NULL; 3645c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->glsl_version = original->glsl_version; 364601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = original->native_integers; 3647c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->options = original->options; 3648c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->next_temp = original->next_temp; 3649c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->num_address_regs = original->num_address_regs; 3650c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used = prog->SamplersUsed = original->samplers_used; 3651c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->indirect_addr_temps = original->indirect_addr_temps; 3652c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->indirect_addr_consts = original->indirect_addr_consts; 36533354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3654fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul v->num_immediates = original->num_immediates; 3655c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3656c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* 3657c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Get initial pixel color from the texture. 3658c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; 3659c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3660c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 3661c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src0 = v->get_temp(glsl_type::vec4_type); 3662c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain dst0 = st_dst_reg(src0); 3663c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 3664c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 0; 3665c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3666c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3667dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= FRAG_BIT_TEX0; 3668c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */ 3669c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used |= (1 << 0); 3670c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3671c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (scale_and_bias) { 3672c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain static const gl_state_index scale_state[STATE_LENGTH] = 3673c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { STATE_INTERNAL, STATE_PT_SCALE, 3674c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3675c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain static const gl_state_index bias_state[STATE_LENGTH] = 3676c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { STATE_INTERNAL, STATE_PT_BIAS, 3677c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3678c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain GLint scale_p, bias_p; 3679c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg scale, bias; 3680c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3681c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scale_p = _mesa_add_state_reference(params, scale_state); 3682c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain bias_p = _mesa_add_state_reference(params, bias_state); 3683c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3684c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* MAD colorTemp, colorTemp, scale, bias; */ 3685c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT); 3686c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT); 3687c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias); 3688c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3689c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3690c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (pixel_maps) { 3691c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg temp = v->get_temp(glsl_type::vec4_type); 3692c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 3693c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3694c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain assert(st->pixel_xfer.pixelmap_texture); 3695c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3696c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* With a little effort, we can do four pixel map look-ups with 3697c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * two TEX instructions: 3698c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3699c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3700c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ 3701c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain temp_dst.writemask = WRITEMASK_XY; /* write R,G */ 3702c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3703c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 1; 3704c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3705c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3706c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ 3707c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); 3708c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain temp_dst.writemask = WRITEMASK_ZW; /* write B,A */ 3709c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3710c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 1; 3711c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3712c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3713c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */ 3714c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used |= (1 << 1); 3715c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3716c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* MOV colorTemp, temp; */ 3717c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp); 3718c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3719c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3720c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 3721c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * new visitor. */ 3722c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain foreach_iter(exec_list_iterator, iter, original->instructions) { 3723c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 37243788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie glsl_to_tgsi_instruction *newinst; 3725c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg src_regs[3]; 3726c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 372787f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) 372887f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 372987f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain 3730c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain for (int i=0; i<3; i++) { 3731c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i] = inst->src[i]; 3732c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (src_regs[i].file == PROGRAM_INPUT && 3733c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].index == FRAG_ATTRIB_COL0) 3734c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { 3735c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].file = PROGRAM_TEMPORARY; 3736c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].index = src0.index; 3737c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3738c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain else if (src_regs[i].file == PROGRAM_INPUT) 3739dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 3740c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3741c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 37423788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 37433788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst->tex_target = inst->tex_target; 3744c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3745c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3746c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Make modifications to fragment program info. */ 3747c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->Parameters = _mesa_combine_parameter_lists(params, 3748c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain original->prog->Parameters); 3749c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain _mesa_free_parameter_list(params); 3750c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain count_resources(v, prog); 3751c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain fp->glsl_to_tgsi = v; 3752c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain} 3753c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 37545f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain/** 37555f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Make fragment program for glBitmap: 37565f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Sample the texture and kill the fragment if the bit is 0. 37575f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * This program will be combined with the user's fragment program. 37585f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * 37595f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Based on make_bitmap_fragment_program in st_cb_bitmap.c. 37605f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain */ 37615f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cainextern "C" void 37625f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cainget_bitmap_visitor(struct st_fragment_program *fp, 37635f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_visitor *original, int samplerIndex) 37645f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain{ 37655f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 37665f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain struct st_context *st = st_context(original->ctx); 37675f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain struct gl_program *prog = &fp->Base.Base; 37685f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_src_reg coord, src0; 37695f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_dst_reg dst0; 37705f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_instruction *inst; 37715f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 37725f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 37735f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->ctx = original->ctx; 37745f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->prog = prog; 3775d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin v->shader_program = NULL; 37765f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->glsl_version = original->glsl_version; 377701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = original->native_integers; 37785f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->options = original->options; 37795f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->next_temp = original->next_temp; 37805f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->num_address_regs = original->num_address_regs; 37815f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->samplers_used = prog->SamplersUsed = original->samplers_used; 37825f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->indirect_addr_temps = original->indirect_addr_temps; 37835f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->indirect_addr_consts = original->indirect_addr_consts; 37843354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3785fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul v->num_immediates = original->num_immediates; 37865f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 37875f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */ 37885f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 37895f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0 = v->get_temp(glsl_type::vec4_type); 37905f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain dst0 = st_dst_reg(src0); 37915f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 37925f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst->sampler = samplerIndex; 37935f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst->tex_target = TEXTURE_2D_INDEX; 37945f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 3795dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= FRAG_BIT_TEX0; 37965f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->SamplersUsed |= (1 << samplerIndex); /* mark sampler as used */ 37975f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->samplers_used |= (1 << samplerIndex); 37985f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 37995f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ 38005f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0.negate = NEGATE_XYZW; 38015f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM) 38025f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0.swizzle = SWIZZLE_XXXX; 38035f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst = v->emit(NULL, TGSI_OPCODE_KIL, undef_dst, src0); 38045f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38055f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 38065f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * new visitor. */ 38075f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain foreach_iter(exec_list_iterator, iter, original->instructions) { 38085f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 38093788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie glsl_to_tgsi_instruction *newinst; 38105f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_src_reg src_regs[3]; 38115f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38125f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) 38135f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 38145f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38155f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain for (int i=0; i<3; i++) { 38165f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src_regs[i] = inst->src[i]; 38175f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (src_regs[i].file == PROGRAM_INPUT) 3818dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 38195f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain } 38205f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38213788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 38223788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst->tex_target = inst->tex_target; 38235f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain } 38245f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38255f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Make modifications to fragment program info. */ 38265f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->Parameters = _mesa_clone_parameter_list(original->prog->Parameters); 38275f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain count_resources(v, prog); 38285f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain fp->glsl_to_tgsi = v; 38295f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain} 38305f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 3831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ------------------------- TGSI conversion stuff -------------------------- */ 3832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct label { 3833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned branch_target; 3834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned token; 3835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Intermediate state used during shader translation. 3839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct st_translate { 3841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg; 3842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 384333e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain struct ureg_dst temps[MAX_TEMPS]; 3844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src *constants; 38457732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain struct ureg_src *immediates; 3846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; 3847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; 3848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst address[1]; 3849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src samplers[PIPE_MAX_SAMPLERS]; 3850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src systemValues[SYSTEM_VALUE_MAX]; 3851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *inputMapping; 3853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *outputMapping; 3854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For every instruction that contains a label (eg CALL), keep 3856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * details so that we can go back afterwards and emit the correct 3857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * tgsi instruction number for each label. 3858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct label *labels; 3860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_size; 3861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_count; 3862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Keep a record of the tgsi instruction number that each mesa 3864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction starts at, will be used to fix up labels after 3865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * translation. 3866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned *insn; 3868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_size; 3869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_count; 3870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ 3872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean error; 3874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ 3877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { 3878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_FACE, 3879da1544b39ebdf9b24414dcee214a5ccf76e74a77Christoph Bumiller TGSI_SEMANTIC_VERTEXID, 3880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_INSTANCEID 3881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Make note of a branch to a label in the TGSI code. 3885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * After we've emitted all instructions, we'll go over the list 3886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of labels built here and patch the TGSI code with the actual 3887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * location of each label. 3888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3889a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainstatic unsigned *get_label(struct st_translate *t, unsigned branch_target) 3890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 3892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels_count + 1 >= t->labels_size) { 3894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); 3895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels = (struct label *)realloc(t->labels, 3896a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->labels_size * sizeof(struct label)); 3897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels == NULL) { 3898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static unsigned dummy; 3899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &dummy; 3901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i = t->labels_count++; 3905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels[i].branch_target = branch_target; 3906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &t->labels[i].token; 3907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3910f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Called prior to emitting the TGSI code for each instruction. 3911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Allocate additional space for instructions if needed. 3912f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Update the insn[] array so the next glsl_to_tgsi_instruction points to 3913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the next TGSI instruction. 3914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3915a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainstatic void set_insn_start(struct st_translate *t, unsigned start) 3916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn_count + 1 >= t->insn_size) { 3918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); 3919a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->insn = (unsigned *)realloc(t->insn, t->insn_size * sizeof(t->insn[0])); 3920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn == NULL) { 3921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 3923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn[t->insn_count++] = start; 3927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 39307732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * Map a glsl_to_tgsi constant/immediate to a TGSI immediate. 39317732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 39327732822c833ee22e259af3f8bd2bfb57c986612eBryan Cainstatic struct ureg_src 3933a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainemit_immediate(struct st_translate *t, 39343354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_constant_value values[4], 39353354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int type, int size) 39367732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain{ 39377732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain struct ureg_program *ureg = t->ureg; 39387732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 39393354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain switch(type) 39407732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain { 39417732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_FLOAT: 39423354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate(ureg, &values[0].f, size); 39437732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_INT: 39443354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate_int(ureg, &values[0].i, size); 39457732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_UNSIGNED_INT: 39467732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_BOOL: 39473354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate_uint(ureg, &values[0].u, size); 39487732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain default: 39497732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"should not get here - type must be float, int, uint, or bool"); 39507732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain return ureg_src_undef(); 39517732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 39527732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain} 39537732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 39547732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain/** 3955f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register. 3956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 3958a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caindst_register(struct st_translate *t, 3959a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain gl_register_file file, 3960a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GLuint index) 3961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3962a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(file) { 3963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 3964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 3965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 3967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 396849468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[index] = ureg_DECL_local_temporary(t->ureg); 3969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->temps[index]; 3971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 3973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->procType == TGSI_PROCESSOR_VERTEX) 3974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < VERT_RESULT_MAX); 3975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (t->procType == TGSI_PROCESSOR_FRAGMENT) 3976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < FRAG_RESULT_MAX); 3977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 3978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < GEOM_RESULT_MAX); 3979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 3981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->outputs[t->outputMapping[index]]; 3983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 3985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->address[index]; 3986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3988a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"unknown dst register file"); 3989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 3990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3994f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Map a glsl_to_tgsi src register to a TGSI ureg_src register. 3995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 3997a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainsrc_register(struct st_translate *t, 3998a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain gl_register_file file, 3999a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GLuint index) 4000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4001a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(file) { 4002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 4003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 4004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 4006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 4007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < Elements(t->temps)); 4008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 400949468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[index] = ureg_DECL_local_temporary(t->ureg); 4010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->temps[index]); 4011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 4013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 4014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 4015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 4016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 4017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 4018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 4019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: /* ie, immediate */ 4020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index < 0) 4021a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain return ureg_DECL_constant(t->ureg, 0); 4022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 4024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 40257732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 40267732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain return t->immediates[index]; 40277732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 4028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_INPUT: 4029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->inputMapping[index] < Elements(t->inputs)); 4030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->inputs[t->inputMapping[index]]; 4031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 4033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 4034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ 4035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 4037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->address[index]); 4038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_SYSTEM_VALUE: 4040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < Elements(t->systemValues)); 4041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->systemValues[index]; 4042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4044a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"unknown src register file"); 4045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 4046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 405056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_dst register from an st_dst_reg. 4051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 4053a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caintranslate_dst(struct st_translate *t, 4054a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain const st_dst_reg *dst_reg, 4055bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák bool saturate, bool clamp_color) 4056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4057a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain struct ureg_dst dst = dst_register(t, 4058a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst_reg->file, 4059a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst_reg->index); 4060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4061a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_writemask(dst, dst_reg->writemask); 4062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (saturate) 4064a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_saturate(dst); 4065bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák else if (clamp_color && dst_reg->file == PROGRAM_OUTPUT) { 4066bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák /* Clamp colors for ARB_color_buffer_float. */ 4067bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák switch (t->procType) { 4068bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák case TGSI_PROCESSOR_VERTEX: 4069bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák /* XXX if the geometry shader is present, this must be done there 4070bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák * instead of here. */ 4071bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák if (dst_reg->index == VERT_RESULT_COL0 || 4072bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_COL1 || 4073bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_BFC0 || 4074bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_BFC1) { 4075bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst = ureg_saturate(dst); 4076bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4077bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák break; 4078bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák 4079bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák case TGSI_PROCESSOR_FRAGMENT: 4080bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák if (dst_reg->index >= FRAG_RESULT_COLOR) { 4081bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst = ureg_saturate(dst); 4082bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4083bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák break; 4084bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4085bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst_reg->reladdr != NULL) 4088a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_dst_indirect(dst, ureg_src(t->address[0])); 4089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return dst; 4091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 409456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_src register from an st_src_reg. 4095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 4097a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caintranslate_src(struct st_translate *t, const st_src_reg *src_reg) 4098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4099a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain struct ureg_src src = src_register(t, src_reg->file, src_reg->index); 4100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4101a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src = ureg_swizzle(src, 4102a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 0) & 0x3, 4103a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 1) & 0x3, 4104a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 2) & 0x3, 4105a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 3) & 0x3); 4106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((src_reg->negate & 0xf) == NEGATE_XYZW) 4108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = ureg_negate(src); 4109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->reladdr != NULL) { 4111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Normally ureg_src_indirect() would be used here, but a stupid compiler 4112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * bug in g++ makes ureg_src_indirect (an inline C function) erroneously 4113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * set the bit for src.Negate. So we have to do the operation manually 4114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * here to work around the compiler's problems. */ 4115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/ 4116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src addr = ureg_src(t->address[0]); 4117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Indirect = 1; 4118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectFile = addr.File; 4119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectIndex = addr.Index; 4120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectSwizzle = addr.SwizzleX; 4121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->file != PROGRAM_INPUT && 4123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_reg->file != PROGRAM_OUTPUT) { 4124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If src_reg->index was negative, it was set to zero in 4125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * src_register(). Reassign it now. But don't do this 4126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for input/output regs since they get remapped while 4127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * const buffers don't. 4128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Index = src_reg->index; 4130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 4134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 41362083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airliestatic struct tgsi_texture_offset 41372083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlietranslate_tex_offset(struct st_translate *t, 41382083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie const struct tgsi_texture_offset *in_offset) 41392083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie{ 41402083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie struct tgsi_texture_offset offset; 41412083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 41422083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie assert(in_offset->File == PROGRAM_IMMEDIATE); 41432083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 41442083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.File = TGSI_FILE_IMMEDIATE; 41452083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.Index = in_offset->Index; 41462083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleX = in_offset->SwizzleX; 41472083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleY = in_offset->SwizzleY; 41482083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleZ = in_offset->SwizzleZ; 41492083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 41502083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie return offset; 41512083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie} 41522083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 4153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 4154a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caincompile_tgsi_instruction(struct st_translate *t, 4155bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák const glsl_to_tgsi_instruction *inst, 4156bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák bool clamp_dst_color_output) 4157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 4159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint i; 4160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst dst[1]; 4161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src src[4]; 41622083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET]; 41632083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 4164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_dst; 4165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_src; 4166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4167a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain num_dst = num_inst_dst_regs(inst->op); 4168a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain num_src = num_inst_src_regs(inst->op); 4169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (num_dst) 4171a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst[0] = translate_dst(t, 4172a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain &inst->dst, 4173bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák inst->saturate, 4174bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák clamp_dst_color_output); 4175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < num_src; i++) 4177a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src[i] = translate_src(t, &inst->src[i]); 4178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4179a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(inst->op) { 418056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 418156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_CAL: 418256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 418356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 418456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 4185a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(num_dst == 0); 4186a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_label_insn(ureg, 4187a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4188a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src, 4189a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain get_label(t, 4190a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0)); 4191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 4192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 419356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TEX: 419456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXB: 419556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXD: 419656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXL: 419756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXP: 4198515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie case TGSI_OPCODE_TXQ: 41995f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie case TGSI_OPCODE_TXF: 4200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src[num_src++] = t->samplers[inst->sampler]; 42012083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie for (i = 0; i < inst->tex_offset_num_offset; i++) { 42022083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]); 42032083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 4204a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_tex_insn(ureg, 4205a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4206a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst, num_dst, 42073f80b69b5f2093ffc624bb901ce34f0e289bc25dDave Airlie st_translate_texture_target(inst->tex_target, inst->tex_shadow), 42082083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie texoffsets, inst->tex_offset_num_offset, 4209a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src); 4210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 4211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 421256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_SCS: 4213a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY); 4214a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_insn(ureg, inst->op, dst, num_dst, src, num_src); 4215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4218a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_insn(ureg, 4219a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4220a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst, num_dst, 4221a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src); 4222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 422735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * Emit the TGSI instructions for inverting and adjusting WPOS. 4228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This code is unavoidable because it also depends on whether 4229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). 4230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 423235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonsecaemit_wpos_adjustment( struct st_translate *t, 423335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca const struct gl_program *program, 423435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca boolean invert, 423535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjX, GLfloat adjY[2]) 4236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 4238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment program uses fragment position input. 4240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Need to replace instances of INPUT[WPOS] with temp T 4241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * where T = INPUT[WPOS] by y is inverted. 4242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static const gl_state_index wposTransformState[STATE_LENGTH] 4244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 4245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; 4246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX: note we are modifying the incoming shader here! Need to 4248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * do this before emitting the constant decls below, or this 4249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will be missed: 4250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, 4252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wposTransformState); 4253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 425435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); 425535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); 4256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 4257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 425835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* First, apply the coordinate shift: */ 425935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (adjX || adjY[0] || adjY[1]) { 426035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (adjY[0] != adjY[1]) { 426135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Adjust the y coordinate by adjY[1] or adjY[0] respectively 426235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * depending on whether inversion is actually going to be applied 426335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * or not, which is determined by testing against the inversion 426435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * state variable used below, which will be either +1 or -1. 426535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 426649468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg); 426735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca 426835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_CMP(ureg, adj_temp, 426935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, invert ? 2 : 0), 427035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f), 427135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f)); 427235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp)); 427335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } else { 427435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_ADD(ureg, wpos_temp, wpos_input, 427535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f)); 427635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 427735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input = ureg_src(wpos_temp); 427835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } else { 427935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* MOV wpos_temp, input[wpos] 428035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 428135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MOV( ureg, wpos_temp, wpos_input ); 4282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 428435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be 428535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion/identity, or the other way around if we're drawing to an FBO. 428635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 4287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (invert) { 4288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy 4289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 429035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MAD( ureg, 429135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 429235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input, 429335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 0), 429435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 1)); 4295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 4296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww 4297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 429835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MAD( ureg, 429935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 430035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input, 430135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 2), 430235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 3)); 4303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use wpos_temp as position input from here on: 4306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 4308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit fragment position/ooordinate code. 4313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 4315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainemit_wpos(struct st_context *st, 4316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_translate *t, 4317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *program, 4318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg) 4319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_fragment_program *fp = 4321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (const struct gl_fragment_program *) program; 4322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct pipe_screen *pscreen = st->pipe->screen; 432335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjX = 0.0f; 432435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjY[2] = { 0.0f, 0.0f }; 4325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean invert = FALSE; 4326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 432735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Query the pixel center conventions supported by the pipe driver and set 432835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * adjX, adjY to help out if it cannot handle the requested one internally. 432935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 433035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * The bias of the y-coordinate depends on whether y-inversion takes place 433135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are 433235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * drawing to an FBO (causes additional inversion), and whether the the pipe 433335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * driver origin and the requested origin differ (the latter condition is 433435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * stored in the 'invert' variable). 433535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 433635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * For height = 100 (i = integer, h = half-integer, l = lower, u = upper): 433735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 433835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * center shift only: 433935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * i -> h: +0.5 434035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * h -> i: -0.5 434135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 434235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion only: 434335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99 434435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5 434535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0 434635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5 434735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 434835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion and center shift: 434935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5 435035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99 435135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5 435235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 435335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 4354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->OriginUpperLeft) { 4355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in upper-left */ 4356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { 4357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin */ 4358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { 4360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin, need to invert Y */ 4361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 4363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in lower-left */ 4369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) 4370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin */ 4371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) 4373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin, need to invert Y */ 4374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 4375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->PixelCenterInteger) { 4380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center integer */ 438135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer */ 438335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[1] = 1.0f; 4384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 438535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 438635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer, need to bias X,Y */ 438835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjX = -0.5f; 438935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[0] = -0.5f; 439035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[1] = 0.5f; 439135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 4392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center half integer */ 4397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer */ 4399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer, need to bias X,Y */ 440235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjX = adjY[0] = adjY[1] = 0.5f; 4403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 4404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* we invert after adjustment so that we avoid the MOV to temporary, 4410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and reuse the adjustment ADD instead */ 441135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca emit_wpos_adjustment(t, program, invert, adjX, adjY); 4412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4415bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. 4416bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * TGSI uses +1 for front, -1 for back. 4417bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * This function converts the TGSI value to the GL value. Simply clamping/ 4418bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * saturating the value to [0,1] does the job. 4419bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain */ 4420bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 4421bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_face_var(struct st_translate *t) 4422bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 4423bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 4424bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst face_temp = ureg_DECL_temporary(ureg); 4425bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; 4426bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4427bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* MOV_SAT face_temp, input[face] */ 4428bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain face_temp = ureg_saturate(face_temp); 4429bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, face_temp, face_input); 4430bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4431bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* Use face_temp as face input from here on: */ 4432bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); 4433bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4434bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4435bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 4436bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_edgeflags(struct st_translate *t) 4437bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 4438bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 4439bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; 4440bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; 4441bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4442bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, edge_dst, edge_src); 4443bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4444bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4445bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain/** 4446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format. 4447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param program the program to translate 4448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numInputs number of input registers used 4449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputMapping maps Mesa fragment program inputs to TGSI generic 4450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * input indexes 4451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticName the TGSI_SEMANTIC flag for each input 4452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticIndex the semantic index (ex: which texcoord) for 4453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each input 4454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input 4455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numOutputs number of output registers used 4456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputMapping maps Mesa fragment program outputs to TGSI 4457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic outputs 4458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticName the TGSI_SEMANTIC flag for each output 4459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticIndex the semantic index (ex: which texcoord) for 4460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each output 4461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 4462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY 4463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" enum pipe_error 4465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_translate_program( 4466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_context *ctx, 4467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uint procType, 4468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg, 4469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor *program, 4470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *proginfo, 4471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numInputs, 4472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint inputMapping[], 4473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticName[], 4474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticIndex[], 4475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint interpMode[], 4476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numOutputs, 4477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint outputMapping[], 4478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticName[], 4479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticIndex[], 4480bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák boolean passthrough_edgeflags, 4481bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák boolean clamp_color) 4482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4483794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca struct st_translate *t; 4484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 4485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain enum pipe_error ret = PIPE_OK; 4486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numInputs <= Elements(t->inputs)); 4488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numOutputs <= Elements(t->outputs)); 4489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4490794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca t = CALLOC_STRUCT(st_translate); 4491794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (!t) { 4492794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 4493794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca goto out; 4494794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 4495794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 4496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(t, 0, sizeof *t); 4497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->procType = procType; 4499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputMapping = inputMapping; 4500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputMapping = outputMapping; 4501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->ureg = ureg; 4502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4503d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program) { 4504d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) { 4505d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin struct gl_uniform_storage *const storage = 4506d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin &program->shader_program->UniformStorage[i]; 4507d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4508d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin _mesa_uniform_detach_all_driver_storage(storage); 4509d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4510d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4511d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare input attributes. 4514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (procType == TGSI_PROCESSOR_FRAGMENT) { 4516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_fs_input(ureg, 4518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticName[i], 4519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticIndex[i], 4520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain interpMode[i]); 4521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->InputsRead & FRAG_BIT_WPOS) { 4524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Must do this after setting up t->inputs, and before 4525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * emitting constant references, below: 4526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_wpos(st_context(ctx), t, proginfo, ureg); 4528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4530bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (proginfo->InputsRead & FRAG_BIT_FACE) 4531bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_face_var(t); 4532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare output attributes. 4535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (outputSemanticName[i]) { 4538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_POSITION: 4539a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4540a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_POSITION, /* Z/Depth */ 4541a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4542a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Z); 4543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_STENCIL: 4545a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4546a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_STENCIL, /* Stencil */ 4547a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4548a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Y); 4549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_COLOR: 4551a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4552a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_COLOR, 4553a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4554f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4556a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR"); 4557794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca ret = PIPE_ERROR_BAD_INPUT; 4558794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca goto out; 4559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (procType == TGSI_PROCESSOR_GEOMETRY) { 4563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_gs_input(ureg, 4565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i, 4566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticName[i], 4567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticIndex[i]); 4568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4571a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4572a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticName[i], 4573a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(procType == TGSI_PROCESSOR_VERTEX); 4578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_vs_input(ureg, i); 4581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 458459be691638200797583bce39a83f641d30d97492Bryan Cain if (outputSemanticName[i] == TGSI_SEMANTIC_CLIPDIST) { 458559be691638200797583bce39a83f641d30d97492Bryan Cain int mask = ((1 << (program->num_clip_distances - 4*outputSemanticIndex[i])) - 1) & TGSI_WRITEMASK_XYZW; 458659be691638200797583bce39a83f641d30d97492Bryan Cain t->outputs[i] = ureg_DECL_output_masked(ureg, 458759be691638200797583bce39a83f641d30d97492Bryan Cain outputSemanticName[i], 458859be691638200797583bce39a83f641d30d97492Bryan Cain outputSemanticIndex[i], 458959be691638200797583bce39a83f641d30d97492Bryan Cain mask); 459059be691638200797583bce39a83f641d30d97492Bryan Cain } else { 459159be691638200797583bce39a83f641d30d97492Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 459259be691638200797583bce39a83f641d30d97492Bryan Cain outputSemanticName[i], 459359be691638200797583bce39a83f641d30d97492Bryan Cain outputSemanticIndex[i]); 459459be691638200797583bce39a83f641d30d97492Bryan Cain } 4595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4596bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (passthrough_edgeflags) 4597bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_edgeflags(t); 4598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare address register. 4601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->num_address_regs > 0) { 4603a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(program->num_address_regs == 1); 4604a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->address[0] = ureg_DECL_address(ureg); 4605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare misc input registers 4608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 4610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLbitfield sysInputs = proginfo->SystemValuesRead; 4611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned numSys = 0; 4612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; sysInputs; i++) { 4613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (sysInputs & (1 << i)) { 4614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned semName = mesa_sysval_to_semantic[i]; 4615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); 4616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain numSys++; 4617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sysInputs &= ~(1 << i); 4618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_temps) { 4623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If temps are accessed with indirect addressing, declare temporaries 4624f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in sequential order. Else, we declare them on demand elsewhere. 4625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (Note: the number of temporaries is equal to program->next_temp) 4626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned)program->next_temp; i++) { 4628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ 462949468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[i] = ureg_DECL_local_temporary(t->ureg); 4630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 46337732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit constants and uniforms. TGSI uses a single index space for these, 46347732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * so we put all the translated regs in t->constants. 4635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->Parameters) { 4637a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants = (struct ureg_src *)CALLOC(proginfo->Parameters->NumParameters * sizeof(t->constants[0])); 4638f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->constants == NULL) { 4639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ret = PIPE_ERROR_OUT_OF_MEMORY; 4640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain goto out; 4641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < proginfo->Parameters->NumParameters; i++) { 4644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (proginfo->Parameters->Parameters[i].Type) { 4645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 4646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 4647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 4648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 4649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 4650a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants[i] = ureg_DECL_constant(ureg, i); 4651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 46537732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect 46547732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * addressing of the const buffer. 46557732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * FIXME: Be smarter and recognize param arrays: 46567732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * indirect addressing is only valid within the referenced 46577732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * array. 46587732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 4659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 4660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_consts) 4661a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants[i] = ureg_DECL_constant(ureg, i); 4662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 46633354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->constants[i] = emit_immediate(t, 46643354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain proginfo->Parameters->ParameterValues[i], 46653354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain proginfo->Parameters->Parameters[i].DataType, 46663354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 4); 4667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 46737732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 46747732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit immediate values. 46757732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 46763354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->immediates = (struct ureg_src *)CALLOC(program->num_immediates * sizeof(struct ureg_src)); 46777732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain if (t->immediates == NULL) { 46787732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain ret = PIPE_ERROR_OUT_OF_MEMORY; 46797732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain goto out; 46807732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 46813354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain i = 0; 46823354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain foreach_iter(exec_list_iterator, iter, program->immediates) { 46833354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain immediate_storage *imm = (immediate_storage *)iter.get(); 4684fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul assert(i < program->num_immediates); 46853354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); 46867732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 4687fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul assert(i == program->num_immediates); 4688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* texture samplers */ 4690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 469144867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (program->samplers_used & (1 << i)) { 4692a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->samplers[i] = ureg_DECL_sampler(ureg, i); 4693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit each instruction in turn: 4697f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, program->instructions) { 4699a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain set_insn_start(t, ureg_get_instruction_number(ureg)); 4700bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(), 4701bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák clamp_color); 4702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fix up all emitted labels: 4705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < t->labels_count; i++) { 4707a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_fixup_label(ureg, t->labels[i].token, 4708a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->insn[t->labels[i].branch_target]); 4709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4711d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program) { 4712d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin /* This has to be done last. Any operation the can cause 4713d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin * prog->ParameterValues to get reallocated (e.g., anything that adds a 4714d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin * program constant) has to happen before creating this linkage. 4715d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin */ 4716d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4717d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program->_LinkedShaders[i] == NULL) 4718d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin continue; 4719d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4720d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin _mesa_associate_uniform_storage(ctx, program->shader_program, 4721d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin program->shader_program->_LinkedShaders[i]->Program->Parameters); 4722d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4723d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4724d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainout: 4726794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (t) { 4727794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->insn); 4728794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->labels); 4729794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->constants); 4730794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->immediates); 4731794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 4732794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (t->error) { 4733794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca debug_printf("%s: translate error flag set\n", __FUNCTION__); 4734794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 4735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4736794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t); 4737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ret; 4740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ----------------------------- End TGSI code ------------------------------ */ 4742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 474444867da3543ca54ef245695cef72a6e305451d93Bryan Cain * Convert a shader's GLSL IR into a Mesa gl_program, although without 474544867da3543ca54ef245695cef72a6e305451d93Bryan Cain * generating Mesa IR. 4746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct gl_program * 4748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_mesa_program(struct gl_context *ctx, 4749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 475059be691638200797583bce39a83f641d30d97492Bryan Cain struct gl_shader *shader, 475159be691638200797583bce39a83f641d30d97492Bryan Cain int num_clip_distances) 4752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor* v = new glsl_to_tgsi_visitor(); 4754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog; 4755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLenum target; 4756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *target_string; 4757a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain bool progress; 4758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_compiler_options *options = 4759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 4760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_VERTEX_PROGRAM_ARB; 4764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "vertex"; 4765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_FRAGMENT_PROGRAM_ARB; 4768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "fragment"; 4769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_GEOMETRY_PROGRAM_NV; 4772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "geometry"; 4773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(shader->ir); 4780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 4782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!prog) 4783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Parameters = _mesa_new_parameter_list(); 4785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->ctx = ctx; 4786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->prog = prog; 4787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->shader_program = shader_program; 4788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->options = options; 4789b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain v->glsl_version = ctx->Const.GLSLVersion; 479001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = ctx->Const.NativeIntegers; 479159be691638200797583bce39a83f641d30d97492Bryan Cain v->num_clip_distances = num_clip_distances; 4792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 479358a7461e1672935e7d30780a4dd40c00abbc28a5Ian Romanick _mesa_generate_parameters_list_for_uniforms(shader_program, shader, 479458a7461e1672935e7d30780a4dd40c00abbc28a5Ian Romanick prog->Parameters); 4795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 479604e324008759282728a95a1394bac2c4c2a1a3f9Marek Olšák /* Remove reads from output registers. */ 479704e324008759282728a95a1394bac2c4c2a1a3f9Marek Olšák lower_output_reads(shader->ir); 479810937e651222501c0e9f4f44e6b842c261e2edfbVincent Lejeune 479956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Emit intermediate IR for main(). */ 4800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(shader->ir, v); 4801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Now emit bodies for any functions that were used. */ 4803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 4804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_FALSE; 4805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, v->function_signatures) { 4807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = (function_entry *)iter.get(); 4808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry->bgn_inst) { 4810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->current_function = entry; 4811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 481256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB); 4813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst->function = entry; 4814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&entry->sig->body, v); 4816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *last; 4818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (glsl_to_tgsi_instruction *)v->instructions.get_tail(); 481956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (last->op != TGSI_OPCODE_RET) 482056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_RET); 4821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *end; 482356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain end = v->emit(NULL, TGSI_OPCODE_ENDSUB); 4824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain end->function = entry; 4825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_TRUE; 4827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 4830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#if 0 4832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Print out some information (for debugging purposes) used by the 4833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * optimization passes. */ 4834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < v->next_temp; i++) { 4835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fr = v->get_first_temp_read(i); 4836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fw = v->get_first_temp_write(i); 4837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lr = v->get_last_temp_read(i); 4838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lw = v->get_last_temp_write(i); 4839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw); 4841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(fw <= fr); 4842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#endif 4844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 48459c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */ 484629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain v->simplify_cmp(); 48479c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain v->copy_propagate(); 48489c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain while (v->eliminate_dead_code_advanced()); 4849c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 48509c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain /* FIXME: These passes to optimize temporary registers don't work when there 485116d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * is indirect addressing of the temporary register space. We need proper 485216d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * array support so that we don't have to give up these passes in every 485316d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * shader that uses arrays. 485416d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain */ 485516d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain if (!v->indirect_addr_temps) { 485616d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->eliminate_dead_code(); 48578c50f18b29637470539d05ccc32b0cae0092aeacEmil Velikov v->merge_registers(); 485816d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->renumber_registers(); 485916d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain } 486056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 486156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Write the END instruction. */ 486256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_END); 4863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ctx->Shader.Flags & GLSL_DUMP) { 4865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("GLSL IR for linked %s program %d:\n", target_string, 4867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader_program->Name); 4868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_print_ir(shader->ir, NULL); 4869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 48718f9fc8b9d208cf601d126721709315aa3c1c2024José Fonseca fflush(stdout); 4872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 487444867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->Instructions = NULL; 487544867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->NumInstructions = 0; 4876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4877cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); 48785768ed6429937940bd48f5de4f8383273952880aBryan Cain count_resources(v, prog); 4879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &shader->Program, prog); 4881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4882719909698c67c287a393d2380278e7b7495ae018Ian Romanick /* This has to be done last. Any operation the can cause 4883719909698c67c287a393d2380278e7b7495ae018Ian Romanick * prog->ParameterValues to get reallocated (e.g., anything that adds a 4884719909698c67c287a393d2380278e7b7495ae018Ian Romanick * program constant) has to happen before creating this linkage. 4885719909698c67c287a393d2380278e7b7495ae018Ian Romanick */ 4886719909698c67c287a393d2380278e7b7495ae018Ian Romanick _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters); 4887719909698c67c287a393d2380278e7b7495ae018Ian Romanick if (!shader_program->LinkStatus) { 4888719909698c67c287a393d2380278e7b7495ae018Ian Romanick return NULL; 4889719909698c67c287a393d2380278e7b7495ae018Ian Romanick } 4890719909698c67c287a393d2380278e7b7495ae018Ian Romanick 4891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_vertex_program *stvp; 4892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_fragment_program *stfp; 4893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_geometry_program *stgp; 4894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp = (struct st_vertex_program *)prog; 4898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp->glsl_to_tgsi = v; 4899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp = (struct st_fragment_program *)prog; 4902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp->glsl_to_tgsi = v; 4903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp = (struct st_geometry_program *)prog; 4906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp->glsl_to_tgsi = v; 4907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return prog; 4914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 491659be691638200797583bce39a83f641d30d97492Bryan Cain/** 491759be691638200797583bce39a83f641d30d97492Bryan Cain * Searches through the IR for a declaration of gl_ClipDistance and returns the 491859be691638200797583bce39a83f641d30d97492Bryan Cain * declared size of the gl_ClipDistance array. Returns 0 if gl_ClipDistance is 491959be691638200797583bce39a83f641d30d97492Bryan Cain * not declared in the IR. 492059be691638200797583bce39a83f641d30d97492Bryan Cain */ 492159be691638200797583bce39a83f641d30d97492Bryan Cainint get_clip_distance_size(exec_list *ir) 492259be691638200797583bce39a83f641d30d97492Bryan Cain{ 492359be691638200797583bce39a83f641d30d97492Bryan Cain foreach_iter (exec_list_iterator, iter, *ir) { 492459be691638200797583bce39a83f641d30d97492Bryan Cain ir_instruction *inst = (ir_instruction *)iter.get(); 492559be691638200797583bce39a83f641d30d97492Bryan Cain ir_variable *var = inst->as_variable(); 492659be691638200797583bce39a83f641d30d97492Bryan Cain if (var == NULL) continue; 492759be691638200797583bce39a83f641d30d97492Bryan Cain if (!strcmp(var->name, "gl_ClipDistance")) { 492859be691638200797583bce39a83f641d30d97492Bryan Cain return var->type->length; 492959be691638200797583bce39a83f641d30d97492Bryan Cain } 493059be691638200797583bce39a83f641d30d97492Bryan Cain } 493159be691638200797583bce39a83f641d30d97492Bryan Cain 493259be691638200797583bce39a83f641d30d97492Bryan Cain return 0; 493359be691638200797583bce39a83f641d30d97492Bryan Cain} 493459be691638200797583bce39a83f641d30d97492Bryan Cain 4935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" { 4936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader * 4938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 4939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader; 4941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || 4942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type == GL_GEOMETRY_SHADER_ARB); 4943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader = rzalloc(NULL, struct gl_shader); 4944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shader) { 4945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Type = type; 4946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Name = name; 4947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader(ctx, shader); 4948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shader; 4950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader_program * 4953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader_program(struct gl_context *ctx, GLuint name) 4954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shProg; 4956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg = rzalloc(NULL, struct gl_shader_program); 4957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shProg) { 4958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg->Name = name; 4959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader_program(ctx, shProg); 4960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shProg; 4962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Link a shader. 4966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Called via ctx->Driver.LinkShader() 496756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * This actually involves converting GLSL IR into an intermediate TGSI-like IR 496856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * with code lowering and other optimizations. 4969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean 4971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 4972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 497359be691638200797583bce39a83f641d30d97492Bryan Cain int num_clip_distances[MESA_SHADER_TYPES]; 4974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(prog->LinkStatus); 4975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 4978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 4979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool progress; 4981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list *ir = prog->_LinkedShaders[i]->ir; 4982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_shader_compiler_options *options = 4983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 4984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 498559be691638200797583bce39a83f641d30d97492Bryan Cain /* We have to determine the length of the gl_ClipDistance array before 498659be691638200797583bce39a83f641d30d97492Bryan Cain * the array is lowered to two vec4s by lower_clip_distance(). 498759be691638200797583bce39a83f641d30d97492Bryan Cain */ 498859be691638200797583bce39a83f641d30d97492Bryan Cain num_clip_distances[i] = get_clip_distance_size(ir); 498959be691638200797583bce39a83f641d30d97492Bryan Cain 4990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 4991c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP | 4992c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie EXP_TO_EXP2 | LOG_TO_LOG2; 4993c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie if (options->EmitNoPow) 4994c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie what_to_lower |= POW_TO_EXP2; 4995c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie if (!ctx->Const.NativeIntegers) 4996c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie what_to_lower |= INT_DIV_TO_MUL_RCP; 4997c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie 4998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = false; 4999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Lowering */ 5001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do_mat_op_to_vec(ir); 5002c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie lower_instructions(ir, what_to_lower); 5003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 5005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 50061d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick progress = do_common_optimization(ir, true, true, 50071d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick options->MaxUnrollIterations) 50081d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick || progress; 5009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 501010d31cb307f90a08fafed5c67945ffe53d279940Bryan Cain progress = lower_quadop_vector(ir, false) || progress; 501159be691638200797583bce39a83f641d30d97492Bryan Cain progress = lower_clip_distance(ir) || progress; 5012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5013488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) 5014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_discard(ir) || progress; 5015488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain 5016488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; 5017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoNoise) 5019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_noise(ir) || progress; 5020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are forms of indirect addressing that the driver 5022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * cannot handle, perform the lowering pass. 5023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 5024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 5025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 5026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = 5027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lower_variable_index_to_cond_assign(ir, 5028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectInput, 5029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectOutput, 5030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectTemp, 5031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectUniform) 5032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || progress; 5033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_vec_index_to_cond_assign(ir) || progress; 5035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 5036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(ir); 5038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 5041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *linked_prog; 5042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 5044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 5045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 504659be691638200797583bce39a83f641d30d97492Bryan Cain linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i], 504759be691638200797583bce39a83f641d30d97492Bryan Cain num_clip_distances[i]); 5048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (linked_prog) { 5050e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick static const GLenum targets[] = { 5051e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_VERTEX_PROGRAM_ARB, 5052e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_FRAGMENT_PROGRAM_ARB, 5053e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_GEOMETRY_PROGRAM_NV 5054e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick }; 5055e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick 5056e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5057e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick linked_prog); 5058e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) { 5059e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5060e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick NULL); 5061b2064ff3115afa075021902ecd35f4a5a772dc9eMarek Olšák _mesa_reference_program(ctx, &linked_prog, NULL); 5062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_FALSE; 5063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &linked_prog, NULL); 5067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_TRUE; 5070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 5071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5072c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšákvoid 50739f2963b631cb2a2899fcb0eb384895fd33f9821dBrian Paulst_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, 5074c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák const GLuint outputMapping[], 5075c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák struct pipe_stream_output_info *so) 5076c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák{ 5077c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák unsigned i; 5078c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák struct gl_transform_feedback_info *info = 5079c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák &glsl_to_tgsi->shader_program->LinkedTransformFeedback; 5080c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák 5081c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák for (i = 0; i < info->NumOutputs; i++) { 5082c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->output[i].register_index = 5083c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák outputMapping[info->Outputs[i].OutputRegister]; 50842449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].start_component = info->Outputs[i].ComponentOffset; 50852449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].num_components = info->Outputs[i].NumComponents; 5086c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->output[i].output_buffer = info->Outputs[i].OutputBuffer; 50872449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].dst_offset = info->Outputs[i].DstOffset; 50882449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák } 50892449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák 50902449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 50912449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->stride[i] = info->BufferStride[i]; 5092c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák } 5093c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->num_outputs = info->NumOutputs; 5094c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák} 5095c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák 5096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} /* extern "C" */ 5097