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; 307b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 308b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int glsl_version; 30901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke bool native_integers; 310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *find_variable_storage(ir_variable *var); 312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3133354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int add_constant(gl_register_file file, gl_constant_value values[4], 3143354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int size, int datatype, GLuint *swizzle_out); 3153354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *get_function_signature(ir_function_signature *sig); 317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg get_temp(const glsl_type *type); 319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr); 320f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg st_src_reg_for_float(float val); 322b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_int(int val); 323b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg st_src_reg_for_type(int type, int val); 324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \name Visit methods 327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * As typical for the visitor pattern, there must be one \c visit method for 329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each concrete subclass of \c ir_instruction. Virtual base classes within 330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the hierarchy should not have \c visit methods. 331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@{*/ 333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_variable *); 334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop *); 335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_loop_jump *); 336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function_signature *); 337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_function *); 338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_expression *); 339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_swizzle *); 340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_variable *); 341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_array *); 342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_dereference_record *); 343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_assignment *); 344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_constant *); 345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_call *); 346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_return *); 347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_discard *); 348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_texture *); 349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain virtual void visit(ir_if *); 350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*@}*/ 351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result; 353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of variable_storage */ 355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list variables; 356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3573354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /** List of immediate_storage */ 3583354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain exec_list immediates; 359fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul unsigned num_immediates; 3603354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of function_entry */ 362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list function_signatures; 363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int next_signature_id; 364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** List of glsl_to_tgsi_instruction */ 366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list instructions; 367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 36856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op); 369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 37656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2); 379b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 380b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain unsigned get_opcode(ir_instruction *ir, unsigned op, 381b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 382b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1); 383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /** 385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit the correct dot-product instruction for the type of arguments 386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 387c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir, 388c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_dst_reg dst, 389c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_src_reg src0, 390c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain st_src_reg src1, 391c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain unsigned elements); 392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 39356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0); 395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 39656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scalar(ir_instruction *ir, unsigned op, 397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1); 398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3990dc575c6f6157867accf749a06ec745617ea64acBryan Cain void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst); 4000dc575c6f6157867accf749a06ec745617ea64acBryan Cain 401b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); 402b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 40356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain void emit_scs(ir_instruction *ir, unsigned op, 404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, const st_src_reg &src); 405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 40679a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_mad(ir_expression *ir, 40779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch int mul_operand); 4085379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain bool try_emit_mad_for_and_not(ir_expression *ir, 4095379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain int mul_operand); 41079a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbäch bool try_emit_sat(ir_expression *ir); 411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void emit_swz(ir_expression *ir); 413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool process_move_condition(ir_rvalue *ir); 415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 41629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain void simplify_cmp(void); 417c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void rename_temp_register(int index, int new_index); 419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_read(int index); 420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_first_temp_write(int index); 421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_read(int index); 422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int get_last_temp_write(int index); 423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void copy_propagate(void); 425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void eliminate_dead_code(void); 42641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int eliminate_dead_code_advanced(void); 427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void merge_registers(void); 428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void renumber_registers(void); 429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *mem_ctx; 431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 433552cc48fca9b932fceb3d8fa7f9d0067f46b67c2Bryan Cainstatic st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); 434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 435b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); 436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 437b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainstatic st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); 438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); 441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfail_link(struct gl_shader_program *prog, const char *fmt, ...) 444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_list args; 446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_start(args, fmt); 447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_vasprintf_append(&prog->InfoLog, fmt, args); 448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain va_end(args); 449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->LinkStatus = GL_FALSE; 451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainswizzle_for_size(int size) 455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size_swizzles[4] = { 457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((size >= 1) && (size <= 4)); 464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size_swizzles[size - 1]; 465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 46756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic bool 46856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainis_tex_instruction(unsigned opcode) 46956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 47056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 47156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex; 47256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 47356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 47456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 47556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_dst_regs(unsigned opcode) 47656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 47756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 47856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->num_dst; 47956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 48056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 48156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainstatic unsigned 48256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainnum_inst_src_regs(unsigned opcode) 48356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain{ 48456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 48556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain return info->is_tex ? info->num_src - 1 : info->num_src; 48656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain} 48756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 48956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0, st_src_reg src1, st_src_reg src2) 492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); 494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int num_reladdr = 0, i; 495b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 496b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op = get_opcode(ir, op, dst, src0, src1); 497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If we have to do relative addressing, we want to load the ARL 499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * reg directly for one of the regs, and preload the other reladdr 500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sources into temps. 501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += dst.reladdr != NULL; 503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src0.reladdr != NULL; 504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src1.reladdr != NULL; 505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr += src2.reladdr != NULL; 506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src2, &num_reladdr); 508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src1, &num_reladdr); 509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain reladdr_to_temp(ir, &src0, &num_reladdr); 510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 512b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *dst.reladdr); 513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_reladdr--; 514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(num_reladdr == 0); 516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->op = op; 518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst = dst; 519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[0] = src0; 520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[1] = src1; 521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[2] = src2; 522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->ir = ir; 52341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dead_mask = 0; 524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->function = NULL; 526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 52710dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL) 528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->num_address_regs = 1; 529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update indirect addressing status used by TGSI */ 531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst.reladdr) { 532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch(dst.file) { 533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 5447732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 5457732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"immediates should not have indirect addressing"); 5467732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain break; 547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i<3; i++) { 553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(inst->src[i].reladdr) { 55416d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain switch(inst->src[i].file) { 555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_temps = true; 557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->indirect_addr_consts = true; 565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 5667732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 5677732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"immediates should not have indirect addressing"); 5687732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain break; 569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 571f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(inst); 5770dc575c6f6157867accf749a06ec745617ea64acBryan Cain 5780dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 5790dc575c6f6157867accf749a06ec745617ea64acBryan Cain try_emit_float_set(ir, op, dst); 5800dc575c6f6157867accf749a06ec745617ea64acBryan Cain 581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return inst; 582f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 583f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 58656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1) 588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, src1, undef_src); 590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 59356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(dst.writemask != 0); 597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, dst, src0, undef_src, undef_src); 598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_instruction * 60156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) 602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 6060dc575c6f6157867accf749a06ec745617ea64acBryan Cain /** 6070dc575c6f6157867accf749a06ec745617ea64acBryan Cain * Emits the code to convert the result of float SET instructions to integers. 6080dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 6090dc575c6f6157867accf749a06ec745617ea64acBryan Cainvoid 6100dc575c6f6157867accf749a06ec745617ea64acBryan Cainglsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op, 6110dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_dst_reg dst) 6120dc575c6f6157867accf749a06ec745617ea64acBryan Cain{ 6130dc575c6f6157867accf749a06ec745617ea64acBryan Cain if ((op == TGSI_OPCODE_SEQ || 6140dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SNE || 6150dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SGE || 6160dc575c6f6157867accf749a06ec745617ea64acBryan Cain op == TGSI_OPCODE_SLT)) 6170dc575c6f6157867accf749a06ec745617ea64acBryan Cain { 6180dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg src = st_src_reg(dst); 6190dc575c6f6157867accf749a06ec745617ea64acBryan Cain src.negate = ~src.negate; 6200dc575c6f6157867accf749a06ec745617ea64acBryan Cain dst.type = GLSL_TYPE_FLOAT; 6210dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_F2I, dst, src); 6220dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 6230dc575c6f6157867accf749a06ec745617ea64acBryan Cain} 6240dc575c6f6157867accf749a06ec745617ea64acBryan Cain 625b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain/** 626b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * Determines whether to use an integer, unsigned integer, or float opcode 627b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * based on the operands and input opcode, then emits the result. 628b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain */ 629b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainunsigned 630b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, 631b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, 632b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg src0, st_src_reg src1) 633b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 634b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain int type = GLSL_TYPE_FLOAT; 635b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 63618a9979dc138adc743f4c19acde7218538614db9Bryan Cain assert(src0.type != GLSL_TYPE_ARRAY); 63718a9979dc138adc743f4c19acde7218538614db9Bryan Cain assert(src0.type != GLSL_TYPE_STRUCT); 63818a9979dc138adc743f4c19acde7218538614db9Bryan Cain assert(src1.type != GLSL_TYPE_ARRAY); 63918a9979dc138adc743f4c19acde7218538614db9Bryan Cain assert(src1.type != GLSL_TYPE_STRUCT); 64018a9979dc138adc743f4c19acde7218538614db9Bryan Cain 641b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) 642b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain type = GLSL_TYPE_FLOAT; 64301d81dedc795005ed235856ce762bb1981655716Kenneth Graunke else if (native_integers) 6440dc575c6f6157867accf749a06ec745617ea64acBryan Cain type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type; 645b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 646b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case4(c, f, i, u) \ 647b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case TGSI_OPCODE_##c: \ 648b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \ 649b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \ 650b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else op = TGSI_OPCODE_##f; \ 651b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 652b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case3(f, i, u) case4(f, f, i, u) 653b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2fi(f, i) case4(f, f, i, i) 654b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain#define case2iu(i, u) case4(i, LAST, i, u) 655b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 656b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain switch(op) { 657b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(ADD, UADD); 658b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MUL, UMUL); 659b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(MAD, UMAD); 660b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(DIV, IDIV, UDIV); 661b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MAX, IMAX, UMAX); 662b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(MIN, IMIN, UMIN); 663b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(MOD, UMOD); 664b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 665b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SEQ, USEQ); 666b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2fi(SNE, USNE); 667b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SGE, ISGE, USGE); 668b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case3(SLT, ISLT, USLT); 669b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 670b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain case2iu(ISHR, USHR); 671cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie 672cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie case2fi(SSG, ISSG); 673cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie case3(ABS, IABS, IABS); 674b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 675b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain default: break; 676b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 677b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 678b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(op != TGSI_OPCODE_LAST); 679b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return op; 680b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 681b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 682c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cainglsl_to_tgsi_instruction * 683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, 684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0, st_src_reg src1, 685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned elements) 686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 68756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain static const unsigned dot_opcodes[] = { 68856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain }; 690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 691c15eb5569bf76c5dc41327017b92a5d960207b97Bryan Cain return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 692f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 69556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emits TGSI scalar opcodes to produce unique answers across channels. 696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 69756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Some TGSI opcodes are scalar-only, like ARB_fp/vp. The src X 698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel determines the result across all channels. So to do a vec4 699f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this operation, we want to emit a scalar per source channel used 700f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * to produce dest channels. 701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 70356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg orig_src0, st_src_reg orig_src1) 706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 71056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI RCP is a scalar operation splatting results to all channels, 711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * dst channels. 713f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint this_mask = (1 << i); 716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = orig_src0; 718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src1 = orig_src1; 719f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (done_mask & this_mask) 721f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 724f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (j = i + 1; j < 4; j++) { 726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz && 732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src1.swizzle, j) == src1_swiz) { 733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src1_swiz, src1_swiz); 740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, op, dst, src0, src1); 742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 74856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, st_src_reg src0) 750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg undef = undef_src; 752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain undef.swizzle = SWIZZLE_XXXX; 754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src0, undef); 756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 758b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainvoid 759b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, 760b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_dst_reg dst, st_src_reg src0) 761b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 76210dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain int op = TGSI_OPCODE_ARL; 76310dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain 76410dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) 76510dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain op = TGSI_OPCODE_UARL; 76610dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain 76710dbd029279dda1689410d8ef2bc5aba64dd5958Bryan Cain emit(NULL, op, dst, src0); 768b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 769b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 77156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Emit an TGSI_OPCODE_SCS instruction 772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 77356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * The \c SCS opcode functions a bit differently than the other TGSI opcodes. 77456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Instead of splatting its result across all four components of the 77556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * destination, it writes one value to the \c x component and another value to 77656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the \c y component. 777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param ir IR instruction being processed 77956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending 78056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * on which value is desired. 781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param dst Destination register 782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param src Source register 783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 78556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cainglsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, 786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst, 787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const st_src_reg &src) 788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Vertex programs cannot use the SCS opcode. 790f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_scalar(ir, op, dst, src); 793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 79656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1; 797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const unsigned scs_mask = (1U << component); 798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int done_mask = ~dst.writemask; 799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp; 800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 80156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS); 802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are compnents in the destination that differ from the component 804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * that will be written by the SCS instrution, we'll need a temporary. 805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (scs_mask != unsigned(dst.writemask)) { 807f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp = get_temp(glsl_type::vec4_type); 808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < 4; i++) { 811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned this_mask = (1U << i); 812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src0 = src; 813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((done_mask & this_mask) != 0) 815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The source swizzle specified which component of the source generates 818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sine / cosine for the current component in the destination. The SCS 819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction requires that this value be swizzle to the X component. 820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Replace the current swizzle with a swizzle that puts the source in 821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the X component. 822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned src0_swiz = GET_SWZ(src.swizzle, i); 824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src0_swiz, src0_swiz); 827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned j = i + 1; j < 4; j++) { 828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there is another enabled component in the destination that is 829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * derived from the same inputs, generate its value on this pass as 830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * well. 831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!(done_mask & (1 << j)) && 833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GET_SWZ(src0.swizzle, j) == src0_swiz) { 834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this_mask |= (1 << j); 835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this_mask != scs_mask) { 839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst; 840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp); 841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction. 843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 84456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0); 845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Move the result of the SCS instruction to the desired location in 848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the destination. 849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp.swizzle = MAKE_SWIZZLE4(component, component, 851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain component, component); 85256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp); 853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = this_mask; 854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit the SCS instruction to write directly to the destination. 856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 85756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0); 858f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask = scs_mask; 859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 861f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain done_mask |= this_mask; 862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 8653354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainint 8663354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cainglsl_to_tgsi_visitor::add_constant(gl_register_file file, 8673354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_constant_value values[4], int size, int datatype, 8683354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain GLuint *swizzle_out) 8693354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain{ 8703354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain if (file == PROGRAM_CONSTANT) { 8713354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values, 8723354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain size, datatype, swizzle_out); 8733354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } else { 8743354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int index = 0; 8753354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain immediate_storage *entry; 8763354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain assert(file == PROGRAM_IMMEDIATE); 8773354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8783354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /* Search immediate storage to see if we already have an identical 8793354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain * immediate that we can use instead of adding a duplicate entry. 8803354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain */ 8813354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain foreach_iter(exec_list_iterator, iter, this->immediates) { 8823354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry = (immediate_storage *)iter.get(); 8833354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8843354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain if (entry->size == size && 8853354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry->type == datatype && 8863354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain !memcmp(entry->values, values, size * sizeof(gl_constant_value))) { 8873354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return index; 8883354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8893354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain index++; 8903354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8913354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 8923354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain /* Add this immediate to the list. */ 8933354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain entry = new(mem_ctx) immediate_storage(values, size, datatype); 8943354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->immediates.push_tail(entry); 8953354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->num_immediates++; 8963354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return index; 8973354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain } 8983354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain} 8993354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 9007a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::st_src_reg_for_float(float val) 902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 9037732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT); 9046d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain union gl_constant_value uval; 905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 9066d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain uval.f = val; 9073354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(src.file, &uval, 1, GL_FLOAT, &src.swizzle); 908b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 909b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return src; 910b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 911b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 9127a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 913b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_int(int val) 914b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 9157732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT); 916b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain union gl_constant_value uval; 917b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 91801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke assert(native_integers); 919b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 920b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain uval.i = val; 9213354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle); 922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 9267a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunkest_src_reg 927b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cainglsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) 928b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain{ 92901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 930b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : 931b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain st_src_reg_for_int(val); 932b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 933b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain return st_src_reg_for_float(val); 934b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain} 935b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain 936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic int 937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Caintype_size(const struct glsl_type *type) 938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size; 941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (type->base_type) { 943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_matrix()) { 948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type->matrix_columns; 949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Regardless of size of vector, it gets a vec4. This is bad 951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * packing for things like floats, but otherwise arrays become a 952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * mess. Hopefully a later pass over the code can pack scalars 953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * down if appropriate. 954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_ARRAY: 958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type->length > 0); 959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return type_size(type->fields.array) * type->length; 960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_STRUCT: 961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size = 0; 962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type->length; i++) { 963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain size += type_size(type->fields.structure[i].type); 964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return size; 966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_SAMPLER: 967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Samplers take up one slot in UNIFORMS[], but they're baked in 968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * at link time. 969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 1; 971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return 0; 974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * In the initial pass of codegen, we assign temporary numbers to 979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * intermediate results. (not SSA -- variable assignments will reuse 980b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain * storage). 981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_src_reg 983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_temp(const glsl_type *type) 984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 98701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT; 988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.file = PROGRAM_TEMPORARY; 989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index = next_temp; 990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = NULL; 991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(type); 992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array() || type->is_record()) { 994f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 9965164244df02f33d6ad9e0a286f4b6d6af2dfbc75Bryan Cain src.swizzle = swizzle_for_size(type->vector_elements); 997f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.negate = 0; 999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 1001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvariable_storage * 1004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) 1005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry; 1008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->variables) { 1010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (variable_storage *)iter.get(); 1011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->var == var) 1013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 1014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 1017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_variable *ir) 1021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "gl_FragCoord") == 0) { 1023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 1024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->OriginUpperLeft = ir->origin_upper_left; 1026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fp->PixelCenterInteger = ir->pixel_center_integer; 1027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 1030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 1031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_state_slot *const slots = ir->state_slots; 1032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->state_slots != NULL); 1033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Check if this statevar's setup in the STATE file exactly 1035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * matches how we'll want to reference it as a 1036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * struct/array/whatever. If not, then we need to move it into 1037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * temporary storage and hope that it'll get copy-propagated 1038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * out. 1039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->num_state_slots; i++) { 1041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (slots[i].swizzle != SWIZZLE_XYZW) { 1042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1043f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 10467a5d28908c03c5ce38da3f041d23bfd103a5becdKenneth Graunke variable_storage *storage; 1047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg dst; 1048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i == ir->num_state_slots) { 1049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We'll set the index later. */ 1050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 1051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 1052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst = undef_dst; 1054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The variable_storage constructor allocates slots based on the size 1056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of the type. However, this had better match the number of state 1057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * elements that we're going to copy into the new temporary. 1058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert((int) ir->num_state_slots == type_size(ir->type)); 1060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 1062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 1063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 1064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(ir->type); 1065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1066b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, 106701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT)); 1068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < ir->num_state_slots; i++) { 1072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int index = _mesa_add_state_reference(this->prog->Parameters, 1073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index *)slots[i].tokens); 1074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_STATE_VAR) { 1076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->index == -1) { 1077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage->index = index; 1078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index == storage->index + (int)i); 1080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 108218a9979dc138adc743f4c19acde7218538614db9Bryan Cain /* We use GLSL_TYPE_FLOAT here regardless of the actual type of 108318a9979dc138adc743f4c19acde7218538614db9Bryan Cain * the data being moved since MOV does not care about the type of 108418a9979dc138adc743f4c19acde7218538614db9Bryan Cain * data it is moving, and we don't want to declare registers with 108518a9979dc138adc743f4c19acde7218538614db9Bryan Cain * array or struct types. 108618a9979dc138adc743f4c19acde7218538614db9Bryan Cain */ 108718a9979dc138adc743f4c19acde7218538614db9Bryan Cain st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT); 1088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = slots[i].swizzle; 108956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, dst, src); 1090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* even a float takes up a whole vec4 reg in a struct/array. */ 1091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index++; 1092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (storage->file == PROGRAM_TEMPORARY && 1096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dst.index != storage->index + (int) ir->num_state_slots) { 1097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(this->shader_program, 1098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", 1099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->name, dst.index - storage->index, 1100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type_size(ir->type)); 1101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop *ir) 1107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_variable *counter = NULL; 1109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->counter != NULL) 1111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter = new(ir) ir_dereference_variable(ir->counter); 1112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->from != NULL) { 1114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->counter != NULL); 1115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); 1117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 112256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BGNLOOP); 1123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->to) { 1125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir->cmp, glsl_type::bool_type, 1127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->to); 1128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_if *if_stmt = new(ir) ir_if(e); 1129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); 1131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->then_instructions.push_tail(brk); 1133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_stmt->accept(this); 1135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete if_stmt; 1137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete brk; 1139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->body_instructions, this); 1142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->increment) { 1144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *e = 1145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new(ir) ir_expression(ir_binop_add, counter->type, 1146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain counter, ir->increment); 1147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); 1149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a->accept(this); 1151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete a; 1152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete e; 1153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 115556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_ENDLOOP); 1156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_loop_jump *ir) 1160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->mode) { 1162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_break: 116356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_BRK); 1164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_loop_jump::jump_continue: 116656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(NULL, TGSI_OPCODE_CONT); 1167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function_signature *ir) 1174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 1176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (void)ir; 1177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_function *ir) 1181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Ignore function bodies other than main() -- we shouldn't see calls to 1183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * them since they should all be inlined before we get to glsl_to_tgsi. 1184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(ir->name, "main") == 0) { 1186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ir_function_signature *sig; 1187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list empty; 1188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig = ir->matching_signature(&empty); 1190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(sig); 1192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->body) { 1194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_instruction *ir = (ir_instruction *)iter.get(); 1195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(this); 1197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 120179a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 1202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 1203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int nonmul_operand = 1 - mul_operand; 1205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg a, b, c; 12063bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain st_dst_reg result_dst; 1207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *expr = ir->operands[mul_operand]->as_expression(); 1209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!expr || expr->operation != ir_binop_mul) 1210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[0]->accept(this); 1213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain a = this->result; 1214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain expr->operands[1]->accept(this); 1215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain b = this->result; 1216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[nonmul_operand]->accept(this); 1217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain c = this->result; 1218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = get_temp(ir->type); 12203bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst = st_dst_reg(this->result); 12213bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 12223bd06e5b82b438041f50e2469be9ea68bf3b4300Bryan Cain emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c); 1223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 12275379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain/** 12285379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * Emit MAD(a, -b, a) instead of AND(a, NOT(b)) 12295379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12305379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * The logic values are 1.0 for true and 0.0 for false. Logical-and is 12315379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * implemented using multiplication, and logical-or is implemented using 12325379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 12335379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * As result, the logical expression (a & !b) can be rewritten as: 12345379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12355379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a * !b 12365379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a * (1 - b) 12375379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - (a * 1) - (a * b) 12385379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a + -(a * b) 12395379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * - a + (a * -b) 12405379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * 12415379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * This final expression can be implemented as a single MAD(a, -b, a) 12425379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain * instruction. 12435379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain */ 12445379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cainbool 12455379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cainglsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 12465379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain{ 12475379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain const int other_operand = 1 - try_operand; 12485379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain st_src_reg a, b; 12495379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12505379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain ir_expression *expr = ir->operands[try_operand]->as_expression(); 12515379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (!expr || expr->operation != ir_unop_logic_not) 12525379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return false; 12535379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12545379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain ir->operands[other_operand]->accept(this); 12555379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain a = this->result; 12565379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain expr->operands[0]->accept(this); 12575379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain b = this->result; 12585379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12595379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain b.negate = ~b.negate; 12605379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12615379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain this->result = get_temp(ir->type); 12625379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a); 12635379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 12645379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return true; 12655379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain} 12665379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 126779a486ead92e4493b2de1fedf0c8cb5de47003cdKai Wasserbächbool 1268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir) 1269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Saturates were only introduced to vertex programs in 1271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * NV_vertex_program3, so don't give them to drivers in the VP. 1272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 1274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 1277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sat_src) 1278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return false; 1279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sat_src->accept(this); 1281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src = this->result; 1282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1283b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain /* If we generated an expression instruction into a temporary in 1284b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * processing the saturate's operand, apply the saturate to that 1285b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * instruction. Otherwise, generate a MOV to do the saturate. 1286b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * 1287b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * Note that we have to be careful to only do this optimization if 1288b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * the instruction in question was what generated src->result. For 1289b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * example, ir_dereference_array might generate a MUL instruction 1290b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * to create the reladdr, and return us a src reg using that 1291b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * reladdr. That MUL result is not the value we're trying to 1292b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain * saturate. 1293b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain */ 1294b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain ir_expression *sat_src_expr = sat_src->as_expression(); 1295b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 1296b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain sat_src_expr->operation == ir_binop_add || 1297b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain sat_src_expr->operation == ir_binop_dot)) { 1298b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain glsl_to_tgsi_instruction *new_inst; 1299b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain new_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 1300b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain new_inst->saturate = true; 1301b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain } else { 1302b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain this->result = get_temp(ir->type); 1303b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain st_dst_reg result_dst = st_dst_reg(this->result); 1304b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1305b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain glsl_to_tgsi_instruction *inst; 1306b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain inst = emit(ir, TGSI_OPCODE_MOV, result_dst, src); 1307b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain inst->saturate = true; 1308b44648c9186d403abaeeeb3190d6759f951a49e4Bryan Cain } 1309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return true; 1311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, 1315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg *reg, int *num_reladdr) 1316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!reg->reladdr) 1318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1320b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit_arl(ir, address_reg, *reg->reladdr); 1321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (*num_reladdr != 1) { 1323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::vec4_type); 1324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 132556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg); 1326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain *reg = temp; 1327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (*num_reladdr)--; 1330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_expression *ir) 1334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int operand; 1336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg op[Elements(ir->operands)]; 1337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg result_src; 1338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst; 1339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 134056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c) 1341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operation == ir_binop_add) { 1343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 1)) 1344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_mad(ir, 0)) 1346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 13485379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 13495379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 13505379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain */ 13515379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (ir->operation == ir_binop_logic_and) { 13525379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (try_emit_mad_for_and_not(ir, 1)) 13535379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return; 13545379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain if (try_emit_mad_for_and_not(ir, 0)) 13555379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain return; 13565379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain } 13575379a70d3fabd9cf92a615647f81289d33ae9468Bryan Cain 1358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (try_emit_sat(ir)) 1359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 1360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 136156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->operation == ir_quadop_vector) 136256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain assert(!"ir_quadop_vector should have been lowered"); 1363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (operand = 0; operand < ir->get_num_operands(); operand++) { 1365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(this); 1367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->result.file == PROGRAM_UNDEFINED) { 1368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_print_visitor v; 1369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to get tree for expression operand:\n"); 1370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[operand]->accept(&v); 1371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[operand] = this->result; 1374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Matrix expression operands should have been broken down to vector 1376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operations already. 1377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->operands[operand]->type->is_matrix()); 1379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int vector_elements = ir->operands[0]->type->vector_elements; 1382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[1]) { 1383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain vector_elements = MAX2(vector_elements, 1384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->vector_elements); 1385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.file = PROGRAM_UNDEFINED; 1388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 1390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 1391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = get_temp(ir->type); 1393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* convenience for the emit functions below. */ 1394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 1395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Limit writes to the channels that will be used by result_src later. 1396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This does limit this temp's use as a temporary for multi-instruction 1397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * sequences. 1398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->operation) { 1402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_logic_not: 14038c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain if (result_dst.type != GLSL_TYPE_FLOAT) 14040dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 14058c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain else { 14068c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 14078c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * older GPUs implement SEQ using multiple instructions (i915 uses two 14088c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * SGE instructions and a MUL instruction). Since our logic values are 14098c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain * 0.0 and 1.0, 1-x also implements !x. 14108c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain */ 14118c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain op[0].negate = ~op[0].negate; 14128c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0)); 14138c31bc704826d46cad65c4d65b4b70de7144205aBryan Cain } 1414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_neg: 1416c4529d10bed098b8d3d694f2a333f9afabbabbf9Bryan Cain if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT) 1417b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 1418b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else { 1419b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain op[0].negate = ~op[0].negate; 1420b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain result_src = op[0]; 1421b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_abs: 1424cc94f0541c7729bca95f21b879c2071722ca3017Dave Airlie emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]); 1425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sign: 142756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]); 1428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rcp: 143056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]); 1431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp2: 143456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]); 1435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_exp: 1437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log: 1438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"not reached: should be handled by ir_explog_to_explog2"); 1439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_log2: 144156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]); 1442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin: 144456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos: 144756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sin_reduced: 145056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_cos_reduced: 145356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdx: 145756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]); 1458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_dFdy: 146082fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák { 146182fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák /* The X component contains 1 or -1 depending on whether the framebuffer 146282fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák * is a FBO or the window system buffer, respectively. 146382fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák * It is then multiplied with the source operand of DDY. 146482fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák */ 146582fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák static const gl_state_index transform_y_state[STATE_LENGTH] 146682fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM }; 146782fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák 146882fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák unsigned transform_y_index = 146982fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák _mesa_add_state_reference(this->prog->Parameters, 147082fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák transform_y_state); 147182fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák 147282fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR, 147382fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák transform_y_index, 147482fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák glsl_type::vec4_type); 147582fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák transform_y.swizzle = SWIZZLE_XXXX; 147682fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák 147782fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák st_src_reg temp = get_temp(glsl_type::vec4_type); 147882fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák 147982fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák emit(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]); 148082fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák emit(ir, TGSI_OPCODE_DDY, result_dst, temp); 1481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 148282fc813ca870c4002502e098519bead7bec1a7e8Marek Olšák } 1483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_noise: { 1485a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain /* At some point, a motivated person could add a better 1486a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * implementation of noise. Currently not even the nvidia 1487a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * binary drivers do anything more than this. In any case, the 1488a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * place to do this is in the GL state tracker, not the poor 1489a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain * driver. 1490a6705aa5ca151278ed1e596b68a327afd1405b9eBryan Cain */ 149156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5)); 1492f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_add: 149656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 1497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_sub: 149956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]); 1500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mul: 150356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_div: 1506b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1507b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1508b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1509b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]); 1510b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_mod: 1512b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain if (result_dst.type == GLSL_TYPE_FLOAT) 1513b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1514b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1515b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]); 1516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 151956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]); 1520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 15220dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]); 1523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 15250dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]); 1526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 152856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]); 1529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_equal: 153156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_nequal: 153456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_all_equal: 1537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "==" operator producing a scalar boolean. */ 1538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 154001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke st_src_reg temp = get_temp(native_integers ? 15411141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1542b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 15439098953ee6e0699e13e35183c817ecf40363d538Bryan Cain 15446da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (native_integers) { 15456da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 15466da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 15476da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15486da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]); 15496da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15506da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Emit 1-3 AND operations to combine the SEQ results. */ 15516da8c21124152c68fb968b196895f2c881a24280Bryan Cain switch (ir->operands[0]->type->vector_elements) { 15526da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 2: 15536da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15546da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 3: 15556da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15566da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_YYYY; 15576da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_ZZZZ; 15586da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15596da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 15606da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 4: 15616da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_X; 15626da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 15636da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 15646da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15656da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 15666da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_ZZZZ; 15676da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_WWWW; 15686da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 15696da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 15706da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15716da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 15726da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 15736da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2); 15746da8c21124152c68fb968b196895f2c881a24280Bryan Cain } else { 15756da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 15766da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15776da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* After the dot-product, the value will be an integer on the 15786da8c21124152c68fb968b196895f2c881a24280Bryan Cain * range [0,4]. Zero becomes 1.0, and positive values become zero. 15796da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 15806da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 15816da8c21124152c68fb968b196895f2c881a24280Bryan Cain 15829098953ee6e0699e13e35183c817ecf40363d538Bryan Cain /* Negating the result of the dot-product gives values on the range 15839098953ee6e0699e13e35183c817ecf40363d538Bryan Cain * [-4, 0]. Zero becomes 1.0, and negative values become zero. 15849098953ee6e0699e13e35183c817ecf40363d538Bryan Cain * This is achieved using SGE. 15859098953ee6e0699e13e35183c817ecf40363d538Bryan Cain */ 15869098953ee6e0699e13e35183c817ecf40363d538Bryan Cain st_src_reg sge_src = result_src; 15879098953ee6e0699e13e35183c817ecf40363d538Bryan Cain sge_src.negate = ~sge_src.negate; 15889098953ee6e0699e13e35183c817ecf40363d538Bryan Cain emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0)); 15899098953ee6e0699e13e35183c817ecf40363d538Bryan Cain } 1590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 159156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_any_nequal: 1595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* "!=" operator producing a scalar boolean. */ 1596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->operands[0]->type->is_vector() || 1597f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[1]->type->is_vector()) { 159801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke st_src_reg temp = get_temp(native_integers ? 15991141c3f4c4014e3c2834db65b96a3ba7cc78744aBryan Cain glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1600b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain glsl_type::vec4_type); 160156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1602f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain 16036da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (native_integers) { 16046da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 16056da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 16066da8c21124152c68fb968b196895f2c881a24280Bryan Cain 16076da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Emit 1-3 OR operations to combine the SNE results. */ 16086da8c21124152c68fb968b196895f2c881a24280Bryan Cain switch (ir->operands[0]->type->vector_elements) { 16096da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 2: 16106da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 16116da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 3: 16126da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 16136da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_YYYY; 16146da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_ZZZZ; 16156da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 16166da8c21124152c68fb968b196895f2c881a24280Bryan Cain break; 16176da8c21124152c68fb968b196895f2c881a24280Bryan Cain case 4: 16186da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_X; 16196da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 16206da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 16216da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 16226da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp_dst.writemask = WRITEMASK_Y; 16236da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_ZZZZ; 16246da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_WWWW; 16256da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 16266da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 16276da8c21124152c68fb968b196895f2c881a24280Bryan Cain 16286da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp1.swizzle = SWIZZLE_XXXX; 16296da8c21124152c68fb968b196895f2c881a24280Bryan Cain temp2.swizzle = SWIZZLE_YYYY; 16306da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2); 1631f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain } else { 16326da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* After the dot-product, the value will be an integer on the 16336da8c21124152c68fb968b196895f2c881a24280Bryan Cain * range [0,4]. Zero stays zero, and positive values become 1.0. 16346da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16356da8c21124152c68fb968b196895f2c881a24280Bryan Cain glsl_to_tgsi_instruction *const dp = 16366da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit_dp(ir, result_dst, temp, temp, vector_elements); 16376da8c21124152c68fb968b196895f2c881a24280Bryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 16386da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* The clamping to [0,1] can be done for free in the fragment 16396da8c21124152c68fb968b196895f2c881a24280Bryan Cain * shader with a saturate. 16406da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16416da8c21124152c68fb968b196895f2c881a24280Bryan Cain dp->saturate = true; 16426da8c21124152c68fb968b196895f2c881a24280Bryan Cain } else { 16436da8c21124152c68fb968b196895f2c881a24280Bryan Cain /* Negating the result of the dot-product gives values on the range 16446da8c21124152c68fb968b196895f2c881a24280Bryan Cain * [-4, 0]. Zero stays zero, and negative values become 1.0. This 16456da8c21124152c68fb968b196895f2c881a24280Bryan Cain * achieved using SLT. 16466da8c21124152c68fb968b196895f2c881a24280Bryan Cain */ 16476da8c21124152c68fb968b196895f2c881a24280Bryan Cain st_src_reg slt_src = result_src; 16486da8c21124152c68fb968b196895f2c881a24280Bryan Cain slt_src.negate = ~slt_src.negate; 16496da8c21124152c68fb968b196895f2c881a24280Bryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 16506da8c21124152c68fb968b196895f2c881a24280Bryan Cain } 1651f3dce133f0422c42ca61f07f488237107efc30e6Bryan Cain } 1652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 165356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1657a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain case ir_unop_any: { 1658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1659a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain 1660a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* After the dot-product, the value will be an integer on the 1661a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * range [0,4]. Zero stays zero, and positive values become 1.0. 1662a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1663a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain glsl_to_tgsi_instruction *const dp = 1664a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit_dp(ir, result_dst, op[0], op[0], 1665a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain ir->operands[0]->type->vector_elements); 1666a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && 1667a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain result_dst.type == GLSL_TYPE_FLOAT) { 1668a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* The clamping to [0,1] can be done for free in the fragment 1669a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * shader with a saturate. 1670a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1671a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain dp->saturate = true; 1672a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } else if (result_dst.type == GLSL_TYPE_FLOAT) { 1673a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* Negating the result of the dot-product gives values on the range 1674a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1675a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain * is achieved using SLT. 1676a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain */ 1677a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain st_src_reg slt_src = result_src; 1678a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain slt_src.negate = ~slt_src.negate; 1679a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 1680a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1681a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain else { 1682a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain /* Use SNE 0 if integers are being used as boolean values. */ 1683a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); 1684a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1686a43f68810a347f3e952a0bc401be6edb91e1baeaBryan Cain } 1687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_xor: 16890dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 16900dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 16910dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 16920dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1695691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain case ir_binop_logic_or: { 16960dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 16970dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* If integers are used as booleans, we can use an actual "or" 16980dc575c6f6157867accf749a06ec745617ea64acBryan Cain * instruction. 1699691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain */ 17000dc575c6f6157867accf749a06ec745617ea64acBryan Cain assert(native_integers); 17010dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1702691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } else { 17030dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* After the addition, the value will be an integer on the 17040dc575c6f6157867accf749a06ec745617ea64acBryan Cain * range [0,2]. Zero stays zero, and positive values become 1.0. 1705691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain */ 17060dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_to_tgsi_instruction *add = 17070dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 17080dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 17090dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* The clamping to [0,1] can be done for free in the fragment 17100dc575c6f6157867accf749a06ec745617ea64acBryan Cain * shader with a saturate if floats are being used as boolean values. 17110dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17120dc575c6f6157867accf749a06ec745617ea64acBryan Cain add->saturate = true; 17130dc575c6f6157867accf749a06ec745617ea64acBryan Cain } else { 17140dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Negating the result of the addition gives values on the range 17150dc575c6f6157867accf749a06ec745617ea64acBryan Cain * [-2, 0]. Zero stays zero, and negative values become 1.0. This 17160dc575c6f6157867accf749a06ec745617ea64acBryan Cain * is achieved using SLT. 17170dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17180dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg slt_src = result_src; 17190dc575c6f6157867accf749a06ec745617ea64acBryan Cain slt_src.negate = ~slt_src.negate; 17200dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 17210dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 1722691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } 1723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1724691cc0e3a8716a2cdb7271765cd7d4c7465066ebBryan Cain } 1725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_logic_and: 17270dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* If native integers are disabled, the bool args are stored as float 0.0 17280dc575c6f6157867accf749a06ec745617ea64acBryan Cain * or 1.0, so "mul" gives us "and". If they're enabled, just use the 17290dc575c6f6157867accf749a06ec745617ea64acBryan Cain * actual AND opcode. 17300dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17310dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 17320dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 17330dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 17340dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1736f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1737f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_dot: 1738f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type->is_vector()); 1739f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->operands[0]->type == ir->operands[1]->type); 1740f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_dp(ir, result_dst, op[0], op[1], 1741f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->operands[0]->type->vector_elements); 1742f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1743f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_sqrt: 1745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* sqrt(x) = x * rsq(x). */ 174656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 174756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); 1748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For incoming channels <= 0, set the result to 0. */ 1749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0].negate = ~op[0].negate; 175056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_CMP, result_dst, 1751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain op[0], result_src, st_src_reg_for_float(0.0)); 1752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_rsq: 175456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 1755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2f: 175701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) { 1758b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]); 1759b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1760b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 17610dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* fallthrough to next case otherwise */ 17620dc575c6f6157867accf749a06ec745617ea64acBryan Cain case ir_unop_b2f: 17630dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 17640dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0)); 17650dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 17660dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 17670dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* fallthrough to next case otherwise */ 17684683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain case ir_unop_i2u: 17694683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain case ir_unop_u2i: 17704683529048ee133481b2d8f1cae1685aa1736f9aBryan Cain /* Converting between signed and unsigned integers is a no-op. */ 1771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_src = op[0]; 1772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 17730dc575c6f6157867accf749a06ec745617ea64acBryan Cain case ir_unop_b2i: 17740dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 17750dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Booleans are stored as integers using ~0 for true and 0 for false. 17760dc575c6f6157867accf749a06ec745617ea64acBryan Cain * GLSL requires that int(bool) return 1 for true and 0 for false. 17770dc575c6f6157867accf749a06ec745617ea64acBryan Cain * This conversion is done with AND, but it could be done with NEG. 17780dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17790dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1)); 17800dc575c6f6157867accf749a06ec745617ea64acBryan Cain } else { 17810dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* Booleans and integers are both stored as floats when native 17820dc575c6f6157867accf749a06ec745617ea64acBryan Cain * integers are disabled. 17830dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 17840dc575c6f6157867accf749a06ec745617ea64acBryan Cain result_src = op[0]; 17850dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 17860dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 1787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2i: 178801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 1789b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]); 1790b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 1791b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 17931be766111005e483d56ac194c224123e72ce9831Paul Berry case ir_unop_f2u: 17941be766111005e483d56ac194c224123e72ce9831Paul Berry if (native_integers) 17951be766111005e483d56ac194c224123e72ce9831Paul Berry emit(ir, TGSI_OPCODE_F2U, result_dst, op[0]); 17961be766111005e483d56ac194c224123e72ce9831Paul Berry else 17971be766111005e483d56ac194c224123e72ce9831Paul Berry emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 17981be766111005e483d56ac194c224123e72ce9831Paul Berry break; 1799e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_f2i: 1800e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_f2u: 1801e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_i2f: 1802e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert case ir_unop_bitcast_u2f: 1803e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert result_src = op[0]; 1804e16b0a51be7866f3856b62b295df2bcf49e02384Olivier Galibert break; 1805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_f2b: 18060dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 18070dc575c6f6157867accf749a06ec745617ea64acBryan Cain break; 1808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_i2b: 18090dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) 18100dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 18110dc575c6f6157867accf749a06ec745617ea64acBryan Cain else 18120dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 1813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_trunc: 181556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_ceil: 1818f7665ca4fc2a7bba8378d44d38059fc5dd536223Christoph Bumiller emit(ir, TGSI_OPCODE_CEIL, result_dst, op[0]); 1819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_floor: 182156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]); 1822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1823fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller case ir_unop_round_even: 1824fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]); 1825fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller break; 1826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_fract: 182756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]); 1828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_min: 183156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]); 1832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_max: 183456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]); 1835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_pow: 183756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]); 1838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_bit_not: 18410dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1842b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 1843b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1844b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_unop_u2f: 184601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) { 1847b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]); 1848b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1849b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lshift: 18510dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1852d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]); 1853b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1854b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_rshift: 18560dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1857d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]); 1858b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1859b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_and: 18610dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1862d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 1863b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1864b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_xor: 18660dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1867d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 1868b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1869b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_bit_or: 18710dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 1872d24b44c37d51051ff153b4f04e529f2bea6630dbBryan Cain emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1873b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain break; 1874b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 1875fc7ac4da7dfb64aa192ef8cff44cb762beace4c1Christoph Bumiller 1876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"GLSL 1.30 features unsupported"); 1877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 18792ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt case ir_binop_ubo_load: 18802ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt assert(!"not yet supported"); 18812ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt break; 18822ea3ab14f2182978f471674c9dfce029d37f70a7Eric Anholt 1883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_quadop_vector: 1884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This operation should have already been handled. 1885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 1887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 1891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_swizzle *ir) 1896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 1898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 1899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle[4]; 1900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Note that this is only swizzles in expressions, not those on the left 1902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * hand side of an assignment, which do write masking. See ir_assignment 1903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for that. 1904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->val->accept(this); 1907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 1908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(src.file != PROGRAM_UNDEFINED); 1909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < 4; i++) { 1911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i < ir->type->vector_elements) { 1912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (i) { 1913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 0: 1914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 1915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 1: 1917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 1918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 2: 1920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 1921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case 3: 1923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 1924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 1927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last 1928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channel out. 1929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle[i] = swizzle[ir->type->vector_elements - 1]; 1931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 1935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 1937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) 1941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 1942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *entry = find_variable_storage(ir->var); 1943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *var = ir->var; 1944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (var->mode) { 1947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_uniform: 1948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_in: 1953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_inout: 1954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The linker assigns locations for varyings and attributes, 1955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * including deprecated builtins (like gl_Color), user-assign 1956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic attributes (glBindVertexLocation), and 1957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * user-defined varyings. 1958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: We would hit this path for function arguments. Fix! 1960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 1961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_INPUT, 1964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_out: 1967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(var->location != -1); 1968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_OUTPUT, 1970a21df965075f6fa1bf27039490ad65b9f78548e6Dave Airlie var->location + var->index); 1971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_system_value: 1973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, 1974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain PROGRAM_SYSTEM_VALUE, 1975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain var->location); 1976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_auto: 1978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_var_temporary: 1979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 1981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(entry); 1982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp += type_size(var->type); 1984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 1985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry) { 1988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Failed to make storage for %s\n", var->name); 1989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exit(1); 1990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 1992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = st_src_reg(entry->file, entry->index, var->type); 199401d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (!native_integers) 1995b2c067e3075414703a7ebad439d4290c27cab46aBryan Cain this->result.type = GLSL_TYPE_FLOAT; 1996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 1997f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 1999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_array *ir) 2000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *index; 2002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 2003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int element_size = type_size(ir->type); 2004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index = ir->array_index->constant_expression_value(); 2006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array->accept(this); 2008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 2009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index) { 2011f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index += index->value.i[0] * element_size; 2012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Variable index array dereference. It eats the "vec4" of the 2014f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * base of the array and an index that offsets the TGSI register 2015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * index. 2016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_index->accept(this); 2018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg index_reg; 2020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_size == 1) { 2022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain index_reg = this->result; 2023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 20240dc575c6f6157867accf749a06ec745617ea64acBryan Cain index_reg = get_temp(native_integers ? 20250dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_type::int_type : glsl_type::float_type); 2026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 202756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg), 20280dc575c6f6157867accf749a06ec745617ea64acBryan Cain this->result, st_src_reg_for_type(index_reg.type, element_size)); 2029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 20313e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain /* If there was already a relative address register involved, add the 20323e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain * new and the old together to get the new offset. 20333e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain */ 20343e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain if (src.reladdr != NULL) { 20350dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg accum_reg = get_temp(native_integers ? 20360dc575c6f6157867accf749a06ec745617ea64acBryan Cain glsl_type::int_type : glsl_type::float_type); 20373e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 20383e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain emit(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg), 20393e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain index_reg, *src.reladdr); 20403e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 20413e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain index_reg = accum_reg; 20423e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain } 20433e7fce9773ec332665326a785b6ed1fcf5bd578eBryan Cain 2044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.reladdr = ralloc(mem_ctx, st_src_reg); 2045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 2046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2047f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 2049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 2050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = swizzle_for_size(ir->type->vector_elements); 2051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.swizzle = SWIZZLE_NOOP; 2053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 205418a9979dc138adc743f4c19acde7218538614db9Bryan Cain /* Change the register type to the element type of the array. */ 205518a9979dc138adc743f4c19acde7218538614db9Bryan Cain src.type = ir->type->base_type; 205618a9979dc138adc743f4c19acde7218538614db9Bryan Cain 2057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = src; 2058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_dereference_record *ir) 2062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 2064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *struct_type = ir->record->type; 2065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int offset = 0; 2066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->record->accept(this); 2068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < struct_type->length; i++) { 2070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 2071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain offset += type_size(struct_type->fields.structure[i].type); 2073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If the type is smaller than a vec4, replicate the last channel out. */ 2076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_scalar() || ir->type->is_vector()) 2077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 2078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.swizzle = SWIZZLE_NOOP; 2080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.index += offset; 208218a9979dc138adc743f4c19acde7218538614db9Bryan Cain this->result.type = ir->type->base_type; 2083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * We want to be careful in assignment setup to hit the actual storage 2087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instead of potentially using a temporary like we might with the 2088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * ir_dereference handler. 2089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic st_dst_reg 2091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v) 2092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* The LHS must be a dereference. If the LHS is a variable indexed array 2094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * access of a vector, it must be separated into a series conditional moves 2095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before reaching this point (see ir_vec_index_to_cond_assign). 2096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->as_dereference()); 2098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_dereference_array *deref_array = ir->as_dereference_array(); 2099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (deref_array) { 2100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!deref_array->array->type->is_vector()); 2101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use the rvalue deref handler for the most part. We'll ignore 2104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * swizzles in it and write swizzles using writemask, though. 2105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->accept(v); 2107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return st_dst_reg(v->result); 2108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Process the condition of a conditional assignment 2112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Examines the condition of a conditional assignment to generate the optimal 2114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * first operand of a \c CMP instruction. If the condition is a relational 2115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 2116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * used as the source for the \c CMP instruction. Otherwise the comparison 2117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * is processed to a boolean result, and the boolean result is used as the 2118f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * operand to the CMP instruction. 2119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainbool 2121f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) 2122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *src_ir = ir; 2124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool negate = true; 2125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool switch_order = false; 2126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_expression *const expr = ir->as_expression(); 2128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((expr != NULL) && (expr->get_num_operands() == 2)) { 2129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool zero_on_left = false; 2130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (expr->operands[0]->is_zero()) { 2132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[1]; 2133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = true; 2134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (expr->operands[1]->is_zero()) { 2135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = expr->operands[0]; 2136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain zero_on_left = false; 2137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* a is - 0 + - 0 + 2140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a < 0) T F F ( a < 0) T F F 2141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 < a) F F T (-a < 0) F F T 2142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 2143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 2144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a > 0) F F T (-a < 0) F F T 2145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 > a) T F F ( a < 0) T F F 2146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 2147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 2148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Note that exchanging the order of 0 and 'a' in the comparison simply 2150f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * means that the value of 'a' should be negated. 2151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_ir != ir) { 2153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (expr->operation) { 2154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_less: 2155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 2156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 2157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_greater: 2160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = false; 2161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 2162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_lequal: 2165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 2166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = !zero_on_left; 2167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_binop_gequal: 2170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch_order = true; 2171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain negate = zero_on_left; 2172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* This isn't the right kind of comparison afterall, so make sure 2176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the whole condition is visited. 2177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir = ir; 2179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_ir->accept(this); 2185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 218656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 2187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * condition we produced is 0.0 or 1.0. By flipping the sign, we can 218856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * choose which value TGSI_OPCODE_CMP produces without an extra instruction 2189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * computing the condition. 2190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (negate) 2192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 2193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return switch_order; 2195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_assignment *ir) 2199f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2200f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2201f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 2202f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->rhs->accept(this); 2205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r = this->result; 2206f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = get_assignment_lhs(ir->lhs, this); 2208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This should really set to the correct maximal writemask for each 2210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: component written (in the loops below). This case can only 2211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: occur for matrices, arrays, and structures. 2212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->write_mask == 0) { 2214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 2215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2216194732fd7299481dd57815f46a594d155260ce17Bryan Cain } else if (ir->lhs->type->is_scalar() && 2217194732fd7299481dd57815f46a594d155260ce17Bryan Cain ir->lhs->variable_referenced()->mode == ir_var_out) { 2218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 2219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FINISHME: W component of fragment shader output zero, work correctly. 2220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzles[4]; 2224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int first_enabled_chan = 0; 2225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int rhs_chan = 0; 2226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = ir->write_mask; 2228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 2230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) { 2231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_enabled_chan = GET_SWZ(r.swizzle, i); 2232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Swizzle a small RHS vector into the channels being written. 2237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * glsl ir treats write_mask as dictating how many channels are 2239f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * present on the RHS while TGSI treats write_mask as just 2240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * showing which channels of the vec4 RHS get written. 2241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 2243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (l.writemask & (1 << i)) 2244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 2245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 2246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[i] = first_enabled_chan; 2247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 2249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzles[2], swizzles[3]); 2250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(l.file != PROGRAM_UNDEFINED); 2253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(r.file != PROGRAM_UNDEFINED); 2254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 2256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const bool switch_order = this->process_move_condition(ir->condition); 2257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg condition = this->result; 2258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 22608b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain st_src_reg l_src = st_src_reg(l); 22610dc575c6f6157867accf749a06ec745617ea64acBryan Cain st_src_reg condition_temp = condition; 22628b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements); 22638b881ad1c3d9dd3c96afbdbb608a7240d40e9c92Bryan Cain 22640dc575c6f6157867accf749a06ec745617ea64acBryan Cain if (native_integers) { 22650dc575c6f6157867accf749a06ec745617ea64acBryan Cain /* This is necessary because TGSI's CMP instruction expects the 22660dc575c6f6157867accf749a06ec745617ea64acBryan Cain * condition to be a float, and we store booleans as integers. 22670dc575c6f6157867accf749a06ec745617ea64acBryan Cain * If TGSI had a UCMP instruction or similar, this extra 22680dc575c6f6157867accf749a06ec745617ea64acBryan Cain * instruction would not be necessary. 22690dc575c6f6157867accf749a06ec745617ea64acBryan Cain */ 22700dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition_temp = get_temp(glsl_type::vec4_type); 22710dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition.negate = 0; 22720dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_I2F, st_dst_reg(condition_temp), condition); 22730dc575c6f6157867accf749a06ec745617ea64acBryan Cain condition_temp.swizzle = condition.swizzle; 22740dc575c6f6157867accf749a06ec745617ea64acBryan Cain } 22750dc575c6f6157867accf749a06ec745617ea64acBryan Cain 2276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (switch_order) { 22770dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition_temp, l_src, r); 2278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 22790dc575c6f6157867accf749a06ec745617ea64acBryan Cain emit(ir, TGSI_OPCODE_CMP, l, condition_temp, r, l_src); 2280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2285f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain } else if (ir->rhs->as_expression() && 2286f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain this->instructions.get_tail() && 2287f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir && 2288e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet type_size(ir->lhs->type) == 1 && 2289e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst.writemask) { 2290f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain /* To avoid emitting an extra MOV when assigning an expression to a 22910da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * variable, emit the last instruction of the expression again, but 22920da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * replace the destination register with the target of the assignment. 22930da994a9f15b461d16cf88ce16dc07e98dfada6fBryan Cain * Dead code elimination will remove the original instruction. 2294f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain */ 2295e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet glsl_to_tgsi_instruction *inst, *new_inst; 2296f00406b68c07f97b11e873c04917cafdb1a67462Bryan Cain inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2297e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]); 2298e6c64800cc8833fb4083a556c839b51e8ac84a8bHenri Verbeet new_inst->saturate = inst->saturate; 22990dc575c6f6157867accf749a06ec745617ea64acBryan Cain inst->dead_mask = inst->dst.writemask; 2300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(ir->lhs->type); i++) { 230218a9979dc138adc743f4c19acde7218538614db9Bryan Cain if (ir->rhs->type->is_array()) 230318a9979dc138adc743f4c19acde7218538614db9Bryan Cain r.type = ir->rhs->type->element_type()->base_type; 230418a9979dc138adc743f4c19acde7218538614db9Bryan Cain else if (ir->rhs->type->is_record()) 230518a9979dc138adc743f4c19acde7218538614db9Bryan Cain r.type = ir->rhs->type->fields.structure[i].type->base_type; 230656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2310f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2311f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_constant *ir) 2316f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg src; 2318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLfloat stack_vals[4] = { 0 }; 2319b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_constant_value *values = (gl_constant_value *) stack_vals; 2320b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain GLenum gl_type = GL_NONE; 2321f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned int i; 23227732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain static int in_array = 0; 23233354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_register_file file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE; 2324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Unfortunately, 4 floats is all we can get into 23267732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * _mesa_add_typed_unnamed_constant. So, make a temp to store an 2327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * aggregate constant and move each constant value into it. If we 2328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * get lucky, copy propagation will eliminate the extra moves. 2329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->base_type == GLSL_TYPE_STRUCT) { 2331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 2332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 2333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2334f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, ir->components) { 2335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_value = (ir_constant *)iter.get(); 2336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(field_value->type); 2337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 2339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_value->accept(this); 2341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 2342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned int)size; i++) { 234456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 2345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 2347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 2348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 2351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_array()) { 2355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp_base = get_temp(ir->type); 2356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg temp = st_dst_reg(temp_base); 2357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int size = type_size(ir->type->fields.array); 2358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(size > 0); 23607732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain in_array++; 2361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->length; i++) { 2363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->array_elements[i]->accept(this); 2364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = this->result; 2365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int j = 0; j < size; j++) { 236656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, temp, src); 2367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.index++; 2369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain temp.index++; 2370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = temp_base; 23737732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain in_array--; 2374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->type->is_matrix()) { 2378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg mat = get_temp(ir->type); 2379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg mat_column = st_dst_reg(mat); 2380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->matrix_columns; i++) { 2382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(ir->type->base_type == GLSL_TYPE_FLOAT); 2383b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements]; 2384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 23857732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain src = st_src_reg(file, -1, ir->type->base_type); 23863354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain src.index = add_constant(file, 23873354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain values, 23883354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain ir->type->vector_elements, 23893354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain GL_FLOAT, 23903354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain &src.swizzle); 239156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, mat_column, src); 2392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2393f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mat_column.index++; 2394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = mat; 2397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->type->base_type) { 2401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_FLOAT: 2402b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain gl_type = GL_FLOAT; 2403b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 2404b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.f[i]; 2405b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain } 2406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_UINT: 240801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT; 2409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 241001d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2411b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].u = ir->value.u[i]; 2412b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2413b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.u[i]; 2414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_INT: 241701d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_INT : GL_FLOAT; 2418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 241901d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2420b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].i = ir->value.i[i]; 2421b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2422b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.i[i]; 2423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_TYPE_BOOL: 242601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke gl_type = native_integers ? GL_BOOL : GL_FLOAT; 2427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ir->type->vector_elements; i++) { 242801d81dedc795005ed235856ce762bb1981655716Kenneth Graunke if (native_integers) 2429673535f6071e512b18ac6da622e15bdc45ebf0a0Bryan Cain values[i].u = ir->value.b[i] ? ~0 : 0; 2430b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain else 2431b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain values[i].f = ir->value.b[i]; 2432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Non-float/uint/int/bool constant"); 2436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 24387732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain this->result = st_src_reg(file, -1, ir->type); 24393354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain this->result.index = add_constant(file, 24403354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain values, 24413354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain ir->type->vector_elements, 24423354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_type, 24433354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain &this->result.swizzle); 2444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainfunction_entry * 2447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) 2448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry; 2450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->function_signatures) { 2452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = (function_entry *)iter.get(); 2453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (entry->sig == sig) 2455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry = ralloc(mem_ctx, function_entry); 2459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig = sig; 2460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->sig_id = this->next_signature_id++; 2461f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst = NULL; 2462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Allocate storage for all the parameters. */ 2464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, sig->parameters) { 2465f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)iter.get(); 2466f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage; 2467f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2468f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = find_variable_storage(param); 2469f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!storage); 2470f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2471f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2472f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp); 2473f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->variables.push_tail(storage); 2474f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2475f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp += type_size(param->type); 2476f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2477f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2478f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!sig->return_type->is_void()) { 2479f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = get_temp(sig->return_type); 2480f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2481f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->return_reg = undef_src; 2482f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2483f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2484f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->function_signatures.push_tail(entry); 2485f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return entry; 2486f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2487f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2488f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2489f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_call *ir) 2490f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2491f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *call_inst; 249282065fa20ee3f2880a070f1f4f75509b910ceddeKenneth Graunke ir_function_signature *sig = ir->callee; 2493f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = get_function_signature(sig); 2494f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2495f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process in parameters. */ 2497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list_iterator sig_iter = sig->parameters.iterator(); 2498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_in || 2503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.file = storage->file; 2512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index = storage->index; 2513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.reladdr = NULL; 2514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.writemask = WRITEMASK_XYZW; 2515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.cond_mask = COND_TR; 2516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 251856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2526f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit call instruction */ 252956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain call_inst = emit(ir, TGSI_OPCODE_CAL); 2530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain call_inst->function = entry; 2531f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2532f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process out parameters. */ 2533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter = sig->parameters.iterator(); 2534f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, *ir) { 2535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_variable *param = (ir_variable *)sig_iter.get(); 2537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (param->mode == ir_var_out || 2539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param->mode == ir_var_inout) { 2540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain variable_storage *storage = find_variable_storage(param); 2541f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(storage); 2542f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2543f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r; 2544f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.file = storage->file; 2545f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index = storage->index; 2546f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.reladdr = NULL; 2547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.swizzle = SWIZZLE_NOOP; 2548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.negate = 0; 2549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain param_rval->accept(this); 2551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l = st_dst_reg(this->result); 2552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(param->type); i++) { 255456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2555f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2556f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2557f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2558f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2559f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2560f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sig_iter.next(); 2561f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2562f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!sig_iter.has_next()); 2563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Process return value. */ 2565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = entry->return_reg; 2566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2568f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2569f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_texture *ir) 2570f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 25712083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie st_src_reg result_src, coord, lod_info, projector, dx, dy, offset; 2572f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg result_dst, coord_dst; 2573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = NULL; 257456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain unsigned opcode = TGSI_OPCODE_NOP; 2575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2576515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie if (ir->coordinate) { 2577515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie ir->coordinate->accept(this); 2578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2579515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie /* Put our coords in a temp. We'll need to modify them for shadow, 2580515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * projection, or LOD, so the only case we'd use it as is is if 2581515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * we're doing plain old texturing. The optimization passes on 2582515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. 2583515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie */ 2584515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie coord = get_temp(glsl_type::vec4_type); 2585515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie coord_dst = st_dst_reg(coord); 2586515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2587515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie } 2588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 2590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->projector->accept(this); 2591f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain projector = this->result; 2592f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2593f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2594f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Storage for our result. Ideally for an assignment we'd be using 2595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the actual storage for the result here, instead. 2596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2597cc8ff5354da0eeba5551b5d5bd12898c38e6191fDave Airlie result_src = get_temp(ir->type); 2598f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result_dst = st_dst_reg(result_src); 2599f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2600f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (ir->op) { 2601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_tex: 260256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TEX; 2603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txb: 260556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXB; 2606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.bias->accept(this); 2607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txl: 261056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXL; 2611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.lod->accept(this); 2612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lod_info = this->result; 2613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case ir_txd: 261556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXD; 2616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdx->accept(this); 2617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dx = this->result; 2618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->lod_info.grad.dPdy->accept(this); 2619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain dy = this->result; 2620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 26211e3bcbdf31f09666ba358f35ff9486faee3642caKenneth Graunke case ir_txs: 2622515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie opcode = TGSI_OPCODE_TXQ; 2623515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie ir->lod_info.lod->accept(this); 2624515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie lod_info = this->result; 2625515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie break; 26265f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie case ir_txf: 26275f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie opcode = TGSI_OPCODE_TXF; 26285f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie ir->lod_info.lod->accept(this); 26295f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie lod_info = this->result; 26302083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie if (ir->offset) { 26312083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie ir->offset->accept(this); 26322083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset = this->result; 26332083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 2634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2636f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 26379edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák const glsl_type *sampler_type = ir->sampler->type; 26389edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 2639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->projector) { 264056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TEX) { 2641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the projector in as the last component of the coord. */ 2642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 264356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, projector); 2644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 264556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain opcode = TGSI_OPCODE_TXP; 2646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg coord_w = coord; 2648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_w.swizzle = SWIZZLE_WWWW; 2649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For the other TEX opcodes there's no projective version 265156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * since the last slot is taken up by LOD info. Do the 2652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * projective divide now. 2653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 265556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RCP, coord_dst, projector); 2656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* In the case where we have to project the coordinates "by hand," 265856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * the shadow comparator value must also be projected. 2659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg tmp_src = coord; 2661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) { 2662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 2666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_src = get_temp(glsl_type::vec4_type); 2668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg tmp_dst = st_dst_reg(tmp_src); 2669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 26709edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák /* Projective division not allowed for array samplers. */ 26719edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák assert(!sampler_type->sampler_array); 26729edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 2673f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_Z; 267456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); 2675f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2676f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain tmp_dst.writemask = WRITEMASK_XY; 267756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord); 2678f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZ; 268156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w); 2682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord.swizzle = SWIZZLE_XYZW; 2685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 268856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the shadow 268956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * comparator was put in the correct place (and projected) by the code, 2690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * above, that handles by-hand projection. 2691f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 269256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (ir->shadow_comparitor && (!ir->projector || opcode == TGSI_OPCODE_TXP)) { 2693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Slot the shadow value in as the second to last component of the 2694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * coord. 2695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2696f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->shadow_comparitor->accept(this); 26979edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 26989edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák /* XXX This will need to be updated for cubemap array samplers. */ 26992f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && 27002f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie sampler_type->sampler_array) || 27012f275466f78b7268e4f7ae8890eafd4243a2b8b0Dave Airlie sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) { 27029edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák coord_dst.writemask = WRITEMASK_W; 27039edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák } else { 27049edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák coord_dst.writemask = WRITEMASK_Z; 27059edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák } 27069edd0b5ddf406ef089edebd12999ff2a26774ca3Marek Olšák 270756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 27115f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || 27125f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie opcode == TGSI_OPCODE_TXF) { 271356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* TGSI stores LOD or LOD bias in the last channel of the coords. */ 2714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_W; 271556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info); 2716f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain coord_dst.writemask = WRITEMASK_XYZW; 2717f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2718f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 271956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (opcode == TGSI_OPCODE_TXD) 2720f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord, dx, dy); 2721515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie else if (opcode == TGSI_OPCODE_TXQ) 2722515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie inst = emit(ir, opcode, result_dst, lod_info); 27232083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie else if (opcode == TGSI_OPCODE_TXF) { 27242083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst = emit(ir, opcode, result_dst, coord); 27252083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } else 2726f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst = emit(ir, opcode, result_dst, coord); 2727f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2728f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->shadow_comparitor) 2729f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_shadow = GL_TRUE; 2730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->shader_program, 2733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->prog); 2734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 27352083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie if (ir->offset) { 27362083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offset_num_offset = 1; 27372083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].Index = offset.index; 27382083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].File = offset.file; 27392083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0); 27402083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1); 27412083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2); 27422083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 27432083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 2744f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (sampler_type->sampler_dimensionality) { 2745f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_1D: 2746f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2747f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2748f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2749f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_2D: 2750f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = (sampler_type->sampler_array) 2751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_3D: 2754f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_3D_INDEX; 2755f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_CUBE: 2757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_CUBE_INDEX; 2758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_RECT: 2760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->tex_target = TEXTURE_RECT_INDEX; 2761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 2762f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GLSL_SAMPLER_DIM_BUF: 2763f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"FINISHME: Implement ARB_texture_buffer_object"); 2764f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 27658cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu case GLSL_SAMPLER_DIM_EXTERNAL: 27668cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu inst->tex_target = TEXTURE_EXTERNAL_INDEX; 27678cd0873d319cefce74164147c9855e81f051d1e1Chia-I Wu break; 2768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 2769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"Should not get here."); 2770f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2771f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result = result_src; 2773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2774f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2775f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2776f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_return *ir) 2777f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2778f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->get_value()) { 2779f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_dst_reg l; 2780f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 2781f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2782f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(current_function); 2783f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2784f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->get_value()->accept(this); 2785f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg r = this->result; 2786f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2787f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l = st_dst_reg(current_function->return_reg); 2788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2789f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < type_size(current_function->sig->return_type); i++) { 279056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_MOV, l, r); 2791f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain l.index++; 2792f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain r.index++; 2793f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2794f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2795f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 279656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_RET); 2797f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2799f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_discard *ir) 2801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ir->condition) { 2803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->result.negate = ~this->result.negate; 280556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KIL, undef_dst, this->result); 2806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 280756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain emit(ir, TGSI_OPCODE_KILP); 2808f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 2812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::visit(ir_if *ir) 2813f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 28146e7942936c5de59f509779b6f7620d80d2fbc21aMarek Olšák glsl_to_tgsi_instruction *cond_inst, *if_inst; 2815f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *prev_inst; 2816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prev_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2819f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir->condition->accept(this); 2820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(this->result.file != PROGRAM_UNDEFINED); 2821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (this->options->EmitCondCodes) { 2823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we actually generated any instruction for generating 2826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the condition. If not, then cook up a move to a temp so we 2827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have something to set cond_update on. 2828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (cond_inst == prev_inst) { 2830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain st_src_reg temp = get_temp(glsl_type::bool_type); 283156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain cond_inst = emit(ir->condition, TGSI_OPCODE_MOV, st_dst_reg(temp), result); 2832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain cond_inst->cond_update = GL_TRUE; 2834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 283556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF); 2836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if_inst->dst.cond_mask = COND_NE; 2837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 283856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result); 2839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->instructions.push_tail(if_inst); 2842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->then_instructions, this); 2844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!ir->else_instructions.is_empty()) { 28466e7942936c5de59f509779b6f7620d80d2fbc21aMarek Olšák emit(ir->condition, TGSI_OPCODE_ELSE); 2847f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&ir->else_instructions, this); 2848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 285056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); 2851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2852f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2853f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::glsl_to_tgsi_visitor() 2854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2855f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain result.file = PROGRAM_UNDEFINED; 2856f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_temp = 1; 2857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain next_signature_id = 1; 28583354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain num_immediates = 0; 2859f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain current_function = NULL; 2860f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain num_address_regs = 0; 2861105f307d90de92d088116516957e37267d9fe115Vinson Lee samplers_used = 0; 2862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_temps = false; 2863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain indirect_addr_consts = false; 2864105f307d90de92d088116516957e37267d9fe115Vinson Lee glsl_version = 0; 2865105f307d90de92d088116516957e37267d9fe115Vinson Lee native_integers = false; 2866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain mem_ctx = ralloc_context(NULL); 286770d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee ctx = NULL; 286870d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee prog = NULL; 286970d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee shader_program = NULL; 287070d038e46eb877ffa922003c78630eb7eb76c0f3Vinson Lee options = NULL; 2871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::~glsl_to_tgsi_visitor() 2874f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(mem_ctx); 2876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v) 2879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete v; 2881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 2885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Count resources used by the given gpu program (number of texture 2886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * samplers, etc). 2887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 2888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 28895768ed6429937940bd48f5de4f8383273952880aBryan Caincount_resources(glsl_to_tgsi_visitor *v, gl_program *prog) 2890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 289144867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used = 0; 2892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 289344867da3543ca54ef245695cef72a6e305451d93Bryan Cain foreach_iter(exec_list_iterator, iter, v->instructions) { 289444867da3543ca54ef245695cef72a6e305451d93Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 289656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (is_tex_instruction(inst->op)) { 289744867da3543ca54ef245695cef72a6e305451d93Bryan Cain v->samplers_used |= 1 << inst->sampler; 28985768ed6429937940bd48f5de4f8383273952880aBryan Cain 28995768ed6429937940bd48f5de4f8383273952880aBryan Cain if (inst->tex_shadow) { 29005768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->ShadowSamplers |= 1 << inst->sampler; 29015768ed6429937940bd48f5de4f8383273952880aBryan Cain } 2902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 29045768ed6429937940bd48f5de4f8383273952880aBryan Cain 29055768ed6429937940bd48f5de4f8383273952880aBryan Cain prog->SamplersUsed = v->samplers_used; 29066a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick 29076a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick if (v->shader_program != NULL) 29086a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick _mesa_update_shader_textures_used(v->shader_program, prog); 2909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 2912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 2913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 2914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *name, const glsl_type *type, 2915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *val) 2916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 2917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_record()) { 2918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *field_constant; 2919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)val->components.get_head(); 2921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < type->length; i++) { 2923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *field_type = type->fields.structure[i].type; 2924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 2925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type->fields.structure[i].name); 2926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 2927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_type, field_constant); 2928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain field_constant = (ir_constant *)field_constant->next; 2929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2933abcdbdf9cce3c7520ee999fac3099d609960847dEric Anholt unsigned offset; 2934abcdbdf9cce3c7520ee999fac3099d609960847dEric Anholt unsigned index = _mesa_get_uniform_location(ctx, shader_program, name, 2935abcdbdf9cce3c7520ee999fac3099d609960847dEric Anholt &offset); 2936abcdbdf9cce3c7520ee999fac3099d609960847dEric Anholt if (offset == GL_INVALID_INDEX) { 2937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain fail_link(shader_program, 2938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain "Couldn't find uniform for initializer %s\n", name); 2939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 2940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2941abcdbdf9cce3c7520ee999fac3099d609960847dEric Anholt int loc = _mesa_uniform_merge_location_offset(index, offset); 2942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 2944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ir_constant *element; 2945f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const glsl_type *element_type; 2946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (type->is_array()) { 2947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val->array_elements[i]; 2948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type->fields.array; 2949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element = val; 2951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = type; 2952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain void *values; 2955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->base_type == GLSL_TYPE_BOOL) { 2957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *conv = ralloc_array(mem_ctx, int, element_type->components()); 2958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned int j = 0; j < element_type->components(); j++) { 2959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain conv[j] = element->value.b[j]; 2960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = (void *)conv; 2962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type = glsl_type::get_instance(GLSL_TYPE_INT, 2963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 1); 2965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values = &element->value; 2967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 2969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (element_type->is_matrix()) { 2970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform_matrix(ctx, shader_program, 2971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->matrix_columns, 2972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain element_type->vector_elements, 2973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loc, 1, GL_FALSE, (GLfloat *)values); 2974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 2975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 2976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain values, element_type->gl_type); 2977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2978719909698c67c287a393d2380278e7b7495ae018Ian Romanick 2979719909698c67c287a393d2380278e7b7495ae018Ian Romanick loc++; 2980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 2981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 2982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 298329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 298429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which 298529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * are read from the given src in this instruction 298629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 298729d21417e38aed0f0710d3692df320728aef90b1Bryan Cainstatic int 298829d21417e38aed0f0710d3692df320728aef90b1Bryan Cainget_src_arg_mask(st_dst_reg dst, st_src_reg src) 298929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 299029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain int read_mask = 0, comp; 299129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 299229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Now, given the src swizzle and the written channels, find which 299329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * components are actually read 299429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 299529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain for (comp = 0; comp < 4; ++comp) { 299629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain const unsigned coord = GET_SWZ(src.swizzle, comp); 299729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain ASSERT(coord < 4); 299829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W) 299929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain read_mask |= 1 << coord; 300029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 300129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 300229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain return read_mask; 300329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 300429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 300529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain/** 300629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP 300729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * instruction is the first instruction to write to register T0. There are 300829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * several lowering passes done in GLSL IR (e.g. branches and 300929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * relative addressing) that create a large number of conditional assignments 301029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * that ir_to_mesa converts to CMP instructions like the one mentioned above. 301129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 301229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Here is why this conversion is safe: 301329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * CMP T0, T1 T2 T0 can be expanded to: 301429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * if (T1 < 0.0) 301529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T2; 301629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * else 301729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0; 301829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * 301929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same 302029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * as the original program. If (T1 < 0.0) evaluates to false, executing 302129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized. 302229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2 302329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * because any instruction that was going to read from T0 after this was going 302429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * to read a garbage value anyway. 302529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain */ 302629d21417e38aed0f0710d3692df320728aef90b1Bryan Cainvoid 302729d21417e38aed0f0710d3692df320728aef90b1Bryan Cainglsl_to_tgsi_visitor::simplify_cmp(void) 302829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain{ 3029794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca unsigned *tempWrites; 303029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned outputWrites[MAX_PROGRAM_OUTPUTS]; 303129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 3032794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca tempWrites = new unsigned[MAX_TEMPS]; 3033794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (!tempWrites) { 3034794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca return; 3035794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 30361d01429c6a1ae679d0cc0cb61db1948fca5ced4cMathias Fröhlich memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS); 303729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain memset(outputWrites, 0, sizeof(outputWrites)); 303829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 303929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 304029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 304129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain unsigned prevWriteMask = 0; 304229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 304329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* Give up if we encounter relative addressing or flow control. */ 304429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.reladdr || 304529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tgsi_get_opcode_info(inst->op)->is_branch || 304629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_BGNSUB || 304729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_CONT || 304829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_END || 304929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_ENDSUB || 305029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op == TGSI_OPCODE_RET) { 3051794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca break; 305229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 305329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 305429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) { 305529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain assert(inst->dst.index < MAX_PROGRAM_OUTPUTS); 305629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = outputWrites[inst->dst.index]; 305729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain outputWrites[inst->dst.index] |= inst->dst.writemask; 305829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY) { 305933e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain assert(inst->dst.index < MAX_TEMPS); 306029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain prevWriteMask = tempWrites[inst->dst.index]; 306129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain tempWrites[inst->dst.index] |= inst->dst.writemask; 306229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 306329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 306429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain /* For a CMP to be considered a conditional write, the destination 306529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain * register and source register two must be the same. */ 306629d21417e38aed0f0710d3692df320728aef90b1Bryan Cain if (inst->op == TGSI_OPCODE_CMP 306729d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && !(inst->dst.writemask & prevWriteMask) 306829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].file == inst->dst.file 306929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->src[2].index == inst->dst.index 307029d21417e38aed0f0710d3692df320728aef90b1Bryan Cain && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) { 307129d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 307229d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->op = TGSI_OPCODE_MOV; 307329d21417e38aed0f0710d3692df320728aef90b1Bryan Cain inst->src[0] = inst->src[1]; 307429d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 307529d21417e38aed0f0710d3692df320728aef90b1Bryan Cain } 3076794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 3077794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca delete [] tempWrites; 307829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain} 307929d21417e38aed0f0710d3692df320728aef90b1Bryan Cain 3080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Replaces all references to a temporary register index with another index. */ 3081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) 3083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned j; 3087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 308856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3089f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index = new_index; 3092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3093f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.index = new_index; 3097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_read(int index) 3103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 3107f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3108f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3110f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 311156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3113f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3114f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 3115f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3116f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3117f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 311856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 3119f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 3120f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 312156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3122f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 3123f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 3124f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3125f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3126f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3127f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3128f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3129f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3130f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 3131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3132f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3133f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3134f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_first_temp_write(int index) 3135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3137f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3143f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return (depth == 0) ? i : loop_start; 3145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3146f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 314756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) { 3148f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if(depth++ == 0) 3149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = i; 315056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3151f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0) 3152f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain loop_start = -1; 3153f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3154f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return -1; 3160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_read(int index) 3164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that reads the temporary */ 3167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i = 0, j; 3168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 317256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain for (j=0; j < num_inst_src_regs(inst->op); j++) { 3173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[j].file == PROGRAM_TEMPORARY && 3174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[j].index == index) { 3175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 317956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 318156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3185f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3186f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3187f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3188f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3189f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3190f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3191f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3192f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3193f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainint 3194f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::get_last_temp_write(int index) 3195f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3196f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int depth = 0; /* loop depth */ 3197f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last = -1; /* index of last instruction that writes to the temporary */ 3198f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 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 if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) 3204f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (depth == 0) ? i : -2; 3205f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 320656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_BGNLOOP) 3207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain depth++; 320856dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain else if (inst->op == TGSI_OPCODE_ENDLOOP) 3209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (--depth == 0 && last == -2) 3210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = i; 3211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(depth >= 0); 3212f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3213f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i++; 3214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(last >= -1); 3217f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return last; 3218f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3221f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY register 3222f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * channels for copy propagation and updates following instructions to 3223f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * use the original versions. 3224f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production before this pass: 3227f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3229f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3230f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 3231f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3232f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after: 3233f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3234f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3235f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3236f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3237f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3238f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * which allows for dead code elimination on TEMP[1]'s writes. 3239f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3240f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::copy_propagate(void) 3242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3243f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx, 3244f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *, 3245f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp * 4); 3246f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 3247f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int level = 0; 3248f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3249f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3251f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3252f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 3253f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || inst->dst.index < this->next_temp); 3254f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3255f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* First, do any copy propagation possible into the src regs. */ 3256f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < 3; r++) { 3257f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *first = NULL; 3258f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool good = true; 3259f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int acp_base = inst->src[r].index * 4; 3260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->src[r].file != PROGRAM_TEMPORARY || 3262f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].reladdr) 3263f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3264f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* See if we can find entries in the ACP consisting of MOVs 3266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from the same src register for all the swizzled channels 3267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of this src register reference. 3268f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3269f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3270f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3271f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan]; 3272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!copy_chan) { 3274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3277f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(acp_level[acp_base + src_chan] <= level); 3279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!first) { 3281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first = copy_chan; 3282f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 3283f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (first->src[0].file != copy_chan->src[0].file || 3284f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first->src[0].index != copy_chan->src[0].index) { 3285f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain good = false; 3286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (good) { 3292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We've now validated that we can copy-propagate to 3293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * replace this src register reference. Do it. 3294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].file = first->src[0].file; 3296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].index = first->src[0].index; 3297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int swizzle = 0; 3299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan]; 3302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 3303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (3 * i)); 3304f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3305f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->src[r].swizzle = swizzle; 3306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3308f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3309f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (inst->op) { 331056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 331156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 3312f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* End of a basic block, clear the ACP entirely. */ 3313f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3314f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3315f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 331656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 3317f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ++level; 3318f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3319f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 332056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDIF: 332156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 3322f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear all channels written inside the block from the ACP, but 3323f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * leaving those that were not touched. 3324f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3325f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3326f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3327f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3328f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3329f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3330f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp_level[4 * r + c] >= level) 3331f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 333456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_ENDIF) 3335f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain --level; 3336f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 3339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Continuing the block, clear any written channels from 3340f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the ACP. 3341f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3342f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 3343f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any temporary might be written, so no copy propagation 3344f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * across this instruction. 3345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_OUTPUT && 3348f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.reladdr) { 3349f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Any output might be written, so no copy propagation 3350f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * from outputs across this instruction. 3351f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3352f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 3358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else if (inst->dst.file == PROGRAM_TEMPORARY || 3362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_OUTPUT) { 3363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as dst. */ 3364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY) { 3365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << c)) { 3367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + c] = NULL; 3368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Clear where it's used as src. */ 3373f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int r = 0; r < this->next_temp; r++) { 3374f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int c = 0; c < 4; c++) { 3375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!acp[4 * r + c]) 3376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 3377f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3378f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 3379f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3380f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (acp[4 * r + c]->src[0].file == inst->dst.file && 3381f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c]->src[0].index == inst->dst.index && 3382f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.writemask & (1 << src_chan)) 3383f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3384f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * r + c] = NULL; 3385f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3386f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3387f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3388f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3389f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 3390f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3391f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3392f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If this is a copy, add it to the ACP. */ 339356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (inst->op == TGSI_OPCODE_MOV && 3394f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inst->dst.file == PROGRAM_TEMPORARY && 3395f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->dst.reladdr && 3396f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->saturate && 3397f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].reladdr && 3398f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain !inst->src[0].negate) { 3399f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (int i = 0; i < 4; i++) { 3400f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.writemask & (1 << i)) { 3401f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp[4 * inst->dst.index + i] = inst; 3402f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain acp_level[4 * inst->dst.index + i] = level; 3403f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp_level); 3409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(acp); 3410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* 3413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Tracks available PROGRAM_TEMPORARY registers for dead code elimination. 3414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will occur. As an example, a TXP production after copy propagation but 3417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * before this pass: 3418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: MOV TEMP[1], INPUT[4].xyyy; 3420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 1: MOV TEMP[1].w, INPUT[4].wwww; 3421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and after this pass: 3424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB) 3428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * FIXME: doesn't eliminate all dead code inside of loops; it steps around them 3429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3431f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::eliminate_dead_code(void) 3432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3433f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i; 3434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3435f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3436f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int last_read = get_last_temp_read(i); 3437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int j = 0; 3438f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3439f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 3440f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3441f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && 3443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j > last_read) 3444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 3445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain iter.remove(); 3446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain delete inst; 3447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain j++; 3450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3452f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 345441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain/* 345541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead 345641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * code elimination. This is less primitive than eliminate_dead_code(), as it 345741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is per-channel and can detect consecutive writes without a read between them 345841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * as dead code. However, there is some dead code that can be eliminated by 345941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * eliminate_dead_code() but not this function - for example, this function 346041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * cannot eliminate an instruction writing to a register that is never read and 346141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * is the only instruction writing to that register. 346241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * 346341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 346441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * will occur. 346541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 346641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainint 346741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cainglsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) 346841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain{ 346941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx, 347041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *, 347141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain this->next_temp * 4); 347241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 347341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int level = 0; 347441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int removed = 0; 347541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 347641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 347741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 347841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 347941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain assert(inst->dst.file != PROGRAM_TEMPORARY 348041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain || inst->dst.index < this->next_temp); 348141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 348241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain switch (inst->op) { 348341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_BGNLOOP: 348441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDLOOP: 348509497e020a11cc893d06691751faf57c1e762839Bryan Cain case TGSI_OPCODE_CONT: 348609497e020a11cc893d06691751faf57c1e762839Bryan Cain case TGSI_OPCODE_BRK: 348741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* End of a basic block, clear the write array entirely. 348809497e020a11cc893d06691751faf57c1e762839Bryan Cain * 348909497e020a11cc893d06691751faf57c1e762839Bryan Cain * This keeps us from killing dead code when the writes are 349041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * on either side of a loop, even when the register isn't touched 349109497e020a11cc893d06691751faf57c1e762839Bryan Cain * inside the loop. However, glsl_to_tgsi_visitor doesn't seem to emit 349209497e020a11cc893d06691751faf57c1e762839Bryan Cain * dead code of this type, so it shouldn't make a difference as long as 349309497e020a11cc893d06691751faf57c1e762839Bryan Cain * the dead code elimination pass in the GLSL compiler does its job. 349441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 349541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 349641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 349741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 349841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ENDIF: 349941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain case TGSI_OPCODE_ELSE: 35003b15f5046c36fb2d32a4c5f36e77b74efcb539b2Bryan Cain /* Promote the recorded level of all channels written inside the 35013b15f5046c36fb2d32a4c5f36e77b74efcb539b2Bryan Cain * preceding if or else block to the level above the if/else block. 350241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 350341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int r = 0; r < this->next_temp; r++) { 350441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 350541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!writes[4 * r + c]) 350641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 350741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 350820b0daf82de91fd57b7e8d825786789149f6358dBryan Cain if (write_level[4 * r + c] == level) 350920b0daf82de91fd57b7e8d825786789149f6358dBryan Cain write_level[4 * r + c] = level-1; 351041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 351141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 351220b0daf82de91fd57b7e8d825786789149f6358dBryan Cain 351320b0daf82de91fd57b7e8d825786789149f6358dBryan Cain if(inst->op == TGSI_OPCODE_ENDIF) 351420b0daf82de91fd57b7e8d825786789149f6358dBryan Cain --level; 351520b0daf82de91fd57b7e8d825786789149f6358dBryan Cain 351641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 351741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 35184c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain case TGSI_OPCODE_IF: 35194c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain ++level; 35204c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain /* fallthrough to default case to mark the condition as read */ 35214c8b6a286887628e5fc35306189a4c4a83c482eaBryan Cain 352241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain default: 352341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Continuing the block, clear any channels from the write array that 352441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * are read by this instruction. 352541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 3526718b894dbb585af52dd24defb2e8c130216e5485Brian Paul for (unsigned i = 0; i < Elements(inst->src); i++) { 352741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ 352841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Any temporary might be read, so no dead code elimination 352941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * across this instruction. 353041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 353141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 353241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else if (inst->src[i].file == PROGRAM_TEMPORARY) { 353341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Clear where it's used as src. */ 353441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0); 353541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1); 353641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2); 353741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3); 353841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 353941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 354041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (src_chans & (1 << c)) { 354141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->src[i].index + c] = NULL; 354241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain break; 354741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 354841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 354941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* If this instruction writes to a temporary, add it to the write array. 355041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * If there is already an instruction in the write array for one or more 355141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * of the channels, flag that channel write as dead. 355241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 355341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.file == PROGRAM_TEMPORARY && 355441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->dst.reladdr && 355541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain !inst->saturate) { 355641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain for (int c = 0; c < 4; c++) { 355741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (inst->dst.writemask & (1 << c)) { 355841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (writes[4 * inst->dst.index + c]) { 355941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (write_level[4 * inst->dst.index + c] < level) 356041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 356141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain else 356241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c]->dead_mask |= (1 << c); 356341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 356441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain writes[4 * inst->dst.index + c] = inst; 356541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain write_level[4 * inst->dst.index + c] = level; 356641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 356741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 356841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 356941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 357041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 357171cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain /* Anything still in the write array at this point is dead code. */ 357271cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int r = 0; r < this->next_temp; r++) { 357371cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain for (int c = 0; c < 4; c++) { 357471cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain glsl_to_tgsi_instruction *inst = writes[4 * r + c]; 357571cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain if (inst) 357671cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain inst->dead_mask |= (1 << c); 357771cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 357871cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain } 357971cbc9e3c4c9ef6090ee31e87601ae64af26321eBryan Cain 358041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain /* Now actually remove the instructions that are completely dead and update 358141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain * the writemask of other instructions with dead channels. 358241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain */ 358341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain foreach_iter(exec_list_iterator, iter, this->instructions) { 358441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 358541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 358641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain if (!inst->dead_mask || !inst->dst.writemask) 358741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain continue; 3588a9e5528f09a835b66771ba4d3f08ff7fd51e08a6Brian Paul else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { 358941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain iter.remove(); 359041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain delete inst; 359141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain removed++; 359241472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } else 359341472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain inst->dst.writemask &= ~(inst->dead_mask); 359441472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain } 359541472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 359641472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(write_level); 359741472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain ralloc_free(writes); 359841472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 359941472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain return removed; 360041472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain} 360141472f7809dcff114223b8fadc5b97baff6060a9Bryan Cain 3602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Merges temporary registers together where possible to reduce the number of 3603f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * registers needed to run a program. 3604f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 3605f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Produces optimal code only after copy propagation and dead code elimination 3606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * have been run. */ 3607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3608f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::merge_registers(void) 3609f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3610f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp); 3611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp); 3612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i, j; 3613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Read the indices of the last read and first write to each temp register 3615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * into an array so that we don't have to traverse the instruction list as 3616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * much. */ 3617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = get_last_temp_read(i); 3619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[i] = get_first_temp_write(i); 3620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Start looking for registers with non-overlapping usages that can be 3623f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * merged together. */ 3624556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (i=0; i < this->next_temp; i++) { 3625f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[i] < 0 || first_writes[i] < 0) continue; 3627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3628556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain for (j=0; j < this->next_temp; j++) { 3629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Don't touch unused registers. */ 3630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (last_reads[j] < 0 || first_writes[j] < 0) continue; 3631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* We can merge the two registers if the first write to j is after or 3633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in the same instruction as the last read from i. Note that the 3634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register at index i will always be used earlier or at the same time 3635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * as the register at index j. */ 3636556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain if (first_writes[i] <= first_writes[j] && 3637556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain last_reads[i] <= first_writes[j]) 3638556bd82ce1227a568d69dfa0c22841986267d39fBryan Cain { 3639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(j, i); /* Replace all references to j with i.*/ 3640f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3641f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Update the first_writes and last_reads arrays with the new 3642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * values for the merged register index, and mark the newly unused 3643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * register index as such. */ 3644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[i] = last_reads[j]; 3645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain first_writes[j] = -1; 3646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last_reads[j] = -1; 3647f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3648f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(last_reads); 3652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ralloc_free(first_writes); 3653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* Reassign indices to temporary registers by reusing unused indices created 3656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * by optimization passes. */ 3657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainvoid 3658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainglsl_to_tgsi_visitor::renumber_registers(void) 3659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3660f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int i = 0; 3661f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int new_index = 0; 3662f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3663f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < this->next_temp; i++) { 3664f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (get_first_temp_read(i) < 0) continue; 3665f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (i != new_index) 3666f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain rename_temp_register(i, new_index); 3667f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain new_index++; 3668f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3669f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3670f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain this->next_temp = new_index; 3671f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3672f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3673c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain/** 3674c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Returns a fragment program which implements the current pixel transfer ops. 3675c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Based on get_pixel_transfer_program in st_atom_pixeltransfer.c. 3676c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3677c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainextern "C" void 3678c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cainget_pixel_transfer_visitor(struct st_fragment_program *fp, 3679c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_visitor *original, 3680c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain int scale_and_bias, int pixel_maps) 3681c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain{ 3682c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 3683c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct st_context *st = st_context(original->ctx); 3684c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct gl_program *prog = &fp->Base.Base; 3685c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain struct gl_program_parameter_list *params = _mesa_new_parameter_list(); 3686c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg coord, src0; 3687c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_dst_reg dst0; 3688c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_instruction *inst; 3689c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3690c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 3691c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->ctx = original->ctx; 3692c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->prog = prog; 3693d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin v->shader_program = NULL; 3694c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->glsl_version = original->glsl_version; 369501d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = original->native_integers; 3696c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->options = original->options; 3697c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->next_temp = original->next_temp; 3698c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->num_address_regs = original->num_address_regs; 3699c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used = prog->SamplersUsed = original->samplers_used; 3700c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->indirect_addr_temps = original->indirect_addr_temps; 3701c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->indirect_addr_consts = original->indirect_addr_consts; 37023354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3703fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul v->num_immediates = original->num_immediates; 3704c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3705c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* 3706c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * Get initial pixel color from the texture. 3707c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; 3708c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3709c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 3710c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src0 = v->get_temp(glsl_type::vec4_type); 3711c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain dst0 = st_dst_reg(src0); 3712c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 3713c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 0; 3714c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3715c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3716dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= FRAG_BIT_TEX0; 3717c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */ 3718c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used |= (1 << 0); 3719c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3720c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (scale_and_bias) { 3721c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain static const gl_state_index scale_state[STATE_LENGTH] = 3722c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { STATE_INTERNAL, STATE_PT_SCALE, 3723c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3724c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain static const gl_state_index bias_state[STATE_LENGTH] = 3725c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { STATE_INTERNAL, STATE_PT_BIAS, 3726c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3727c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain GLint scale_p, bias_p; 3728c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg scale, bias; 3729c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3730c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scale_p = _mesa_add_state_reference(params, scale_state); 3731c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain bias_p = _mesa_add_state_reference(params, bias_state); 3732c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3733c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* MAD colorTemp, colorTemp, scale, bias; */ 3734c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT); 3735c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT); 3736c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias); 3737c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3738c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3739c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (pixel_maps) { 3740c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg temp = v->get_temp(glsl_type::vec4_type); 3741c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_dst_reg temp_dst = st_dst_reg(temp); 3742c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3743c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain assert(st->pixel_xfer.pixelmap_texture); 3744c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3745c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* With a little effort, we can do four pixel map look-ups with 3746c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * two TEX instructions: 3747c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain */ 3748c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3749c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ 3750c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain temp_dst.writemask = WRITEMASK_XY; /* write R,G */ 3751c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3752c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 1; 3753c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3754c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3755c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ 3756c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); 3757c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain temp_dst.writemask = WRITEMASK_ZW; /* write B,A */ 3758c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3759c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->sampler = 1; 3760c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst->tex_target = TEXTURE_2D_INDEX; 3761c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3762c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */ 3763c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain v->samplers_used |= (1 << 1); 3764c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3765c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* MOV colorTemp, temp; */ 3766c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp); 3767c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3768c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3769c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 3770c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain * new visitor. */ 3771c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain foreach_iter(exec_list_iterator, iter, original->instructions) { 3772c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 37733788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie glsl_to_tgsi_instruction *newinst; 3774c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain st_src_reg src_regs[3]; 3775c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 377687f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) 377787f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 377887f8d8547db9b947ae847c509a464e06d0ac6c64Bryan Cain 3779c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain for (int i=0; i<3; i++) { 3780c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i] = inst->src[i]; 3781c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain if (src_regs[i].file == PROGRAM_INPUT && 3782c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].index == FRAG_ATTRIB_COL0) 3783c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain { 3784c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].file = PROGRAM_TEMPORARY; 3785c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain src_regs[i].index = src0.index; 3786c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3787c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain else if (src_regs[i].file == PROGRAM_INPUT) 3788dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 3789c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3790c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 37913788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 37923788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst->tex_target = inst->tex_target; 3793c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain } 3794c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 3795c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain /* Make modifications to fragment program info. */ 3796c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain prog->Parameters = _mesa_combine_parameter_lists(params, 3797c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain original->prog->Parameters); 3798c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain _mesa_free_parameter_list(params); 3799c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain count_resources(v, prog); 3800c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain fp->glsl_to_tgsi = v; 3801c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain} 3802c0dcab2882a4731dccd363a40c3ebcabc88b9c5dBryan Cain 38035f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain/** 38045f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Make fragment program for glBitmap: 38055f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Sample the texture and kill the fragment if the bit is 0. 38065f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * This program will be combined with the user's fragment program. 38075f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * 38085f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * Based on make_bitmap_fragment_program in st_cb_bitmap.c. 38095f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain */ 38105f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cainextern "C" void 38115f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cainget_bitmap_visitor(struct st_fragment_program *fp, 38125f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_visitor *original, int samplerIndex) 38135f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain{ 38145f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 38155f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain struct st_context *st = st_context(original->ctx); 38165f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain struct gl_program *prog = &fp->Base.Base; 38175f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_src_reg coord, src0; 38185f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_dst_reg dst0; 38195f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_instruction *inst; 38205f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38215f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 38225f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->ctx = original->ctx; 38235f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->prog = prog; 3824d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin v->shader_program = NULL; 38255f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->glsl_version = original->glsl_version; 382601d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = original->native_integers; 38275f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->options = original->options; 38285f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->next_temp = original->next_temp; 38295f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->num_address_regs = original->num_address_regs; 38305f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->samplers_used = prog->SamplersUsed = original->samplers_used; 38315f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->indirect_addr_temps = original->indirect_addr_temps; 38325f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->indirect_addr_consts = original->indirect_addr_consts; 38333354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3834fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul v->num_immediates = original->num_immediates; 38355f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38365f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */ 38375f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 38385f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0 = v->get_temp(glsl_type::vec4_type); 38395f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain dst0 = st_dst_reg(src0); 38405f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 38415f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst->sampler = samplerIndex; 38425f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst->tex_target = TEXTURE_2D_INDEX; 38435f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 3844dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= FRAG_BIT_TEX0; 38455f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->SamplersUsed |= (1 << samplerIndex); /* mark sampler as used */ 38465f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain v->samplers_used |= (1 << samplerIndex); 38475f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38485f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ 38495f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0.negate = NEGATE_XYZW; 38505f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM) 38515f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src0.swizzle = SWIZZLE_XXXX; 38525f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain inst = v->emit(NULL, TGSI_OPCODE_KIL, undef_dst, src0); 38535f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38545f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 38555f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain * new visitor. */ 38565f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain foreach_iter(exec_list_iterator, iter, original->instructions) { 38575f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 38583788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie glsl_to_tgsi_instruction *newinst; 38595f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain st_src_reg src_regs[3]; 38605f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38615f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (inst->dst.file == PROGRAM_OUTPUT) 38625f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 38635f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38645f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain for (int i=0; i<3; i++) { 38655f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain src_regs[i] = inst->src[i]; 38665f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain if (src_regs[i].file == PROGRAM_INPUT) 3867dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 38685f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain } 38695f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38703788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 38713788b4b5c942b2346bf122486b687c632ab7eac4Dave Airlie newinst->tex_target = inst->tex_target; 38725f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain } 38735f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 38745f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain /* Make modifications to fragment program info. */ 38755f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain prog->Parameters = _mesa_clone_parameter_list(original->prog->Parameters); 38765f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain count_resources(v, prog); 38775f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain fp->glsl_to_tgsi = v; 38785f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain} 38795f0b4b0e9d376f9ec1cb5ae08c36052f4f51ac37Bryan Cain 3880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ------------------------- TGSI conversion stuff -------------------------- */ 3881f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct label { 3882f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned branch_target; 3883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned token; 3884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3885f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Intermediate state used during shader translation. 3888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct st_translate { 3890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg; 3891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 389233e0c47b05c8fbae9d7af57ba65b612825b5db60Bryan Cain struct ureg_dst temps[MAX_TEMPS]; 3893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src *constants; 38947732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain struct ureg_src *immediates; 3895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; 3896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; 3897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst address[1]; 3898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src samplers[PIPE_MAX_SAMPLERS]; 3899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src systemValues[SYSTEM_VALUE_MAX]; 3900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *inputMapping; 3902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint *outputMapping; 3903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* For every instruction that contains a label (eg CALL), keep 3905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * details so that we can go back afterwards and emit the correct 3906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * tgsi instruction number for each label. 3907f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3908f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct label *labels; 3909f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_size; 3910f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned labels_count; 3911f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3912f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Keep a record of the tgsi instruction number that each mesa 3913f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * instruction starts at, will be used to fix up labels after 3914f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * translation. 3915f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3916f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned *insn; 3917f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_size; 3918f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned insn_count; 3919f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3920f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ 3921f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3922f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean error; 3923f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3924f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ 3926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { 3927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_FACE, 3928da1544b39ebdf9b24414dcee214a5ccf76e74a77Christoph Bumiller TGSI_SEMANTIC_VERTEXID, 3929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain TGSI_SEMANTIC_INSTANCEID 3930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain}; 3931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3933f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Make note of a branch to a label in the TGSI code. 3934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * After we've emitted all instructions, we'll go over the list 3935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * of labels built here and patch the TGSI code with the actual 3936f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * location of each label. 3937f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3938a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainstatic unsigned *get_label(struct st_translate *t, unsigned branch_target) 3939f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3940f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 3941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels_count + 1 >= t->labels_size) { 3943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); 3944f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels = (struct label *)realloc(t->labels, 3945a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->labels_size * sizeof(struct label)); 3946f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->labels == NULL) { 3947f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static unsigned dummy; 3948f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3949f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &dummy; 3950f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3951f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3952f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i = t->labels_count++; 3954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->labels[i].branch_target = branch_target; 3955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return &t->labels[i].token; 3956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 3959f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Called prior to emitting the TGSI code for each instruction. 3960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Allocate additional space for instructions if needed. 3961f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Update the insn[] array so the next glsl_to_tgsi_instruction points to 3962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * the next TGSI instruction. 3963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 3964a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainstatic void set_insn_start(struct st_translate *t, unsigned start) 3965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 3966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn_count + 1 >= t->insn_size) { 3967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); 3968a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->insn = (unsigned *)realloc(t->insn, t->insn_size * sizeof(t->insn[0])); 3969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->insn == NULL) { 3970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->error = TRUE; 3971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 3972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 3974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->insn[t->insn_count++] = start; 3976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 3977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 3978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 39797732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * Map a glsl_to_tgsi constant/immediate to a TGSI immediate. 39807732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 39817732822c833ee22e259af3f8bd2bfb57c986612eBryan Cainstatic struct ureg_src 3982a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainemit_immediate(struct st_translate *t, 39833354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain gl_constant_value values[4], 39843354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain int type, int size) 39857732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain{ 39867732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain struct ureg_program *ureg = t->ureg; 39877732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 39883354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain switch(type) 39897732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain { 39907732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_FLOAT: 39913354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate(ureg, &values[0].f, size); 39927732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_INT: 39933354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate_int(ureg, &values[0].i, size); 39947732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_UNSIGNED_INT: 39957732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case GL_BOOL: 39963354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain return ureg_DECL_immediate_uint(ureg, &values[0].u, size); 39977732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain default: 39987732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain assert(!"should not get here - type must be float, int, uint, or bool"); 39997732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain return ureg_src_undef(); 40007732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 40017732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain} 40027732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 40037732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain/** 4004f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register. 4005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 4007a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caindst_register(struct st_translate *t, 4008a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain gl_register_file file, 4009a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GLuint index) 4010f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4011a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(file) { 4012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 4013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 4014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 4016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 401749468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[index] = ureg_DECL_local_temporary(t->ureg); 4018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->temps[index]; 4020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 4022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->procType == TGSI_PROCESSOR_VERTEX) 4023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < VERT_RESULT_MAX); 4024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (t->procType == TGSI_PROCESSOR_FRAGMENT) 4025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < FRAG_RESULT_MAX); 4026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index < GEOM_RESULT_MAX); 4028f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4029f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 4030f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4031f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->outputs[t->outputMapping[index]]; 4032f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4033f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 4034f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->address[index]; 4035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4037a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"unknown dst register file"); 4038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_dst_undef(); 4039f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4043f751730ad003bb19ce85bc4d0abddaf40edde6c1Bryan Cain * Map a glsl_to_tgsi src register to a TGSI ureg_src register. 4044f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4045f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 4046a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cainsrc_register(struct st_translate *t, 4047a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain gl_register_file file, 40488cc1860d4a55c93ce12a649c281012b37212ffbdNiels Ole Salscheider GLint index) 4049f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4050a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(file) { 4051f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNDEFINED: 4052f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 4053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_TEMPORARY: 4055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 4056a8ed00d5f13d7b016bc2ea56f130adc3fa857cc8Brian Paul assert(index < (int) Elements(t->temps)); 4057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ureg_dst_is_undef(t->temps[index])) 405849468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[index] = ureg_DECL_local_temporary(t->ureg); 4059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->temps[index]); 4060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 4062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 4063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 4064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 4065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(index >= 0); 4066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 4067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 4068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: /* ie, immediate */ 4069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (index < 0) 4070a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain return ureg_DECL_constant(t->ureg, 0); 4071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->constants[index]; 4073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 40747732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain case PROGRAM_IMMEDIATE: 40757732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain return t->immediates[index]; 40767732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 4077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_INPUT: 4078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->inputMapping[index] < Elements(t->inputs)); 4079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->inputs[t->inputMapping[index]]; 4080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_OUTPUT: 4082f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(t->outputMapping[index] < Elements(t->outputs)); 4083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ 4084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4085f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ADDRESS: 4086f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src(t->address[index]); 4087f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4088f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_SYSTEM_VALUE: 4089a8ed00d5f13d7b016bc2ea56f130adc3fa857cc8Brian Paul assert(index < (int) Elements(t->systemValues)); 4090f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return t->systemValues[index]; 4091f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4092f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4093a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"unknown src register file"); 4094f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ureg_src_undef(); 4095f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4096f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 409956dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_dst register from an st_dst_reg. 4100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_dst 4102a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caintranslate_dst(struct st_translate *t, 4103a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain const st_dst_reg *dst_reg, 4104bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák bool saturate, bool clamp_color) 4105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4106a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain struct ureg_dst dst = dst_register(t, 4107a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst_reg->file, 4108a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst_reg->index); 4109f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4110a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_writemask(dst, dst_reg->writemask); 4111f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4112f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (saturate) 4113a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_saturate(dst); 4114bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák else if (clamp_color && dst_reg->file == PROGRAM_OUTPUT) { 4115bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák /* Clamp colors for ARB_color_buffer_float. */ 4116bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák switch (t->procType) { 4117bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák case TGSI_PROCESSOR_VERTEX: 4118bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák /* XXX if the geometry shader is present, this must be done there 4119bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák * instead of here. */ 4120bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák if (dst_reg->index == VERT_RESULT_COL0 || 4121bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_COL1 || 4122bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_BFC0 || 4123bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst_reg->index == VERT_RESULT_BFC1) { 4124bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst = ureg_saturate(dst); 4125bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4126bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák break; 4127bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák 4128bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák case TGSI_PROCESSOR_FRAGMENT: 4129bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák if (dst_reg->index >= FRAG_RESULT_COLOR) { 4130bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák dst = ureg_saturate(dst); 4131bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4132bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák break; 4133bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4134bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák } 4135f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4136f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (dst_reg->reladdr != NULL) 4137a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst = ureg_dst_indirect(dst, ureg_src(t->address[0])); 4138f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4139f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return dst; 4140f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4141f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4142f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 414356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * Create a TGSI ureg_src register from an st_src_reg. 4144f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4145f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct ureg_src 4146a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caintranslate_src(struct st_translate *t, const st_src_reg *src_reg) 4147f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4148a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain struct ureg_src src = src_register(t, src_reg->file, src_reg->index); 4149f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4150a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src = ureg_swizzle(src, 4151a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 0) & 0x3, 4152a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 1) & 0x3, 4153a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 2) & 0x3, 4154a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain GET_SWZ(src_reg->swizzle, 3) & 0x3); 4155f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4156f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if ((src_reg->negate & 0xf) == NEGATE_XYZW) 4157f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src = ureg_negate(src); 4158f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4159f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->reladdr != NULL) { 4160f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Normally ureg_src_indirect() would be used here, but a stupid compiler 4161f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * bug in g++ makes ureg_src_indirect (an inline C function) erroneously 4162f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * set the bit for src.Negate. So we have to do the operation manually 4163f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * here to work around the compiler's problems. */ 4164f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/ 4165f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src addr = ureg_src(t->address[0]); 4166f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Indirect = 1; 4167f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectFile = addr.File; 4168f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectIndex = addr.Index; 4169f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.IndirectSwizzle = addr.SwizzleX; 4170f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4171f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (src_reg->file != PROGRAM_INPUT && 4172f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src_reg->file != PROGRAM_OUTPUT) { 4173f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If src_reg->index was negative, it was set to zero in 4174f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * src_register(). Reassign it now. But don't do this 4175f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * for input/output regs since they get remapped while 4176f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * const buffers don't. 4177f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4178f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src.Index = src_reg->index; 4179f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4180f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4181f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4182f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return src; 4183f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4184f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 41852083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airliestatic struct tgsi_texture_offset 41862083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlietranslate_tex_offset(struct st_translate *t, 41872083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie const struct tgsi_texture_offset *in_offset) 41882083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie{ 41892083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie struct tgsi_texture_offset offset; 41902083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 41912083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie assert(in_offset->File == PROGRAM_IMMEDIATE); 41922083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 41932083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.File = TGSI_FILE_IMMEDIATE; 41942083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.Index = in_offset->Index; 41952083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleX = in_offset->SwizzleX; 41962083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleY = in_offset->SwizzleY; 41972083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie offset.SwizzleZ = in_offset->SwizzleZ; 419834665381713249c29b7da5028396222dfea477c2Vinson Lee offset.Padding = 0; 41992083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 42002083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie return offset; 42012083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie} 42022083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 4203f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 4204a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Caincompile_tgsi_instruction(struct st_translate *t, 4205bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák const glsl_to_tgsi_instruction *inst, 4206bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák bool clamp_dst_color_output) 4207f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4208f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 4209f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint i; 4210f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_dst dst[1]; 4211f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src src[4]; 42122083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET]; 42132083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie 4214f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_dst; 4215f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned num_src; 4216f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4217a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain num_dst = num_inst_dst_regs(inst->op); 4218a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain num_src = num_inst_src_regs(inst->op); 4219f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4220f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (num_dst) 4221a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst[0] = translate_dst(t, 4222a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain &inst->dst, 4223bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák inst->saturate, 4224bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák clamp_dst_color_output); 4225f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4226f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < num_src; i++) 4227a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src[i] = translate_src(t, &inst->src[i]); 4228f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4229a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain switch(inst->op) { 423056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_BGNLOOP: 423156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_CAL: 423256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ELSE: 423356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_ENDLOOP: 423456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_IF: 4235a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(num_dst == 0); 4236a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_label_insn(ureg, 4237a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4238a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src, 4239a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain get_label(t, 4240a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0)); 4241f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 4242f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 424356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TEX: 424456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXB: 424556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXD: 424656dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXL: 424756dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_TXP: 4248515d9e88801e2e1e2a7ac74ccd43f8fedfb80a96Dave Airlie case TGSI_OPCODE_TXQ: 42495f3de17ef0f8b6280a6bf331ea6686a260f0d0d4Dave Airlie case TGSI_OPCODE_TXF: 4250f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain src[num_src++] = t->samplers[inst->sampler]; 42512083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie for (i = 0; i < inst->tex_offset_num_offset; i++) { 42522083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]); 42532083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie } 4254a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_tex_insn(ureg, 4255a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4256a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst, num_dst, 42573f80b69b5f2093ffc624bb901ce34f0e289bc25dDave Airlie st_translate_texture_target(inst->tex_target, inst->tex_shadow), 42582083a276eb270b748d1c2668eb9faa5aadc8e700Dave Airlie texoffsets, inst->tex_offset_num_offset, 4259a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src); 4260f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return; 4261f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 426256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain case TGSI_OPCODE_SCS: 4263a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY); 4264a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_insn(ureg, inst->op, dst, num_dst, src, num_src); 4265f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4266f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4267f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4268a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_insn(ureg, 4269a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain inst->op, 4270a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain dst, num_dst, 4271a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain src, num_src); 4272f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4273f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4274f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4275f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4276f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 427735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * Emit the TGSI instructions for inverting and adjusting WPOS. 4278f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * This code is unavoidable because it also depends on whether 4279f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). 4280f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4281f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 428235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonsecaemit_wpos_adjustment( struct st_translate *t, 428335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca const struct gl_program *program, 428435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca boolean invert, 428535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjX, GLfloat adjY[2]) 4286f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4287f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg = t->ureg; 4288f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4289f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment program uses fragment position input. 4290f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Need to replace instances of INPUT[WPOS] with temp T 4291f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * where T = INPUT[WPOS] by y is inverted. 4292f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4293f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain static const gl_state_index wposTransformState[STATE_LENGTH] 4294f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 4295f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; 4296f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4297f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX: note we are modifying the incoming shader here! Need to 4298f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * do this before emitting the constant decls below, or this 4299f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * will be missed: 4300f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4301f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, 4302f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain wposTransformState); 4303f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 430435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); 430535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); 4306f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 4307f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 430835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* First, apply the coordinate shift: */ 430935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (adjX || adjY[0] || adjY[1]) { 431035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (adjY[0] != adjY[1]) { 431135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Adjust the y coordinate by adjY[1] or adjY[0] respectively 431235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * depending on whether inversion is actually going to be applied 431335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * or not, which is determined by testing against the inversion 431435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * state variable used below, which will be either +1 or -1. 431535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 431649468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg); 431735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca 431835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_CMP(ureg, adj_temp, 431935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, invert ? 2 : 0), 432035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f), 432135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f)); 432235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp)); 432335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } else { 432435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_ADD(ureg, wpos_temp, wpos_input, 432535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f)); 432635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 432735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input = ureg_src(wpos_temp); 432835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } else { 432935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* MOV wpos_temp, input[wpos] 433035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 433135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MOV( ureg, wpos_temp, wpos_input ); 4332f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4333f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 433435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be 433535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion/identity, or the other way around if we're drawing to an FBO. 433635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 4337f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (invert) { 4338f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy 4339f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 434035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MAD( ureg, 434135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 434235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input, 434335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 0), 434435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 1)); 4345f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } else { 4346f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww 4347f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 434835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_MAD( ureg, 434935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 435035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca wpos_input, 435135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 2), 435235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca ureg_scalar(wpostrans, 3)); 4353f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4354f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4355f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Use wpos_temp as position input from here on: 4356f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4357f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 4358f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4359f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4360f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4361f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4362f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Emit fragment position/ooordinate code. 4363f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4364f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic void 4365f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainemit_wpos(struct st_context *st, 4366f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_translate *t, 4367f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *program, 4368f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg) 4369f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4370f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_fragment_program *fp = 4371f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain (const struct gl_fragment_program *) program; 4372f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct pipe_screen *pscreen = st->pipe->screen; 437335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjX = 0.0f; 437435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca GLfloat adjY[2] = { 0.0f, 0.0f }; 4375f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain boolean invert = FALSE; 4376f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 437735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca /* Query the pixel center conventions supported by the pipe driver and set 437835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * adjX, adjY to help out if it cannot handle the requested one internally. 437935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 438035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * The bias of the y-coordinate depends on whether y-inversion takes place 438135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are 438235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * drawing to an FBO (causes additional inversion), and whether the the pipe 438335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * driver origin and the requested origin differ (the latter condition is 438435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * stored in the 'invert' variable). 438535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 438635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * For height = 100 (i = integer, h = half-integer, l = lower, u = upper): 438735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 438835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * center shift only: 438935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * i -> h: +0.5 439035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * h -> i: -0.5 439135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 439235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion only: 439335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99 439435ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5 439535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0 439635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5 439735ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * 439835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * inversion and center shift: 439935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5 440035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99 440135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5 440235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 440335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca */ 4404f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->OriginUpperLeft) { 4405f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in upper-left */ 4406f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { 4407f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin */ 4408f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4409f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { 4410f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin, need to invert Y */ 4411f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4412f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 4413f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4414f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4415f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4416f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4417f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4418f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants origin in lower-left */ 4419f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) 4420f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports lower-left origin */ 4421f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4422f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) 4423f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports upper-left origin, need to invert Y */ 4424f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain invert = TRUE; 4425f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4426f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4427f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4428f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4429f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (fp->PixelCenterInteger) { 4430f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center integer */ 443135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4432f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer */ 443335ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[1] = 1.0f; 4434f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 443535ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 443635ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4437f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer, need to bias X,Y */ 443835ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjX = -0.5f; 443935ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[0] = -0.5f; 444035ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjY[1] = 0.5f; 444135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca } 4442f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4443f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4444f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4445f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4446f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fragment shader wants pixel center half integer */ 4447f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4448f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center half integer */ 4449f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4450f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4451f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* the driver supports pixel center integer, need to bias X,Y */ 445235ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca adjX = adjY[0] = adjY[1] = 0.5f; 4453f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 4454f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4455f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 4456f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(0); 4457f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4458f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4459f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* we invert after adjustment so that we avoid the MOV to temporary, 4460f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * and reuse the adjustment ADD instead */ 446135ffe94a340cf4e0ebe810a1d576113f96ea9deeJosé Fonseca emit_wpos_adjustment(t, program, invert, adjX, adjY); 4462f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4463f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4464f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 4465bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. 4466bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * TGSI uses +1 for front, -1 for back. 4467bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * This function converts the TGSI value to the GL value. Simply clamping/ 4468bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain * saturating the value to [0,1] does the job. 4469bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain */ 4470bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 4471bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_face_var(struct st_translate *t) 4472bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 4473bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 4474bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst face_temp = ureg_DECL_temporary(ureg); 4475bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; 4476bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4477bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* MOV_SAT face_temp, input[face] */ 4478bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain face_temp = ureg_saturate(face_temp); 4479bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, face_temp, face_input); 4480bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4481bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain /* Use face_temp as face input from here on: */ 4482bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); 4483bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4484bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4485bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainstatic void 4486bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cainemit_edgeflags(struct st_translate *t) 4487bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain{ 4488bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_program *ureg = t->ureg; 4489bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; 4490bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; 4491bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4492bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain ureg_MOV(ureg, edge_dst, edge_src); 4493bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain} 4494bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain 4495bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain/** 4496f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format. 4497f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param program the program to translate 4498f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numInputs number of input registers used 4499f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputMapping maps Mesa fragment program inputs to TGSI generic 4500f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * input indexes 4501f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticName the TGSI_SEMANTIC flag for each input 4502f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param inputSemanticIndex the semantic index (ex: which texcoord) for 4503f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each input 4504f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input 4505f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param numOutputs number of output registers used 4506f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputMapping maps Mesa fragment program outputs to TGSI 4507f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * generic outputs 4508f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticName the TGSI_SEMANTIC flag for each output 4509f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \param outputSemanticIndex the semantic index (ex: which texcoord) for 4510f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * each output 4511f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * 4512f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY 4513f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4514f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" enum pipe_error 4515f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_translate_program( 4516f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_context *ctx, 4517f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain uint procType, 4518f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct ureg_program *ureg, 4519f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_visitor *program, 4520f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_program *proginfo, 4521f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numInputs, 4522f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint inputMapping[], 4523f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticName[], 4524f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte inputSemanticIndex[], 4525f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint interpMode[], 4526f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák const GLboolean is_centroid[], 4527f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLuint numOutputs, 4528f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const GLuint outputMapping[], 4529f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticName[], 4530f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const ubyte outputSemanticIndex[], 4531bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák boolean passthrough_edgeflags, 4532bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák boolean clamp_color) 4533f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4534794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca struct st_translate *t; 4535f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned i; 4536f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain enum pipe_error ret = PIPE_OK; 4537f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4538f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numInputs <= Elements(t->inputs)); 4539f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(numOutputs <= Elements(t->outputs)); 4540f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4541794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca t = CALLOC_STRUCT(st_translate); 4542794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (!t) { 4543794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca ret = PIPE_ERROR_OUT_OF_MEMORY; 4544794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca goto out; 4545794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 4546794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 4547f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain memset(t, 0, sizeof *t); 4548f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4549f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->procType = procType; 4550f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputMapping = inputMapping; 4551f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->outputMapping = outputMapping; 4552f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->ureg = ureg; 4553f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4554d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program) { 4555d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) { 4556d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin struct gl_uniform_storage *const storage = 4557d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin &program->shader_program->UniformStorage[i]; 4558d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4559d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin _mesa_uniform_detach_all_driver_storage(storage); 4560d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4561d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4562d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4563f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4564f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare input attributes. 4565f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4566f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (procType == TGSI_PROCESSOR_FRAGMENT) { 4567f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4568f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg, 4569f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák inputSemanticName[i], 4570f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák inputSemanticIndex[i], 4571f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák interpMode[i], 0, 4572f40b5723f017bfb9e3819a5463184627ee727cc1Marek Olšák is_centroid[i]); 4573f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4574f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4575f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->InputsRead & FRAG_BIT_WPOS) { 4576f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Must do this after setting up t->inputs, and before 4577f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * emitting constant references, below: 4578f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4579f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain emit_wpos(st_context(ctx), t, proginfo, ureg); 4580f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4581f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4582bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (proginfo->InputsRead & FRAG_BIT_FACE) 4583bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_face_var(t); 4584f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4585f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* 4586f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Declare output attributes. 4587f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4588f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4589f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (outputSemanticName[i]) { 4590f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_POSITION: 4591a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4592a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_POSITION, /* Z/Depth */ 4593a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4594a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Z); 4595f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4596f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_STENCIL: 4597a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4598a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_STENCIL, /* Stencil */ 4599a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4600a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Y); 4601f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4602f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case TGSI_SEMANTIC_COLOR: 4603a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4604a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain TGSI_SEMANTIC_COLOR, 4605a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4606f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4607f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4608a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR"); 4609794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca ret = PIPE_ERROR_BAD_INPUT; 4610794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca goto out; 4611f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4612f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4613f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4614f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else if (procType == TGSI_PROCESSOR_GEOMETRY) { 4615f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4616f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_gs_input(ureg, 4617f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain i, 4618f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticName[i], 4619f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain inputSemanticIndex[i]); 4620f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4621f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4622f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 4623a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->outputs[i] = ureg_DECL_output(ureg, 4624a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticName[i], 4625a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain outputSemanticIndex[i]); 4626f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4627f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4628f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else { 4629f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(procType == TGSI_PROCESSOR_VERTEX); 4630f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4631f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numInputs; i++) { 4632f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->inputs[i] = ureg_DECL_vs_input(ureg, i); 4633f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4634f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4635f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < numOutputs; i++) { 46367e63b613a5a067462c450338e0bdce5b5976f6f1Marcin Slusarz t->outputs[i] = ureg_DECL_output(ureg, 46377e63b613a5a067462c450338e0bdce5b5976f6f1Marcin Slusarz outputSemanticName[i], 46387e63b613a5a067462c450338e0bdce5b5976f6f1Marcin Slusarz outputSemanticIndex[i]); 4639f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4640bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain if (passthrough_edgeflags) 4641bf1cee9f24022e3da96d84fdc6baaa050d3eadf1Bryan Cain emit_edgeflags(t); 4642f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4643f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4644f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare address register. 4645f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4646f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->num_address_regs > 0) { 4647a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain assert(program->num_address_regs == 1); 4648a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->address[0] = ureg_DECL_address(ureg); 4649f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4650f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4651f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Declare misc input registers 4652f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4653f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain { 4654f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLbitfield sysInputs = proginfo->SystemValuesRead; 4655f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned numSys = 0; 4656f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; sysInputs; i++) { 4657f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (sysInputs & (1 << i)) { 4658f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain unsigned semName = mesa_sysval_to_semantic[i]; 4659f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); 4660b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca if (semName == TGSI_SEMANTIC_INSTANCEID || 4661b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca semName == TGSI_SEMANTIC_VERTEXID) { 4662b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca /* From Gallium perspective, these system values are always 4663b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca * integer, and require native integer support. However, if 4664b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca * native integer is supported on the vertex stage but not the 4665b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca * pixel stage (e.g, i915g + draw), Mesa will generate IR that 4666b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca * assumes these system values are floats. To resolve the 4667b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca * inconsistency, we insert a U2F. 4668b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca */ 4669b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca struct st_context *st = st_context(ctx); 4670b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca struct pipe_screen *pscreen = st->pipe->screen; 4671b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca assert(procType == TGSI_PROCESSOR_VERTEX); 4672b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS)); 4673b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca if (!ctx->Const.NativeIntegers) { 4674b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg); 4675b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]); 4676b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca t->systemValues[i] = ureg_scalar(ureg_src(temp), 0); 4677b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca } 4678b3ba0a7afa6311e12852fb1373452e480f89ea96José Fonseca } 4679f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain numSys++; 4680f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain sysInputs &= ~(1 << i); 4681f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4682f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4683f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4684f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4685f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_temps) { 4686f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If temps are accessed with indirect addressing, declare temporaries 4687f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * in sequential order. Else, we declare them on demand elsewhere. 4688f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * (Note: the number of temporaries is equal to program->next_temp) 4689f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4690f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < (unsigned)program->next_temp; i++) { 4691f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ 469249468a1b2a241d5a6a1155f79b48fa6562524206Francisco Jerez t->temps[i] = ureg_DECL_local_temporary(t->ureg); 4693f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4694f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4695f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 46967732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit constants and uniforms. TGSI uses a single index space for these, 46977732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * so we put all the translated regs in t->constants. 4698f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4699f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (proginfo->Parameters) { 4700a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants = (struct ureg_src *)CALLOC(proginfo->Parameters->NumParameters * sizeof(t->constants[0])); 4701f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (t->constants == NULL) { 4702f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain ret = PIPE_ERROR_OUT_OF_MEMORY; 4703f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain goto out; 4704f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4705f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4706f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < proginfo->Parameters->NumParameters; i++) { 4707f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (proginfo->Parameters->Parameters[i].Type) { 4708f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_ENV_PARAM: 4709f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_LOCAL_PARAM: 4710f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_STATE_VAR: 4711f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_NAMED_PARAM: 4712f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_UNIFORM: 4713a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants[i] = ureg_DECL_constant(ureg, i); 4714f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4715f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 47167732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect 47177732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * addressing of the const buffer. 47187732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * FIXME: Be smarter and recognize param arrays: 47197732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * indirect addressing is only valid within the referenced 47207732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain * array. 47217732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 4722f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case PROGRAM_CONSTANT: 4723f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (program->indirect_addr_consts) 4724a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->constants[i] = ureg_DECL_constant(ureg, i); 4725f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain else 47263354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->constants[i] = emit_immediate(t, 47273354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain proginfo->Parameters->ParameterValues[i], 47283354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain proginfo->Parameters->Parameters[i].DataType, 47293354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain 4); 4730f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4731f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4732f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4733f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4734f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4735f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 47367732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain 47377732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain /* Emit immediate values. 47387732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain */ 47393354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->immediates = (struct ureg_src *)CALLOC(program->num_immediates * sizeof(struct ureg_src)); 47407732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain if (t->immediates == NULL) { 47417732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain ret = PIPE_ERROR_OUT_OF_MEMORY; 47427732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain goto out; 47437732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 47443354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain i = 0; 47453354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain foreach_iter(exec_list_iterator, iter, program->immediates) { 47463354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain immediate_storage *imm = (immediate_storage *)iter.get(); 4747fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul assert(i < program->num_immediates); 47483354a5b56398f90fc36ab14b6444aae27b50e859Bryan Cain t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); 47497732822c833ee22e259af3f8bd2bfb57c986612eBryan Cain } 4750fdae0eaf222f271bfbc7e71d8561eb8b90685ae5Brian Paul assert(i == program->num_immediates); 4751f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4752f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* texture samplers */ 4753f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 475444867da3543ca54ef245695cef72a6e305451d93Bryan Cain if (program->samplers_used & (1 << i)) { 4755a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->samplers[i] = ureg_DECL_sampler(ureg, i); 4756f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4757f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4758f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4759f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Emit each instruction in turn: 4760f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4761f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, program->instructions) { 4762a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain set_insn_start(t, ureg_get_instruction_number(ureg)); 4763bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(), 4764bc1c8369384b5e16547c5bf9728aa78f8dfd66ccMarek Olšák clamp_color); 4765f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4766f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4767f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Fix up all emitted labels: 4768f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4769f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i = 0; i < t->labels_count; i++) { 4770a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain ureg_fixup_label(ureg, t->labels[i].token, 4771a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain t->insn[t->labels[i].branch_target]); 4772f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4773f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4774d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program) { 4775d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin /* This has to be done last. Any operation the can cause 4776d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin * prog->ParameterValues to get reallocated (e.g., anything that adds a 4777d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin * program constant) has to happen before creating this linkage. 4778d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin */ 4779d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4780d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin if (program->shader_program->_LinkedShaders[i] == NULL) 4781d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin continue; 4782d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4783d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin _mesa_associate_uniform_storage(ctx, program->shader_program, 4784d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin program->shader_program->_LinkedShaders[i]->Program->Parameters); 4785d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4786d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin } 4787d4bf5cefb0943a196c603360187493e270a66442Vadim Girlin 4788f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainout: 4789794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (t) { 4790794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->insn); 4791794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->labels); 4792794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->constants); 4793794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t->immediates); 4794794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca 4795794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca if (t->error) { 4796794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca debug_printf("%s: translate error flag set\n", __FUNCTION__); 4797794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca } 4798f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4799794c5158b0a0b2978ebae6fdc2747e6febcd42c1José Fonseca FREE(t); 4800f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4801f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4802f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return ret; 4803f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4804f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/* ----------------------------- End TGSI code ------------------------------ */ 4805f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4806f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 480744867da3543ca54ef245695cef72a6e305451d93Bryan Cain * Convert a shader's GLSL IR into a Mesa gl_program, although without 480844867da3543ca54ef245695cef72a6e305451d93Bryan Cain * generating Mesa IR. 4809f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 4810f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstatic struct gl_program * 4811f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainget_mesa_program(struct gl_context *ctx, 4812f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shader_program, 48137e63b613a5a067462c450338e0bdce5b5976f6f1Marcin Slusarz struct gl_shader *shader) 4814f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 48157d65356d8a4d268dce4c933d7704d709e1cdacfaVinson Lee glsl_to_tgsi_visitor* v; 4816f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *prog; 4817f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain GLenum target; 4818f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const char *target_string; 4819a2c3b9f38d81f363bd62abc87dc3abef2beeba95Bryan Cain bool progress; 4820f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_compiler_options *options = 4821f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 4822f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4823f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4824f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4825f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_VERTEX_PROGRAM_ARB; 4826f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "vertex"; 4827f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4828f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4829f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_FRAGMENT_PROGRAM_ARB; 4830f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "fragment"; 4831f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4832f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4833f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target = GL_GEOMETRY_PROGRAM_NV; 4834f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain target_string = "geometry"; 4835f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4836f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4837f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4838f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4839f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4840f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4841f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(shader->ir); 4842f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4843f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 4844f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!prog) 4845f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4846f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain prog->Parameters = _mesa_new_parameter_list(); 48477d65356d8a4d268dce4c933d7704d709e1cdacfaVinson Lee v = new glsl_to_tgsi_visitor(); 4848f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->ctx = ctx; 4849f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->prog = prog; 4850f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->shader_program = shader_program; 4851f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->options = options; 4852b191382c60bdcfeb7f424b23aa6ab63de81e2f08Bryan Cain v->glsl_version = ctx->Const.GLSLVersion; 485301d81dedc795005ed235856ce762bb1981655716Kenneth Graunke v->native_integers = ctx->Const.NativeIntegers; 4854f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 485558a7461e1672935e7d30780a4dd40c00abbc28a5Ian Romanick _mesa_generate_parameters_list_for_uniforms(shader_program, shader, 485658a7461e1672935e7d30780a4dd40c00abbc28a5Ian Romanick prog->Parameters); 4857f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 485804e324008759282728a95a1394bac2c4c2a1a3f9Marek Olšák /* Remove reads from output registers. */ 485904e324008759282728a95a1394bac2c4c2a1a3f9Marek Olšák lower_output_reads(shader->ir); 486010937e651222501c0e9f4f44e6b842c261e2edfbVincent Lejeune 486156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Emit intermediate IR for main(). */ 4862f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(shader->ir, v); 4863f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4864f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Now emit bodies for any functions that were used. */ 4865f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 4866f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_FALSE; 4867f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4868f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain foreach_iter(exec_list_iterator, iter, v->function_signatures) { 4869f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain function_entry *entry = (function_entry *)iter.get(); 4870f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4871f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (!entry->bgn_inst) { 4872f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain v->current_function = entry; 4873f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 487456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB); 4875f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain entry->bgn_inst->function = entry; 4876f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4877f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain visit_exec_list(&entry->sig->body, v); 4878f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4879f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *last; 4880f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain last = (glsl_to_tgsi_instruction *)v->instructions.get_tail(); 488156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain if (last->op != TGSI_OPCODE_RET) 488256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_RET); 4883f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4884f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain glsl_to_tgsi_instruction *end; 488556dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain end = v->emit(NULL, TGSI_OPCODE_ENDSUB); 4886f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain end->function = entry; 4887f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4888f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = GL_TRUE; 4889f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4890f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4891f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 4892f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4893f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#if 0 4894f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Print out some information (for debugging purposes) used by the 4895f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * optimization passes. */ 4896f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (i=0; i < v->next_temp; i++) { 4897f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fr = v->get_first_temp_read(i); 4898f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int fw = v->get_first_temp_write(i); 4899f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lr = v->get_last_temp_read(i); 4900f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain int lw = v->get_last_temp_write(i); 4901f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4902f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw); 4903f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(fw <= fr); 4904f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4905f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain#endif 4906f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 49079c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */ 490829d21417e38aed0f0710d3692df320728aef90b1Bryan Cain v->simplify_cmp(); 49099c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain v->copy_propagate(); 49109c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain while (v->eliminate_dead_code_advanced()); 4911c341d3cfd0ddbabf6274212b7f0da1a25854a673Bryan Cain 49129c2810103d107d1e5ef8bd8b57819d12264f664aBryan Cain /* FIXME: These passes to optimize temporary registers don't work when there 491316d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * is indirect addressing of the temporary register space. We need proper 491416d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * array support so that we don't have to give up these passes in every 491516d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain * shader that uses arrays. 491616d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain */ 491716d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain if (!v->indirect_addr_temps) { 491816d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->eliminate_dead_code(); 49198c50f18b29637470539d05ccc32b0cae0092aeacEmil Velikov v->merge_registers(); 492016d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain v->renumber_registers(); 492116d7a717d592524e4d62fec4173cb9523f7a1453Bryan Cain } 492256dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain 492356dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain /* Write the END instruction. */ 492456dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain v->emit(NULL, TGSI_OPCODE_END); 4925f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4926f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (ctx->Shader.Flags & GLSL_DUMP) { 4927f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4928f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("GLSL IR for linked %s program %d:\n", target_string, 4929f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader_program->Name); 4930f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_print_ir(shader->ir, NULL); 4931f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 4932f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain printf("\n"); 49338f9fc8b9d208cf601d126721709315aa3c1c2024José Fonseca fflush(stdout); 4934f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4935f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 493644867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->Instructions = NULL; 493744867da3543ca54ef245695cef72a6e305451d93Bryan Cain prog->NumInstructions = 0; 4938f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4939cf45949d6a896651a5f3864d3b195e26d59eee74Paul Berry do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); 49405768ed6429937940bd48f5de4f8383273952880aBryan Cain count_resources(v, prog); 4941f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4942f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &shader->Program, prog); 4943f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4944719909698c67c287a393d2380278e7b7495ae018Ian Romanick /* This has to be done last. Any operation the can cause 4945719909698c67c287a393d2380278e7b7495ae018Ian Romanick * prog->ParameterValues to get reallocated (e.g., anything that adds a 4946719909698c67c287a393d2380278e7b7495ae018Ian Romanick * program constant) has to happen before creating this linkage. 4947719909698c67c287a393d2380278e7b7495ae018Ian Romanick */ 4948719909698c67c287a393d2380278e7b7495ae018Ian Romanick _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters); 4949719909698c67c287a393d2380278e7b7495ae018Ian Romanick if (!shader_program->LinkStatus) { 4950719909698c67c287a393d2380278e7b7495ae018Ian Romanick return NULL; 4951719909698c67c287a393d2380278e7b7495ae018Ian Romanick } 4952719909698c67c287a393d2380278e7b7495ae018Ian Romanick 4953f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_vertex_program *stvp; 4954f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_fragment_program *stfp; 4955f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct st_geometry_program *stgp; 4956f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4957f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain switch (shader->Type) { 4958f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_VERTEX_SHADER: 4959f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp = (struct st_vertex_program *)prog; 4960f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stvp->glsl_to_tgsi = v; 4961f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4962f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_FRAGMENT_SHADER: 4963f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp = (struct st_fragment_program *)prog; 4964f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stfp->glsl_to_tgsi = v; 4965f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4966f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain case GL_GEOMETRY_SHADER: 4967f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp = (struct st_geometry_program *)prog; 4968f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain stgp->glsl_to_tgsi = v; 4969f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain break; 4970f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain default: 4971f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(!"should not be reached"); 4972f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return NULL; 4973f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4974f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4975f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return prog; 4976f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4977f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4978f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainextern "C" { 4979f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4980f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader * 4981f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 4982f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4983f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader *shader; 4984f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || 4985f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain type == GL_GEOMETRY_SHADER_ARB); 4986f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader = rzalloc(NULL, struct gl_shader); 4987f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shader) { 4988f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Type = type; 4989f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shader->Name = name; 4990f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader(ctx, shader); 4991f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 4992f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shader; 4993f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 4994f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 4995f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainstruct gl_shader_program * 4996f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_new_shader_program(struct gl_context *ctx, GLuint name) 4997f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 4998f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_shader_program *shProg; 4999f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg = rzalloc(NULL, struct gl_shader_program); 5000f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (shProg) { 5001f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain shProg->Name = name; 5002f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_init_shader_program(ctx, shProg); 5003f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5004f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return shProg; 5005f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 5006f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5007f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain/** 5008f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Link a shader. 5009f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * Called via ctx->Driver.LinkShader() 501056dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * This actually involves converting GLSL IR into an intermediate TGSI-like IR 501156dc2c176c3ef0d4d5abea54ff4035b062262286Bryan Cain * with code lowering and other optimizations. 5012f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 5013f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan CainGLboolean 5014f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cainst_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 5015f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain{ 5016f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain assert(prog->LinkStatus); 5017f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5018f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 5019f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 5020f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 5021f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5022f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain bool progress; 5023f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain exec_list *ir = prog->_LinkedShaders[i]->ir; 5024f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain const struct gl_shader_compiler_options *options = 5025f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 5026f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5027f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do { 5028c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP | 5029c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie EXP_TO_EXP2 | LOG_TO_LOG2; 5030c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie if (options->EmitNoPow) 5031c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie what_to_lower |= POW_TO_EXP2; 5032c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie if (!ctx->Const.NativeIntegers) 5033c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie what_to_lower |= INT_DIV_TO_MUL_RCP; 5034c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie 5035f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = false; 5036f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5037f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* Lowering */ 5038f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain do_mat_op_to_vec(ir); 5039c62e02000d11e29e70a1000d32cb08d9a450485fDave Airlie lower_instructions(ir, what_to_lower); 5040f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5041f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 5042f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 50431d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick progress = do_common_optimization(ir, true, true, 50441d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick options->MaxUnrollIterations) 50451d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick || progress; 5046f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 504710d31cb307f90a08fafed5c67945ffe53d279940Bryan Cain progress = lower_quadop_vector(ir, false) || progress; 5048f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5049488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain if (options->MaxIfDepth == 0) 5050f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_discard(ir) || progress; 5051488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain 5052488fe51cf823ccd137c667f1e92dd86f8323b723Bryan Cain progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; 5053f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5054f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoNoise) 5055f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = lower_noise(ir) || progress; 5056f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5057f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain /* If there are forms of indirect addressing that the driver 5058f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain * cannot handle, perform the lowering pass. 5059f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain */ 5060f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 5061f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 5062f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = 5063f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain lower_variable_index_to_cond_assign(ir, 5064f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectInput, 5065f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectOutput, 5066f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectTemp, 5067f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain options->EmitNoIndirectUniform) 5068f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain || progress; 5069f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5070f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain progress = do_vec_index_to_cond_assign(ir) || progress; 5071f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } while (progress); 5072f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5073f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain validate_ir_tree(ir); 5074f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5075f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5076f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 5077f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain struct gl_program *linked_prog; 5078f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5079f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (prog->_LinkedShaders[i] == NULL) 5080f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain continue; 5081f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 50827e63b613a5a067462c450338e0bdce5b5976f6f1Marcin Slusarz linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 5083f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5084f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain if (linked_prog) { 5085e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick static const GLenum targets[] = { 5086e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_VERTEX_PROGRAM_ARB, 5087e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_FRAGMENT_PROGRAM_ARB, 5088e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick GL_GEOMETRY_PROGRAM_NV 5089e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick }; 5090e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick 5091e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5092e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick linked_prog); 5093e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) { 5094e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5095e2bdef53807d0f23c2a1ff326ea8190cb57aa90aIan Romanick NULL); 5096b2064ff3115afa075021902ecd35f4a5a772dc9eMarek Olšák _mesa_reference_program(ctx, &linked_prog, NULL); 5097f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_FALSE; 5098f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5099f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5100f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5101f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain _mesa_reference_program(ctx, &linked_prog, NULL); 5102f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain } 5103f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5104f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain return GL_TRUE; 5105f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} 5106f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain 5107c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšákvoid 51089f2963b631cb2a2899fcb0eb384895fd33f9821dBrian Paulst_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, 5109c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák const GLuint outputMapping[], 5110c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák struct pipe_stream_output_info *so) 5111c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák{ 5112c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák unsigned i; 5113c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák struct gl_transform_feedback_info *info = 5114c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák &glsl_to_tgsi->shader_program->LinkedTransformFeedback; 5115c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák 5116c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák for (i = 0; i < info->NumOutputs; i++) { 5117c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->output[i].register_index = 5118c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák outputMapping[info->Outputs[i].OutputRegister]; 51192449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].start_component = info->Outputs[i].ComponentOffset; 51202449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].num_components = info->Outputs[i].NumComponents; 5121c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->output[i].output_buffer = info->Outputs[i].OutputBuffer; 51222449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->output[i].dst_offset = info->Outputs[i].DstOffset; 51232449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák } 51242449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák 51252449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 51262449695e822421fdcaf1c66dffc12d7d705ea69dMarek Olšák so->stride[i] = info->BufferStride[i]; 5127c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák } 5128c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák so->num_outputs = info->NumOutputs; 5129c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák} 5130c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák 5131f379d8f73063a4c4d6cf379318c6b37118d46bfaBryan Cain} /* extern "C" */ 5132