1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2011 Bryan Cain 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file glsl_to_tgsi.cpp 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate GLSL IR to TGSI. 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/compiler.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_visitor.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_print_visitor.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_expression_flattening.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_parser_extras.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "../glsl/program.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_optimization.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ast.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/shaderobj.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h" 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" { 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/shaderapi.h" 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/uniforms.h" 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_instruction.h" 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_optimize.h" 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_print.h" 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/program.h" 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/prog_parameter.h" 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/sampler.h" 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_compiler.h" 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h" 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h" 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_shader_tokens.h" 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h" 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_ureg.h" 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_info.h" 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_context.h" 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_program.h" 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_glsl_to_tgsi.h" 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "st_mesa_to_tgsi.h" 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (1 << PROGRAM_ENV_PARAM) | \ 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (1 << PROGRAM_STATE_VAR) | \ 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (1 << PROGRAM_NAMED_PARAM) | \ 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (1 << PROGRAM_CONSTANT) | \ 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (1 << PROGRAM_UNIFORM)) 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Maximum number of temporary registers. 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It is too big for stack allocated arrays -- it will cause stack overflow on 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Windows and likely Mac OS X. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_TEMPS 4096 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* will be 4 for GLSL 4.00 */ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define MAX_GLSL_TEXTURE_OFFSET 1 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_src_reg; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_dst_reg; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int swizzle_for_size(int size); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This struct is a corresponding struct to TGSI ureg_src. 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_src_reg { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg(gl_register_file file, int index, const glsl_type *type) 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = file; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = index; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->swizzle = swizzle_for_size(type->vector_elements); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->swizzle = SWIZZLE_XYZW; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->negate = 0; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = type ? type->base_type : GLSL_TYPE_ERROR; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = NULL; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg(gl_register_file file, int index, int type) 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = type; 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = file; 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = index; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->swizzle = SWIZZLE_XYZW; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->negate = 0; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = NULL; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg() 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = GLSL_TYPE_ERROR; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = PROGRAM_UNDEFINED; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = 0; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->swizzle = 0; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->negate = 0; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = NULL; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org explicit st_src_reg(st_dst_reg reg); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file; /**< PROGRAM_* from Mesa */ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int negate; /**< NEGATE_XYZW mask from mesa */ 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Register index should be offset by the integer in this reg. */ 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg *reladdr; 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass st_dst_reg { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg(gl_register_file file, int writemask, int type) 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = file; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = 0; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->writemask = writemask; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->cond_mask = COND_TR; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = NULL; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = type; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg() 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = GLSL_TYPE_ERROR; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = PROGRAM_UNDEFINED; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = 0; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->writemask = 0; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->cond_mask = COND_TR; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = NULL; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org explicit st_dst_reg(st_src_reg reg); 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file; /**< PROGRAM_* from Mesa */ 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint cond_mask:4; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */ 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Register index should be offset by the integer in this reg. */ 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg *reladdr; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg::st_src_reg(st_dst_reg reg) 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = reg.type; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = reg.file; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = reg.index; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->swizzle = SWIZZLE_XYZW; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->negate = 0; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = reg.reladdr; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_dst_reg::st_dst_reg(st_src_reg reg) 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = reg.type; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->file = reg.file; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->index = reg.index; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->writemask = WRITEMASK_XYZW; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->cond_mask = COND_TR; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->reladdr = reg.reladdr; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass glsl_to_tgsi_instruction : public exec_node { 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Callers of this ralloc-based new need not call delete. It's 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static void* operator new(size_t size, void *ctx) 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *node; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org node = rzalloc_size(ctx, size); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(node != NULL); 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return node; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned op; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src[3]; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Pointer to the ir source this tree came from for debugging */ 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *ir; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean cond_update; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool saturate; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sampler; /**< sampler index */ 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int tex_target; /**< One of TEXTURE_*_INDEX */ 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLboolean tex_shadow; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET]; 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tex_offset_num_offset; 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int dead_mask; /**< Used in dead code elimination */ 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */ 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass variable_storage : public exec_node { 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage(ir_variable *var, gl_register_file file, int index) 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org : file(file), index(index), var(var) 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* empty */ 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var; /* variable that maps to this, if any */ 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass immediate_storage : public exec_node { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org immediate_storage(gl_constant_value *values, int size, int type) 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(this->values, values, size * sizeof(gl_constant_value)); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->size = size; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->type = type; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_constant_value values[4]; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size; /**< Number of components (1-4) */ 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int type; /**< GL_FLOAT, GL_INT, GL_BOOL, or GL_UNSIGNED_INT */ 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass function_entry : public exec_node { 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *sig; 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * identifier of this function signature used by the program. 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * At the point that TGSI instructions for function calls are 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generated, we don't know the address of the first instruction of 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the function body. So we make the BranchTarget that is called a 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * small integer and rewrite them during set_branchtargets(). 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int sig_id; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Pointer to first instruction of the function body. 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set during function body emits after main() is processed. 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *bgn_inst; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Index of the first instruction of the function body in actual TGSI. 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set after conversion from glsl_to_tgsi_instruction to TGSI. 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int inst; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** Storage for the return value. */ 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg return_reg; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass glsl_to_tgsi_visitor : public ir_visitor { 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor(); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ~glsl_to_tgsi_visitor(); 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org function_entry *current_function; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_context *ctx; 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program *prog; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_program *shader_program; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_compiler_options *options; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int next_temp; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num_address_regs; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int samplers_used; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool indirect_addr_temps; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool indirect_addr_consts; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int glsl_version; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool native_integers; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *find_variable_storage(ir_variable *var); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int add_constant(gl_register_file file, gl_constant_value values[4], 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size, int datatype, GLuint *swizzle_out); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org function_entry *get_function_signature(ir_function_signature *sig); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg get_temp(const glsl_type *type); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr); 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg st_src_reg_for_float(float val); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg st_src_reg_for_int(int val); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg st_src_reg_for_type(int type, int val); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \name Visit methods 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As typical for the visitor pattern, there must be one \c visit method for 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * each concrete subclass of \c ir_instruction. Virtual base classes within 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the hierarchy should not have \c visit methods. 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@{*/ 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_variable *); 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_loop *); 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_loop_jump *); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_function_signature *); 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_function *); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_expression *); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_swizzle *); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_dereference_variable *); 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_dereference_array *); 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_dereference_record *); 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_assignment *); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_constant *); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_call *); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_return *); 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_discard *); 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_texture *); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org virtual void visit(ir_if *); 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*@}*/ 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg result; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** List of variable_storage */ 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list variables; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** List of immediate_storage */ 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list immediates; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_immediates; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** List of function_entry */ 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list function_signatures; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int next_signature_id; 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** List of glsl_to_tgsi_instruction */ 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list instructions; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0, st_src_reg src1); 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *emit(ir_instruction *ir, unsigned op, 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0, st_src_reg src1, st_src_reg src2); 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned get_opcode(ir_instruction *ir, unsigned op, 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0, st_src_reg src1); 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit the correct dot-product instruction for the type of arguments 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *emit_dp(ir_instruction *ir, 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src1, 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned elements); 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void emit_scalar(ir_instruction *ir, unsigned op, 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void emit_scalar(ir_instruction *ir, unsigned op, 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0, st_src_reg src1); 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void try_emit_float_set(ir_instruction *ir, unsigned op, st_dst_reg dst); 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0); 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void emit_scs(ir_instruction *ir, unsigned op, 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, const st_src_reg &src); 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool try_emit_mad(ir_expression *ir, 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int mul_operand); 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool try_emit_mad_for_and_not(ir_expression *ir, 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int mul_operand); 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool try_emit_sat(ir_expression *ir); 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void emit_swz(ir_expression *ir); 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool process_move_condition(ir_rvalue *ir); 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void simplify_cmp(void); 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void rename_temp_register(int index, int new_index); 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int get_first_temp_read(int index); 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int get_first_temp_write(int index); 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int get_last_temp_read(int index); 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int get_last_temp_write(int index); 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void copy_propagate(void); 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void eliminate_dead_code(void); 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int eliminate_dead_code_advanced(void); 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void merge_registers(void); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void renumber_registers(void); 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *mem_ctx; 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail_link(struct gl_shader_program *prog, const char *fmt, ...) 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_list args; 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(args, fmt); 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_vasprintf_append(&prog->InfoLog, fmt, args); 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(args); 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->LinkStatus = GL_FALSE; 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswizzle_for_size(int size) 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size_swizzles[4] = { 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert((size >= 1) && (size <= 4)); 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return size_swizzles[size - 1]; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic bool 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgis_tex_instruction(unsigned opcode) 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return info->is_tex; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnum_inst_dst_regs(unsigned opcode) 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return info->num_dst; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnum_inst_src_regs(unsigned opcode) 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const tgsi_opcode_info* info = tgsi_get_opcode_info(opcode); 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return info->is_tex ? info->num_src - 1 : info->num_src; 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction * 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0, st_src_reg src1, st_src_reg src2) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int num_reladdr = 0, i; 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = get_opcode(ir, op, dst, src0, src1); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we have to do relative addressing, we want to load the ARL 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * reg directly for one of the regs, and preload the other reladdr 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sources into temps. 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_reladdr += dst.reladdr != NULL; 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_reladdr += src0.reladdr != NULL; 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_reladdr += src1.reladdr != NULL; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_reladdr += src2.reladdr != NULL; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reladdr_to_temp(ir, &src2, &num_reladdr); 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reladdr_to_temp(ir, &src1, &num_reladdr); 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reladdr_to_temp(ir, &src0, &num_reladdr); 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst.reladdr) { 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_arl(ir, address_reg, *dst.reladdr); 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_reladdr--; 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(num_reladdr == 0); 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op = op; 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst = dst; 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[0] = src0; 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[1] = src1; 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[2] = src2; 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->ir = ir; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dead_mask = 0; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->function = NULL; 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL) 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->num_address_regs = 1; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Update indirect addressing status used by TGSI */ 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst.reladdr) { 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(dst.file) { 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->indirect_addr_temps = true; 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_LOCAL_PARAM: 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ENV_PARAM: 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_STATE_VAR: 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_NAMED_PARAM: 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_CONSTANT: 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNIFORM: 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->indirect_addr_consts = true; 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_IMMEDIATE: 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"immediates should not have indirect addressing"); 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i<3; i++) { 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(inst->src[i].reladdr) { 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(inst->src[i].file) { 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->indirect_addr_temps = true; 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_LOCAL_PARAM: 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ENV_PARAM: 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_STATE_VAR: 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_NAMED_PARAM: 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_CONSTANT: 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNIFORM: 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->indirect_addr_consts = true; 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_IMMEDIATE: 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"immediates should not have indirect addressing"); 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->instructions.push_tail(inst); 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org try_emit_float_set(ir, op, dst); 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return inst; 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction * 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0, st_src_reg src1) 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return emit(ir, op, dst, src0, src1, undef_src); 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction * 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0) 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(dst.writemask != 0); 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return emit(ir, op, dst, src0, undef_src, undef_src); 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction * 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op) 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return emit(ir, op, undef_dst, undef_src, undef_src, undef_src); 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /** 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emits the code to convert the result of float SET instructions to integers. 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_float_set(ir_instruction *ir, unsigned op, 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst) 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((op == TGSI_OPCODE_SEQ || 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op == TGSI_OPCODE_SNE || 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op == TGSI_OPCODE_SGE || 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op == TGSI_OPCODE_SLT)) 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src = st_src_reg(dst); 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.negate = ~src.negate; 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst.type = GLSL_TYPE_FLOAT; 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_F2I, dst, src); 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Determines whether to use an integer, unsigned integer, or float opcode 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * based on the operands and input opcode, then emits the result. 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op, 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0, st_src_reg src1) 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int type = GLSL_TYPE_FLOAT; 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src0.type != GLSL_TYPE_ARRAY); 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src0.type != GLSL_TYPE_STRUCT); 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src1.type != GLSL_TYPE_ARRAY); 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src1.type != GLSL_TYPE_STRUCT); 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src0.type == GLSL_TYPE_FLOAT || src1.type == GLSL_TYPE_FLOAT) 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = GLSL_TYPE_FLOAT; 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (native_integers) 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type = src0.type == GLSL_TYPE_BOOL ? GLSL_TYPE_INT : src0.type; 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case4(c, f, i, u) \ 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_##c: \ 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == GLSL_TYPE_INT) op = TGSI_OPCODE_##i; \ 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (type == GLSL_TYPE_UINT) op = TGSI_OPCODE_##u; \ 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else op = TGSI_OPCODE_##f; \ 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case3(f, i, u) case4(f, f, i, u) 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case2fi(f, i) case4(f, f, i, i) 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define case2iu(i, u) case4(i, LAST, i, u) 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(op) { 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(ADD, UADD); 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(MUL, UMUL); 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(MAD, UMAD); 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(DIV, IDIV, UDIV); 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(MAX, IMAX, UMAX); 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(MIN, IMIN, UMIN); 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2iu(MOD, UMOD); 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(SEQ, USEQ); 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(SNE, USNE); 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(SGE, ISGE, USGE); 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(SLT, ISLT, USLT); 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2iu(ISHR, USHR); 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case2fi(SSG, ISSG); 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case3(ABS, IABS, IABS); 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: break; 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(op != TGSI_OPCODE_LAST); 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return op; 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_instruction * 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_dp(ir_instruction *ir, 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0, st_src_reg src1, 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned elements) 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const unsigned dot_opcodes[] = { 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_OPCODE_DP2, TGSI_OPCODE_DP3, TGSI_OPCODE_DP4 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return emit(ir, dot_opcodes[elements - 2], dst, src0, src1); 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emits TGSI scalar opcodes to produce unique answers across channels. 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Some TGSI opcodes are scalar-only, like ARB_fp/vp. The src X 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channel determines the result across all channels. So to do a vec4 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of this operation, we want to emit a scalar per source channel used 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to produce dest channels. 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg orig_src0, st_src_reg orig_src1) 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i, j; 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int done_mask = ~dst.writemask; 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TGSI RCP is a scalar operation splatting results to all channels, 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dst channels. 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < 4; i++) { 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint this_mask = (1 << i); 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst; 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0 = orig_src0; 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src1 = orig_src1; 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (done_mask & this_mask) 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = i + 1; j < 4; j++) { 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there is another enabled component in the destination that is 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * derived from the same inputs, generate its value on this pass as 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well. 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(done_mask & (1 << j)) && 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src0.swizzle, j) == src0_swiz && 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src1.swizzle, j) == src1_swiz) { 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this_mask |= (1 << j); 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0_swiz, src0_swiz); 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src1_swiz, src1_swiz); 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, op, dst, src0, src1); 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask = this_mask; 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org done_mask |= this_mask; 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op, 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0) 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg undef = undef_src; 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org undef.swizzle = SWIZZLE_XXXX; 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, op, dst, src0, undef); 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, st_src_reg src0) 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int op = TGSI_OPCODE_ARL; 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op = TGSI_OPCODE_UARL; 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(NULL, op, dst, src0); 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit an TGSI_OPCODE_SCS instruction 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The \c SCS opcode functions a bit differently than the other TGSI opcodes. 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Instead of splatting its result across all four components of the 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * destination, it writes one value to the \c x component and another value to 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the \c y component. 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param ir IR instruction being processed 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param op Either \c TGSI_OPCODE_SIN or \c TGSI_OPCODE_COS depending 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on which value is desired. 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param dst Destination register 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param src Source register 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::emit_scs(ir_instruction *ir, unsigned op, 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst, 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const st_src_reg &src) 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Vertex programs cannot use the SCS opcode. 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) { 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, op, dst, src); 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned component = (op == TGSI_OPCODE_SIN) ? 0 : 1; 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned scs_mask = (1U << component); 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int done_mask = ~dst.writemask; 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg tmp; 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(op == TGSI_OPCODE_SIN || op == TGSI_OPCODE_COS); 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there are compnents in the destination that differ from the component 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that will be written by the SCS instrution, we'll need a temporary. 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scs_mask != unsigned(dst.writemask)) { 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = get_temp(glsl_type::vec4_type); 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < 4; i++) { 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned this_mask = (1U << i); 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src0 = src; 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((done_mask & this_mask) != 0) 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The source swizzle specified which component of the source generates 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sine / cosine for the current component in the destination. The SCS 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction requires that this value be swizzle to the X component. 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Replace the current swizzle with a swizzle that puts the source in 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the X component. 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned src0_swiz = GET_SWZ(src.swizzle, i); 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0_swiz, src0_swiz); 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned j = i + 1; j < 4; j++) { 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there is another enabled component in the destination that is 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * derived from the same inputs, generate its value on this pass as 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * well. 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(done_mask & (1 << j)) && 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src0.swizzle, j) == src0_swiz) { 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this_mask |= (1 << j); 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this_mask != scs_mask) { 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst; 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg tmp_dst = st_dst_reg(tmp); 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit the SCS instruction. 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, TGSI_OPCODE_SCS, tmp_dst, src0); 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask = scs_mask; 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Move the result of the SCS instruction to the desired location in 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the destination. 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp.swizzle = MAKE_SWIZZLE4(component, component, 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org component, component); 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, TGSI_OPCODE_SCS, dst, tmp); 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask = this_mask; 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit the SCS instruction to write directly to the destination. 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = emit(ir, TGSI_OPCODE_SCS, dst, src0); 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask = scs_mask; 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org done_mask |= this_mask; 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::add_constant(gl_register_file file, 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_constant_value values[4], int size, int datatype, 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint *swizzle_out) 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == PROGRAM_CONSTANT) { 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return _mesa_add_typed_unnamed_constant(this->prog->Parameters, values, 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size, datatype, swizzle_out); 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index = 0; 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org immediate_storage *entry; 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(file == PROGRAM_IMMEDIATE); 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Search immediate storage to see if we already have an identical 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * immediate that we can use instead of adding a duplicate entry. 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->immediates) { 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = (immediate_storage *)iter.get(); 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->size == size && 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->type == datatype && 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !memcmp(entry->values, values, size * sizeof(gl_constant_value))) { 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index++; 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add this immediate to the list. */ 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) immediate_storage(values, size, datatype); 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->immediates.push_tail(entry); 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->num_immediates++; 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return index; 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_float(float val) 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_FLOAT); 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union gl_constant_value uval; 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uval.f = val; 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index = add_constant(src.file, &uval, 1, GL_FLOAT, &src.swizzle); 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return src; 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_int(int val) 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src(PROGRAM_IMMEDIATE, -1, GLSL_TYPE_INT); 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org union gl_constant_value uval; 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(native_integers); 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uval.i = val; 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index = add_constant(src.file, &uval, 1, GL_INT, &src.swizzle); 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return src; 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::st_src_reg_for_type(int type, int val) 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type == GLSL_TYPE_FLOAT ? st_src_reg_for_float(val) : 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg_for_int(val); 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return st_src_reg_for_float(val); 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtype_size(const struct glsl_type *type) 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size; 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type->base_type) { 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_FLOAT: 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_BOOL: 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_matrix()) { 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type->matrix_columns; 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Regardless of size of vector, it gets a vec4. This is bad 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * packing for things like floats, but otherwise arrays become a 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * mess. Hopefully a later pass over the code can pack scalars 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * down if appropriate. 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_ARRAY: 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type->length > 0); 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return type_size(type->fields.array) * type->length; 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_STRUCT: 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size = 0; 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type->length; i++) { 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size += type_size(type->fields.structure[i].type); 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return size; 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_SAMPLER: 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Samplers take up one slot in UNIFORMS[], but they're baked in 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * at link time. 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In the initial pass of codegen, we assign temporary numbers to 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * intermediate results. (not SSA -- variable assignments will reuse 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * storage). 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_src_reg 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_temp(const glsl_type *type) 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src; 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT; 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.file = PROGRAM_TEMPORARY; 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index = next_temp; 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.reladdr = NULL; 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_temp += type_size(type); 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_array() || type->is_record()) { 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = SWIZZLE_NOOP; 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = swizzle_for_size(type->vector_elements); 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.negate = 0; 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return src; 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvariable_storage * 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::find_variable_storage(ir_variable *var) 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *entry; 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->variables) { 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = (variable_storage *)iter.get(); 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->var == var) 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_variable *ir) 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(ir->name, "gl_FragCoord") == 0) { 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fp->OriginUpperLeft = ir->origin_upper_left; 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fp->PixelCenterInteger = ir->pixel_center_integer; 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) { 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ir_state_slot *const slots = ir->state_slots; 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->state_slots != NULL); 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check if this statevar's setup in the STATE file exactly 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * matches how we'll want to reference it as a 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * struct/array/whatever. If not, then we need to move it into 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * temporary storage and hope that it'll get copy-propagated 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * out. 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->num_state_slots; i++) { 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (slots[i].swizzle != SWIZZLE_XYZW) { 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *storage; 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst; 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i == ir->num_state_slots) { 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We'll set the index later. */ 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variables.push_tail(storage); 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = undef_dst; 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The variable_storage constructor allocates slots based on the size 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the type. However, this had better match the number of state 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * elements that we're going to copy into the new temporary. 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert((int) ir->num_state_slots == type_size(ir->type)); 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp); 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variables.push_tail(storage); 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp += type_size(ir->type); 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index, 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT)); 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < ir->num_state_slots; i++) { 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index = _mesa_add_state_reference(this->prog->Parameters, 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (gl_state_index *)slots[i].tokens); 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (storage->file == PROGRAM_STATE_VAR) { 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (storage->index == -1) { 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org storage->index = index; 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index == storage->index + (int)i); 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We use GLSL_TYPE_FLOAT here regardless of the actual type of 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the data being moved since MOV does not care about the type of 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * data it is moving, and we don't want to declare registers with 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array or struct types. 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src(PROGRAM_STATE_VAR, index, GLSL_TYPE_FLOAT); 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = slots[i].swizzle; 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, dst, src); 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* even a float takes up a whole vec4 reg in a struct/array. */ 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst.index++; 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (storage->file == PROGRAM_TEMPORARY && 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst.index != storage->index + (int) ir->num_state_slots) { 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail_link(this->shader_program, 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "failed to load builtin uniform `%s' (%d/%d regs loaded)\n", 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->name, dst.index - storage->index, 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_size(ir->type)); 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_loop *ir) 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_variable *counter = NULL; 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->counter != NULL) 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org counter = new(ir) ir_dereference_variable(ir->counter); 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->from != NULL) { 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->counter != NULL); 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL); 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a->accept(this); 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete a; 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(NULL, TGSI_OPCODE_BGNLOOP); 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->to) { 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *e = 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ir) ir_expression(ir->cmp, glsl_type::bool_type, 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org counter, ir->to); 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_if *if_stmt = new(ir) ir_if(e); 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break); 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_stmt->then_instructions.push_tail(brk); 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_stmt->accept(this); 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete if_stmt; 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete e; 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete brk; 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_exec_list(&ir->body_instructions, this); 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->increment) { 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *e = 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new(ir) ir_expression(ir_binop_add, counter->type, 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org counter, ir->increment); 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_assignment *a = new(ir) ir_assignment(counter, e, NULL); 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a->accept(this); 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete a; 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete e; 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(NULL, TGSI_OPCODE_ENDLOOP); 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_loop_jump *ir) 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->mode) { 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_loop_jump::jump_break: 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(NULL, TGSI_OPCODE_BRK); 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_loop_jump::jump_continue: 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(NULL, TGSI_OPCODE_CONT); 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_function_signature *ir) 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void)ir; 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_function *ir) 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Ignore function bodies other than main() -- we shouldn't see calls to 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * them since they should all be inlined before we get to glsl_to_tgsi. 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(ir->name, "main") == 0) { 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ir_function_signature *sig; 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list empty; 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig = ir->matching_signature(&empty); 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(sig); 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, sig->body) { 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_instruction *ir = (ir_instruction *)iter.get(); 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->accept(this); 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int nonmul_operand = 1 - mul_operand; 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg a, b, c; 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg result_dst; 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *expr = ir->operands[mul_operand]->as_expression(); 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!expr || expr->operation != ir_binop_mul) 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expr->operands[0]->accept(this); 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a = this->result; 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expr->operands[1]->accept(this); 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b = this->result; 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[nonmul_operand]->accept(this); 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c = this->result; 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = get_temp(ir->type); 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst = st_dst_reg(this->result); 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MAD, result_dst, a, b, c); 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit MAD(a, -b, a) instead of AND(a, NOT(b)) 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The logic values are 1.0 for true and 0.0 for false. Logical-and is 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implemented using multiplication, and logical-or is implemented using 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * addition. Logical-not can be implemented as (true - x), or (1.0 - x). 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * As result, the logical expression (a & !b) can be rewritten as: 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - a * !b 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - a * (1 - b) 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - (a * 1) - (a * b) 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - a + -(a * b) 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - a + (a * -b) 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This final expression can be implemented as a single MAD(a, -b, a) 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction. 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand) 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int other_operand = 1 - try_operand; 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg a, b; 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *expr = ir->operands[try_operand]->as_expression(); 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!expr || expr->operation != ir_unop_logic_not) 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[other_operand]->accept(this); 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org a = this->result; 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org expr->operands[0]->accept(this); 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b = this->result; 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org b.negate = ~b.negate; 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = get_temp(ir->type); 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MAD, st_dst_reg(this->result), a, b, a); 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::try_emit_sat(ir_expression *ir) 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Saturates were only introduced to vertex programs in 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NV_vertex_program3, so don't give them to drivers in the VP. 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->prog->Target == GL_VERTEX_PROGRAM_ARB) 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *sat_src = ir->as_rvalue_to_saturate(); 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!sat_src) 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sat_src->accept(this); 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src = this->result; 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If we generated an expression instruction into a temporary in 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * processing the saturate's operand, apply the saturate to that 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction. Otherwise, generate a MOV to do the saturate. 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that we have to be careful to only do this optimization if 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the instruction in question was what generated src->result. For 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * example, ir_dereference_array might generate a MUL instruction 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to create the reladdr, and return us a src reg using that 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * reladdr. That MUL result is not the value we're trying to 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * saturate. 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *sat_src_expr = sat_src->as_expression(); 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul || 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sat_src_expr->operation == ir_binop_add || 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sat_src_expr->operation == ir_binop_dot)) { 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *new_inst; 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst->saturate = true; 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = get_temp(ir->type); 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg result_dst = st_dst_reg(this->result); 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst; 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, TGSI_OPCODE_MOV, result_dst, src); 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->saturate = true; 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return true; 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir, 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg *reg, int *num_reladdr) 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!reg->reladdr) 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_arl(ir, address_reg, *reg->reladdr); 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (*num_reladdr != 1) { 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = get_temp(glsl_type::vec4_type); 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, st_dst_reg(temp), *reg); 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *reg = temp; 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (*num_reladdr)--; 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_expression *ir) 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int operand; 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg op[Elements(ir->operands)]; 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg result_src; 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg result_dst; 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Quick peephole: Emit MAD(a, b, c) instead of ADD(MUL(a, b), c) 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operation == ir_binop_add) { 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (try_emit_mad(ir, 1)) 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (try_emit_mad(ir, 0)) 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Quick peephole: Emit OPCODE_MAD(-a, -b, a) instead of AND(a, NOT(b)) 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operation == ir_binop_logic_and) { 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (try_emit_mad_for_and_not(ir, 1)) 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (try_emit_mad_for_and_not(ir, 0)) 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (try_emit_sat(ir)) 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operation == ir_quadop_vector) 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"ir_quadop_vector should have been lowered"); 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (operand = 0; operand < ir->get_num_operands(); operand++) { 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.file = PROGRAM_UNDEFINED; 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[operand]->accept(this); 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->result.file == PROGRAM_UNDEFINED) { 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_print_visitor v; 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("Failed to get tree for expression operand:\n"); 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[operand]->accept(&v); 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exit(1); 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[operand] = this->result; 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Matrix expression operands should have been broken down to vector 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operations already. 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!ir->operands[operand]->type->is_matrix()); 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int vector_elements = ir->operands[0]->type->vector_elements; 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operands[1]) { 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vector_elements = MAX2(vector_elements, 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[1]->type->vector_elements); 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.file = PROGRAM_UNDEFINED; 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Storage for our result. Ideally for an assignment we'd be using 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the actual storage for the result here, instead. 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = get_temp(ir->type); 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* convenience for the emit functions below. */ 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst = st_dst_reg(result_src); 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Limit writes to the channels that will be used by result_src later. 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This does limit this temp's use as a temporary for multi-instruction 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sequences. 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst.writemask = (1 << ir->type->vector_elements) - 1; 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->operation) { 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_logic_not: 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result_dst.type != GLSL_TYPE_FLOAT) 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Previously 'SEQ dst, src, 0.0' was used for this. However, many 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * older GPUs implement SEQ using multiple instructions (i915 uses two 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SGE instructions and a MUL instruction). Since our logic values are 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0.0 and 1.0, 1-x also implements !x. 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0].negate = ~op[0].negate; 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], st_src_reg_for_float(1.0)); 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_neg: 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT) 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0].negate = ~op[0].negate; 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = op[0]; 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_abs: 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]); 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_sign: 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]); 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_rcp: 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_RCP, result_dst, op[0]); 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_exp2: 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_EX2, result_dst, op[0]); 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_exp: 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_log: 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"not reached: should be handled by ir_explog_to_explog2"); 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_log2: 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_LG2, result_dst, op[0]); 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_sin: 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_cos: 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_sin_reduced: 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scs(ir, TGSI_OPCODE_SIN, result_dst, op[0]); 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_cos_reduced: 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scs(ir, TGSI_OPCODE_COS, result_dst, op[0]); 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_dFdx: 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_DDX, result_dst, op[0]); 1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_dFdy: 1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The X component contains 1 or -1 depending on whether the framebuffer 1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is a FBO or the window system buffer, respectively. 1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It is then multiplied with the source operand of DDY. 1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const gl_state_index transform_y_state[STATE_LENGTH] 1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM }; 1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned transform_y_index = 1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_add_state_reference(this->prog->Parameters, 1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform_y_state); 1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg transform_y = st_src_reg(PROGRAM_STATE_VAR, 1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform_y_index, 1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::vec4_type); 1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform_y.swizzle = SWIZZLE_XXXX; 1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = get_temp(glsl_type::vec4_type); 1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, st_dst_reg(temp), transform_y, op[0]); 1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_DDY, result_dst, temp); 1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_noise: { 1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* At some point, a motivated person could add a better 1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * implementation of noise. Currently not even the nvidia 1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * binary drivers do anything more than this. In any case, the 1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * place to do this is in the GL state tracker, not the poor 1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * driver. 1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, result_dst, st_src_reg_for_float(0.5)); 1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_add: 1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_sub: 1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SUB, result_dst, op[0], op[1]); 1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_mul: 1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_div: 1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result_dst.type == GLSL_TYPE_FLOAT) 1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_DIV, result_dst, op[0], op[1]); 1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_mod: 1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (result_dst.type == GLSL_TYPE_FLOAT) 1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOD, result_dst, op[0], op[1]); 1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_less: 1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]); 1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_greater: 1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]); 1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_lequal: 1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]); 1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_gequal: 1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]); 1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_equal: 1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_nequal: 1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_all_equal: 1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "==" operator producing a scalar boolean. */ 1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operands[0]->type->is_vector() || 1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[1]->type->is_vector()) { 1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = get_temp(native_integers ? 1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::vec4_type); 1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg temp_dst = st_dst_reg(temp); 1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SEQ, st_dst_reg(temp), op[0], op[1]); 1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit 1-3 AND operations to combine the SEQ results. */ 1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->operands[0]->type->vector_elements) { 1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: 1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 3: 1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_Y; 1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_YYYY; 1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_ZZZZ; 1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 4: 1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_X; 1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_XXXX; 1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_YYYY; 1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_Y; 1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_ZZZZ; 1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_WWWW; 1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, temp_dst, temp1, temp2); 1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_XXXX; 1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_YYYY; 1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, result_dst, temp1, temp2); 1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* After the dot-product, the value will be an integer on the 1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * range [0,4]. Zero becomes 1.0, and positive values become zero. 1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_dp(ir, result_dst, temp, temp, vector_elements); 1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Negating the result of the dot-product gives values on the range 1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * [-4, 0]. Zero becomes 1.0, and negative values become zero. 1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is achieved using SGE. 1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg sge_src = result_src; 1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sge_src.negate = ~sge_src.negate; 1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SGE, result_dst, sge_src, st_src_reg_for_float(0.0)); 1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SEQ, result_dst, op[0], op[1]); 1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_any_nequal: 1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* "!=" operator producing a scalar boolean. */ 1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->operands[0]->type->is_vector() || 1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[1]->type->is_vector()) { 1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = get_temp(native_integers ? 1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::get_instance(ir->operands[0]->type->base_type, 4, 1) : 1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::vec4_type); 1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]); 1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg temp_dst = st_dst_reg(temp); 1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp1 = st_src_reg(temp), temp2 = st_src_reg(temp); 1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit 1-3 OR operations to combine the SNE results. */ 1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->operands[0]->type->vector_elements) { 1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: 1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 3: 1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_Y; 1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_YYYY; 1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_ZZZZ; 1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 4: 1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_X; 1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_XXXX; 1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_YYYY; 1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_Y; 1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_ZZZZ; 1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_WWWW; 1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, temp_dst, temp1, temp2); 1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp1.swizzle = SWIZZLE_XXXX; 1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp2.swizzle = SWIZZLE_YYYY; 1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, result_dst, temp1, temp2); 1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* After the dot-product, the value will be an integer on the 1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * range [0,4]. Zero stays zero, and positive values become 1.0. 1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *const dp = 1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_dp(ir, result_dst, temp, temp, vector_elements); 1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The clamping to [0,1] can be done for free in the fragment 1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader with a saturate. 1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp->saturate = true; 1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Negating the result of the dot-product gives values on the range 1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * achieved using SLT. 1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg slt_src = result_src; 1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org slt_src.negate = ~slt_src.negate; 1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_any: { 1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->operands[0]->type->is_vector()); 1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* After the dot-product, the value will be an integer on the 1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * range [0,4]. Zero stays zero, and positive values become 1.0. 1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *const dp = 1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_dp(ir, result_dst, op[0], op[0], 1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[0]->type->vector_elements); 1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB && 1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst.type == GLSL_TYPE_FLOAT) { 1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The clamping to [0,1] can be done for free in the fragment 1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader with a saturate. 1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dp->saturate = true; 1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (result_dst.type == GLSL_TYPE_FLOAT) { 1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Negating the result of the dot-product gives values on the range 1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * [-4, 0]. Zero stays zero, and negative values become 1.0. This 1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is achieved using SLT. 1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg slt_src = result_src; 1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org slt_src.negate = ~slt_src.negate; 1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Use SNE 0 if integers are being used as boolean values. */ 1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0)); 1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_logic_xor: 1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]); 1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_logic_or: { 1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If integers are used as booleans, we can use an actual "or" 1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction. 1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(native_integers); 1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* After the addition, the value will be an integer on the 1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * range [0,2]. Zero stays zero, and positive values become 1.0. 1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *add = 1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ADD, result_dst, op[0], op[1]); 1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB) { 1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The clamping to [0,1] can be done for free in the fragment 1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader with a saturate if floats are being used as boolean values. 1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org add->saturate = true; 1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Negating the result of the addition gives values on the range 1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * [-2, 0]. Zero stays zero, and negative values become 1.0. This 1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is achieved using SLT. 1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg slt_src = result_src; 1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org slt_src.negate = ~slt_src.negate; 1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0)); 1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_logic_and: 1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If native integers are disabled, the bool args are stored as float 0.0 1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or 1.0, so "mul" gives us "and". If they're enabled, just use the 1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * actual AND opcode. 1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, result_dst, op[0], op[1]); 1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_dot: 1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->operands[0]->type->is_vector()); 1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->operands[0]->type == ir->operands[1]->type); 1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_dp(ir, result_dst, op[0], op[1], 1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->operands[0]->type->vector_elements); 1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_sqrt: 1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* sqrt(x) = x * rsq(x). */ 1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, result_dst, result_src, op[0]); 1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For incoming channels <= 0, set the result to 0. */ 1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0].negate = ~op[0].negate; 1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_CMP, result_dst, 1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org op[0], result_src, st_src_reg_for_float(0.0)); 1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_rsq: 1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_RSQ, result_dst, op[0]); 1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_i2f: 1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_I2F, result_dst, op[0]); 1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* fallthrough to next case otherwise */ 1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_b2f: 1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_float(1.0)); 1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* fallthrough to next case otherwise */ 1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_i2u: 1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_u2i: 1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Converting between signed and unsigned integers is a no-op. */ 1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = op[0]; 1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_b2i: 1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Booleans are stored as integers using ~0 for true and 0 for false. 1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GLSL requires that int(bool) return 1 for true and 0 for false. 1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This conversion is done with AND, but it could be done with NEG. 1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, result_dst, op[0], st_src_reg_for_int(1)); 1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Booleans and integers are both stored as floats when native 1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integers are disabled. 1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = op[0]; 1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_f2i: 1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_F2I, result_dst, op[0]); 1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_f2u: 1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_F2U, result_dst, op[0]); 1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_bitcast_f2i: 1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_bitcast_f2u: 1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_bitcast_i2f: 1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_bitcast_u2f: 1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = op[0]; 1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_f2b: 1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_i2b: 1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_INEG, result_dst, op[0]); 1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], st_src_reg_for_float(0.0)); 1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_trunc: 1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_TRUNC, result_dst, op[0]); 1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_ceil: 1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_CEIL, result_dst, op[0]); 1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_floor: 1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_FLR, result_dst, op[0]); 1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_round_even: 1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ROUND, result_dst, op[0]); 1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_fract: 1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_FRC, result_dst, op[0]); 1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_min: 1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MIN, result_dst, op[0], op[1]); 1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_max: 1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MAX, result_dst, op[0], op[1]); 1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_pow: 1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_scalar(ir, TGSI_OPCODE_POW, result_dst, op[0], op[1]); 1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_bit_not: 1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_NOT, result_dst, op[0]); 1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_unop_u2f: 1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_U2F, result_dst, op[0]); 1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_lshift: 1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_SHL, result_dst, op[0], op[1]); 1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_rshift: 1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ISHR, result_dst, op[0], op[1]); 1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_bit_and: 1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_AND, result_dst, op[0], op[1]); 1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_bit_xor: 1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_XOR, result_dst, op[0], op[1]); 1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_bit_or: 1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_OR, result_dst, op[0], op[1]); 1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"GLSL 1.30 features unsupported"); 1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_ubo_load: 1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"not yet supported"); 1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_quadop_vector: 1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This operation should have already been handled. 1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Should not get here."); 1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = result_src; 1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_swizzle *ir) 1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src; 1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int swizzle[4]; 1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note that this is only swizzles in expressions, not those on the left 1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * hand side of an assignment, which do write masking. See ir_assignment 1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for that. 1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->val->accept(this); 1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = this->result; 1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(src.file != PROGRAM_UNDEFINED); 1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < 4; i++) { 1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i < ir->type->vector_elements) { 1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (i) { 1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 0: 1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle[i] = GET_SWZ(src.swizzle, ir->mask.x); 1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 1: 1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle[i] = GET_SWZ(src.swizzle, ir->mask.y); 1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 2: 1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle[i] = GET_SWZ(src.swizzle, ir->mask.z); 1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case 3: 1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle[i] = GET_SWZ(src.swizzle, ir->mask.w); 1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the type is smaller than a vec4, replicate the last 1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channel out. 1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle[i] = swizzle[ir->type->vector_elements - 1]; 1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); 1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = src; 1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_variable *ir) 1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *entry = find_variable_storage(ir->var); 1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *var = ir->var; 1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!entry) { 1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (var->mode) { 1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_uniform: 1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM, 1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location); 1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variables.push_tail(entry); 1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_in: 1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_inout: 1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The linker assigns locations for varyings and attributes, 1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * including deprecated builtins (like gl_Color), user-assign 1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generic attributes (glBindVertexLocation), and 1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * user-defined varyings. 1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: We would hit this path for function arguments. Fix! 1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var->location != -1); 1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) variable_storage(var, 1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PROGRAM_INPUT, 1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location); 1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_out: 1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(var->location != -1); 1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) variable_storage(var, 1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PROGRAM_OUTPUT, 1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location + var->index); 1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_system_value: 1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) variable_storage(var, 1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PROGRAM_SYSTEM_VALUE, 1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org var->location); 1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_auto: 1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_var_temporary: 1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY, 1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp); 1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variables.push_tail(entry); 1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_temp += type_size(var->type); 1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!entry) { 1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("Failed to make storage for %s\n", var->name); 1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exit(1); 1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = st_src_reg(entry->file, entry->index, var->type); 1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!native_integers) 1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.type = GLSL_TYPE_FLOAT; 1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_array *ir) 2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *index; 2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src; 2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int element_size = type_size(ir->type); 2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index = ir->array_index->constant_expression_value(); 2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->array->accept(this); 2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = this->result; 2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (index) { 2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index += index->value.i[0] * element_size; 2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Variable index array dereference. It eats the "vec4" of the 2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * base of the array and an index that offsets the TGSI register 2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * index. 2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->array_index->accept(this); 2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg index_reg; 2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (element_size == 1) { 2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_reg = this->result; 2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_reg = get_temp(native_integers ? 2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::int_type : glsl_type::float_type); 2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, st_dst_reg(index_reg), 2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result, st_src_reg_for_type(index_reg.type, element_size)); 2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there was already a relative address register involved, add the 2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new and the old together to get the new offset. 2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src.reladdr != NULL) { 2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg accum_reg = get_temp(native_integers ? 2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_type::int_type : glsl_type::float_type); 2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_ADD, st_dst_reg(accum_reg), 2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_reg, *src.reladdr); 2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_reg = accum_reg; 2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.reladdr = ralloc(mem_ctx, st_src_reg); 2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(src.reladdr, &index_reg, sizeof(index_reg)); 2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the type is smaller than a vec4, replicate the last channel out. */ 2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->type->is_scalar() || ir->type->is_vector()) 2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = swizzle_for_size(ir->type->vector_elements); 2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.swizzle = SWIZZLE_NOOP; 2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Change the register type to the element type of the array. */ 2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.type = ir->type->base_type; 2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = src; 2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_dereference_record *ir) 2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *struct_type = ir->record->type; 2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int offset = 0; 2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->record->accept(this); 2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < struct_type->length; i++) { 2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset += type_size(struct_type->fields.structure[i].type); 2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If the type is smaller than a vec4, replicate the last channel out. */ 2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->type->is_scalar() || ir->type->is_vector()) 2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.swizzle = SWIZZLE_NOOP; 2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.index += offset; 2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.type = ir->type->base_type; 2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We want to be careful in assignment setup to hit the actual storage 2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instead of potentially using a temporary like we might with the 2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ir_dereference handler. 2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic st_dst_reg 2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v) 2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The LHS must be a dereference. If the LHS is a variable indexed array 2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * access of a vector, it must be separated into a series conditional moves 2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * before reaching this point (see ir_vec_index_to_cond_assign). 2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->as_dereference()); 2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_dereference_array *deref_array = ir->as_dereference_array(); 2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (deref_array) { 2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!deref_array->array->type->is_vector()); 2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Use the rvalue deref handler for the most part. We'll ignore 2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * swizzles in it and write swizzles using writemask, though. 2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->accept(v); 2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return st_dst_reg(v->result); 2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Process the condition of a conditional assignment 2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examines the condition of a conditional assignment to generate the optimal 2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * first operand of a \c CMP instruction. If the condition is a relational 2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operator with 0 (e.g., \c ir_binop_less), the value being compared will be 2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used as the source for the \c CMP instruction. Otherwise the comparison 2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is processed to a boolean result, and the boolean result is used as the 2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * operand to the CMP instruction. 2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool 2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir) 2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *src_ir = ir; 2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool negate = true; 2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool switch_order = false; 2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_expression *const expr = ir->as_expression(); 2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((expr != NULL) && (expr->get_num_operands() == 2)) { 2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool zero_on_left = false; 2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (expr->operands[0]->is_zero()) { 2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_ir = expr->operands[1]; 2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org zero_on_left = true; 2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (expr->operands[1]->is_zero()) { 2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_ir = expr->operands[0]; 2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org zero_on_left = false; 2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* a is - 0 + - 0 + 2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (a < 0) T F F ( a < 0) T F F 2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (0 < a) F F T (-a < 0) F F T 2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (a <= 0) T T F (-a < 0) F F T (swap order of other operands) 2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (0 <= a) F T T ( a < 0) T F F (swap order of other operands) 2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (a > 0) F F T (-a < 0) F F T 2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (0 > a) T F F ( a < 0) T F F 2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (a >= 0) F T T ( a < 0) T F F (swap order of other operands) 2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (0 >= a) T T F (-a < 0) F F T (swap order of other operands) 2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Note that exchanging the order of 0 and 'a' in the comparison simply 2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * means that the value of 'a' should be negated. 2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_ir != ir) { 2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (expr->operation) { 2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_less: 2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch_order = false; 2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org negate = zero_on_left; 2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_greater: 2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch_order = false; 2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org negate = !zero_on_left; 2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_lequal: 2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch_order = true; 2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org negate = !zero_on_left; 2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_binop_gequal: 2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch_order = true; 2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org negate = zero_on_left; 2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This isn't the right kind of comparison afterall, so make sure 2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the whole condition is visited. 2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_ir = ir; 2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_ir->accept(this); 2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We use the TGSI_OPCODE_CMP (a < 0 ? b : c) for conditional moves, and the 2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * condition we produced is 0.0 or 1.0. By flipping the sign, we can 2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * choose which value TGSI_OPCODE_CMP produces without an extra instruction 2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * computing the condition. 2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (negate) 2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.negate = ~this->result.negate; 2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return switch_order; 2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_assignment *ir) 2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg l; 2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg r; 2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->rhs->accept(this); 2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r = this->result; 2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l = get_assignment_lhs(ir->lhs, this); 2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: This should really set to the correct maximal writemask for each 2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: component written (in the loops below). This case can only 2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: occur for matrices, arrays, and structures. 2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->write_mask == 0) { 2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.writemask = WRITEMASK_XYZW; 2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (ir->lhs->type->is_scalar() && 2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lhs->variable_referenced()->mode == ir_var_out) { 2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FINISHME: This hack makes writing to gl_FragDepth, which lives in the 2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FINISHME: W component of fragment shader output zero, work correctly. 2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.writemask = WRITEMASK_XYZW; 2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int swizzles[4]; 2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int first_enabled_chan = 0; 2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int rhs_chan = 0; 2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.writemask = ir->write_mask; 2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i = 0; i < 4; i++) { 2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (l.writemask & (1 << i)) { 2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_enabled_chan = GET_SWZ(r.swizzle, i); 2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Swizzle a small RHS vector into the channels being written. 2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl ir treats write_mask as dictating how many channels are 2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * present on the RHS while TGSI treats write_mask as just 2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * showing which channels of the vec4 RHS get written. 2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i = 0; i < 4; i++) { 2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (l.writemask & (1 << i)) 2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzles[i] = GET_SWZ(r.swizzle, rhs_chan++); 2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzles[i] = first_enabled_chan; 2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.swizzle = MAKE_SWIZZLE4(swizzles[0], swizzles[1], 2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzles[2], swizzles[3]); 2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(l.file != PROGRAM_UNDEFINED); 2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(r.file != PROGRAM_UNDEFINED); 2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->condition) { 2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const bool switch_order = this->process_move_condition(ir->condition); 2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg condition = this->result; 2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type_size(ir->lhs->type); i++) { 2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg l_src = st_src_reg(l); 2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg condition_temp = condition; 2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l_src.swizzle = swizzle_for_size(ir->lhs->type->vector_elements); 2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) { 2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This is necessary because TGSI's CMP instruction expects the 2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * condition to be a float, and we store booleans as integers. 2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If TGSI had a UCMP instruction or similar, this extra 2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction would not be necessary. 2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition_temp = get_temp(glsl_type::vec4_type); 2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition.negate = 0; 2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_I2F, st_dst_reg(condition_temp), condition); 2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org condition_temp.swizzle = condition.swizzle; 2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (switch_order) { 2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_CMP, l, condition_temp, l_src, r); 2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_CMP, l, condition_temp, r, l_src); 2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index++; 2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index++; 2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (ir->rhs->as_expression() && 2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->instructions.get_tail() && 2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->rhs == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->ir && 2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type_size(ir->lhs->type) == 1 && 2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.writemask == ((glsl_to_tgsi_instruction *)this->instructions.get_tail())->dst.writemask) { 2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* To avoid emitting an extra MOV when assigning an expression to a 2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * variable, emit the last instruction of the expression again, but 2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * replace the destination register with the target of the assignment. 2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Dead code elimination will remove the original instruction. 2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst, *new_inst; 2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst = emit(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2]); 2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst->saturate = inst->saturate; 2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dead_mask = inst->dst.writemask; 2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type_size(ir->lhs->type); i++) { 2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->rhs->type->is_array()) 2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.type = ir->rhs->type->element_type()->base_type; 2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ir->rhs->type->is_record()) 2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.type = ir->rhs->type->fields.structure[i].type->base_type; 2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, l, r); 2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index++; 2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index++; 2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_constant *ir) 2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src; 2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat stack_vals[4] = { 0 }; 2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_constant_value *values = (gl_constant_value *) stack_vals; 2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum gl_type = GL_NONE; 2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int i; 2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int in_array = 0; 2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file = in_array ? PROGRAM_CONSTANT : PROGRAM_IMMEDIATE; 2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Unfortunately, 4 floats is all we can get into 2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * _mesa_add_typed_unnamed_constant. So, make a temp to store an 2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * aggregate constant and move each constant value into it. If we 2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * get lucky, copy propagation will eliminate the extra moves. 2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->type->base_type == GLSL_TYPE_STRUCT) { 2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp_base = get_temp(ir->type); 2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg temp = st_dst_reg(temp_base); 2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, ir->components) { 2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *field_value = (ir_constant *)iter.get(); 2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size = type_size(field_value->type); 2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(size > 0); 2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_value->accept(this); 2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = this->result; 2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < (unsigned int)size; i++) { 2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, temp, src); 2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index++; 2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp.index++; 2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = temp_base; 2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->type->is_array()) { 2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp_base = get_temp(ir->type); 2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg temp = st_dst_reg(temp_base); 2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int size = type_size(ir->type->fields.array); 2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(size > 0); 2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org in_array++; 2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->length; i++) { 2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->array_elements[i]->accept(this); 2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = this->result; 2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int j = 0; j < size; j++) { 2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, temp, src); 2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index++; 2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp.index++; 2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = temp_base; 2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org in_array--; 2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->type->is_matrix()) { 2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg mat = get_temp(ir->type); 2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg mat_column = st_dst_reg(mat); 2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->matrix_columns; i++) { 2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(ir->type->base_type == GLSL_TYPE_FLOAT); 2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values = (gl_constant_value *) &ir->value.f[i * ir->type->vector_elements]; 2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = st_src_reg(file, -1, ir->type->base_type); 2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.index = add_constant(file, 2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values, 2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->type->vector_elements, 2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_FLOAT, 2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &src.swizzle); 2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, mat_column, src); 2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mat_column.index++; 2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = mat; 2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->type->base_type) { 2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_FLOAT: 2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_type = GL_FLOAT; 2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->vector_elements; i++) { 2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].f = ir->value.f[i]; 2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_UINT: 2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_type = native_integers ? GL_UNSIGNED_INT : GL_FLOAT; 2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->vector_elements; i++) { 2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].u = ir->value.u[i]; 2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].f = ir->value.u[i]; 2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_INT: 2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_type = native_integers ? GL_INT : GL_FLOAT; 2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->vector_elements; i++) { 2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].i = ir->value.i[i]; 2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].f = ir->value.i[i]; 2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_TYPE_BOOL: 2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_type = native_integers ? GL_BOOL : GL_FLOAT; 2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ir->type->vector_elements; i++) { 2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (native_integers) 2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].u = ir->value.b[i] ? ~0 : 0; 2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values[i].f = ir->value.b[i]; 2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Non-float/uint/int/bool constant"); 2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = st_src_reg(file, -1, ir->type); 2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.index = add_constant(file, 2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values, 2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->type->vector_elements, 2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_type, 2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &this->result.swizzle); 2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfunction_entry * 2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig) 2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org function_entry *entry; 2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->function_signatures) { 2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = (function_entry *)iter.get(); 2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->sig == sig) 2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = ralloc(mem_ctx, function_entry); 2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->sig = sig; 2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->sig_id = this->next_signature_id++; 2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->bgn_inst = NULL; 2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Allocate storage for all the parameters. */ 2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, sig->parameters) { 2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *param = (ir_variable *)iter.get(); 2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *storage; 2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org storage = find_variable_storage(param); 2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!storage); 2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp); 2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->variables.push_tail(storage); 2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp += type_size(param->type); 2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!sig->return_type->is_void()) { 2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->return_reg = get_temp(sig->return_type); 2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->return_reg = undef_src; 2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->function_signatures.push_tail(entry); 2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return entry; 2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_call *ir) 2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *call_inst; 2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_function_signature *sig = ir->callee; 2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org function_entry *entry = get_function_signature(sig); 2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Process in parameters. */ 2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list_iterator sig_iter = sig->parameters.iterator(); 2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, *ir) { 2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *param = (ir_variable *)sig_iter.get(); 2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (param->mode == ir_var_in || 2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param->mode == ir_var_inout) { 2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *storage = find_variable_storage(param); 2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(storage); 2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param_rval->accept(this); 2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg r = this->result; 2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg l; 2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.file = storage->file; 2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index = storage->index; 2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.reladdr = NULL; 2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.writemask = WRITEMASK_XYZW; 2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.cond_mask = COND_TR; 2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type_size(param->type); i++) { 2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, l, r); 2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index++; 2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index++; 2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig_iter.next(); 2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!sig_iter.has_next()); 2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit call instruction */ 2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org call_inst = emit(ir, TGSI_OPCODE_CAL); 2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org call_inst->function = entry; 2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Process out parameters. */ 2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig_iter = sig->parameters.iterator(); 2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, *ir) { 2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_variable *param = (ir_variable *)sig_iter.get(); 2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (param->mode == ir_var_out || 2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param->mode == ir_var_inout) { 2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org variable_storage *storage = find_variable_storage(param); 2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(storage); 2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg r; 2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.file = storage->file; 2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index = storage->index; 2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.reladdr = NULL; 2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.swizzle = SWIZZLE_NOOP; 2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.negate = 0; 2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org param_rval->accept(this); 2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg l = st_dst_reg(this->result); 2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type_size(param->type); i++) { 2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, l, r); 2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index++; 2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index++; 2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sig_iter.next(); 2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!sig_iter.has_next()); 2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Process return value. */ 2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = entry->return_reg; 2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_texture *ir) 2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg result_src, coord, lod_info, projector, dx, dy, offset; 2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg result_dst, coord_dst; 2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = NULL; 2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned opcode = TGSI_OPCODE_NOP; 2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->coordinate) { 2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->coordinate->accept(this); 2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Put our coords in a temp. We'll need to modify them for shadow, 2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * projection, or LOD, so the only case we'd use it as is is if 2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we're doing plain old texturing. The optimization passes on 2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * glsl_to_tgsi_visitor should handle cleaning up our mess in that case. 2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord = get_temp(glsl_type::vec4_type); 2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst = st_dst_reg(coord); 2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->projector) { 2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->projector->accept(this); 2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org projector = this->result; 2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Storage for our result. Ideally for an assignment we'd be using 2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the actual storage for the result here, instead. 2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_src = get_temp(ir->type); 2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result_dst = st_dst_reg(result_src); 2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (ir->op) { 2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_tex: 2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TEX; 2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txb: 2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXB; 2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.bias->accept(this); 2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lod_info = this->result; 2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txl: 2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXL; 2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.lod->accept(this); 2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lod_info = this->result; 2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txd: 2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXD; 2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.grad.dPdx->accept(this); 2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dx = this->result; 2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.grad.dPdy->accept(this); 2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = this->result; 2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txs: 2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXQ; 2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.lod->accept(this); 2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lod_info = this->result; 2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case ir_txf: 2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXF; 2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->lod_info.lod->accept(this); 2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lod_info = this->result; 2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->offset) { 2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->offset->accept(this); 2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset = this->result; 2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *sampler_type = ir->sampler->type; 2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->projector) { 2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode == TGSI_OPCODE_TEX) { 2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Slot the projector in as the last component of the coord. */ 2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_W; 2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, coord_dst, projector); 2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_XYZW; 2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode = TGSI_OPCODE_TXP; 2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg coord_w = coord; 2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_w.swizzle = SWIZZLE_WWWW; 2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For the other TEX opcodes there's no projective version 2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * since the last slot is taken up by LOD info. Do the 2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * projective divide now. 2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_W; 2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_RCP, coord_dst, projector); 2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* In the case where we have to project the coordinates "by hand," 2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the shadow comparator value must also be projected. 2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg tmp_src = coord; 2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->shadow_comparitor) { 2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Slot the shadow value in as the second to last component of the 2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * coord. 2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->shadow_comparitor->accept(this); 2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp_src = get_temp(glsl_type::vec4_type); 2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg tmp_dst = st_dst_reg(tmp_src); 2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Projective division not allowed for array samplers. */ 2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!sampler_type->sampler_array); 2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp_dst.writemask = WRITEMASK_Z; 2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); 2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp_dst.writemask = WRITEMASK_XY; 2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, tmp_dst, coord); 2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_XYZ; 2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MUL, coord_dst, tmp_src, coord_w); 2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_XYZW; 2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord.swizzle = SWIZZLE_XYZW; 2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If projection is done and the opcode is not TGSI_OPCODE_TXP, then the shadow 2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * comparator was put in the correct place (and projected) by the code, 2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * above, that handles by-hand projection. 2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->shadow_comparitor && (!ir->projector || opcode == TGSI_OPCODE_TXP)) { 2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Slot the shadow value in as the second to last component of the 2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * coord. 2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->shadow_comparitor->accept(this); 2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX This will need to be updated for cubemap array samplers. */ 2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && 2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_type->sampler_array) || 2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) { 2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_W; 2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_Z; 2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); 2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_XYZW; 2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB || 2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode == TGSI_OPCODE_TXF) { 2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TGSI stores LOD or LOD bias in the last channel of the coords. */ 2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_W; 2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, coord_dst, lod_info); 2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord_dst.writemask = WRITEMASK_XYZW; 2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode == TGSI_OPCODE_TXD) 2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, opcode, result_dst, coord, dx, dy); 2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (opcode == TGSI_OPCODE_TXQ) 2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, opcode, result_dst, lod_info); 2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (opcode == TGSI_OPCODE_TXF) { 2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, opcode, result_dst, coord); 2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = emit(ir, opcode, result_dst, coord); 2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->shadow_comparitor) 2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_shadow = GL_TRUE; 2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler, 2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->shader_program, 2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->prog); 2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->offset) { 2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offset_num_offset = 1; 2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offsets[0].Index = offset.index; 2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offsets[0].File = offset.file; 2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0); 2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1); 2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2); 2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (sampler_type->sampler_dimensionality) { 2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_1D: 2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = (sampler_type->sampler_array) 2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_2D: 2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = (sampler_type->sampler_array) 2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_3D: 2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_3D_INDEX; 2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_CUBE: 2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_CUBE_INDEX; 2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_RECT: 2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_RECT_INDEX; 2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_BUF: 2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"FINISHME: Implement ARB_texture_buffer_object"); 2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GLSL_SAMPLER_DIM_EXTERNAL: 2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_EXTERNAL_INDEX; 2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"Should not get here."); 2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result = result_src; 2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_return *ir) 2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->get_value()) { 2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg l; 2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(current_function); 2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->get_value()->accept(this); 2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg r = this->result; 2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l = st_dst_reg(current_function->return_reg); 2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < type_size(current_function->sig->return_type); i++) { 2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_MOV, l, r); 2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org l.index++; 2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r.index++; 2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_RET); 2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_discard *ir) 2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ir->condition) { 2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->condition->accept(this); 2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->result.negate = ~this->result.negate; 2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_KIL, undef_dst, this->result); 2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir, TGSI_OPCODE_KILP); 2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::visit(ir_if *ir) 2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *cond_inst, *if_inst; 2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *prev_inst; 2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prev_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir->condition->accept(this); 2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(this->result.file != PROGRAM_UNDEFINED); 2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (this->options->EmitCondCodes) { 2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond_inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail(); 2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* See if we actually generated any instruction for generating 2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the condition. If not, then cook up a move to a temp so we 2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have something to set cond_update on. 2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cond_inst == prev_inst) { 2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = get_temp(glsl_type::bool_type); 2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond_inst = emit(ir->condition, TGSI_OPCODE_MOV, st_dst_reg(temp), result); 2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cond_inst->cond_update = GL_TRUE; 2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_inst = emit(ir->condition, TGSI_OPCODE_IF); 2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_inst->dst.cond_mask = COND_NE; 2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result); 2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->instructions.push_tail(if_inst); 2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_exec_list(&ir->then_instructions, this); 2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ir->else_instructions.is_empty()) { 2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit(ir->condition, TGSI_OPCODE_ELSE); 2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_exec_list(&ir->else_instructions, this); 2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF); 2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::glsl_to_tgsi_visitor() 2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org result.file = PROGRAM_UNDEFINED; 2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_temp = 1; 2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next_signature_id = 1; 2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_immediates = 0; 2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org current_function = NULL; 2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_address_regs = 0; 2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org samplers_used = 0; 2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org indirect_addr_temps = false; 2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org indirect_addr_consts = false; 2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_version = 0; 2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org native_integers = false; 2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mem_ctx = ralloc_context(NULL); 2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx = NULL; 2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog = NULL; 2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_program = NULL; 2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options = NULL; 2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::~glsl_to_tgsi_visitor() 2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(mem_ctx); 2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void free_glsl_to_tgsi_visitor(glsl_to_tgsi_visitor *v) 2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete v; 2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Count resources used by the given gpu program (number of texture 2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * samplers, etc). 2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcount_resources(glsl_to_tgsi_visitor *v, gl_program *prog) 2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used = 0; 2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, v->instructions) { 2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (is_tex_instruction(inst->op)) { 2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used |= 1 << inst->sampler; 2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->tex_shadow) { 2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->ShadowSamplers |= 1 << inst->sampler; 2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->SamplersUsed = v->samplers_used; 2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (v->shader_program != NULL) 2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_update_shader_textures_used(v->shader_program, prog); 2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgset_uniform_initializer(struct gl_context *ctx, void *mem_ctx, 2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_program *shader_program, 2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *name, const glsl_type *type, 2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *val) 2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_record()) { 2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *field_constant; 2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_constant = (ir_constant *)val->components.get_head(); 2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < type->length; i++) { 2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *field_type = type->fields.structure[i].type; 2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, 2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type->fields.structure[i].name); 2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_type, field_constant); 2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org field_constant = (ir_constant *)field_constant->next; 2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned offset; 2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index = _mesa_get_uniform_location(ctx, shader_program, name, 2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &offset); 2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (offset == GL_INVALID_INDEX) { 2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail_link(shader_program, 2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Couldn't find uniform for initializer %s\n", name); 2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loc = _mesa_uniform_merge_location_offset(index, offset); 2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ir_constant *element; 2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_type *element_type; 2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type->is_array()) { 2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element = val->array_elements[i]; 2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type = type->fields.array; 2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element = val; 2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type = type; 2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *values; 2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (element_type->base_type == GLSL_TYPE_BOOL) { 2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int *conv = ralloc_array(mem_ctx, int, element_type->components()); 2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned int j = 0; j < element_type->components(); j++) { 2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org conv[j] = element->value.b[j]; 2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values = (void *)conv; 2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type = glsl_type::get_instance(GLSL_TYPE_INT, 2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type->vector_elements, 2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1); 2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values = &element->value; 2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (element_type->is_matrix()) { 2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_uniform_matrix(ctx, shader_program, 2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type->matrix_columns, 2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org element_type->vector_elements, 2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc, 1, GL_FALSE, (GLfloat *)values); 2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org values, element_type->gl_type); 2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loc++; 2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which 2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are read from the given src in this instruction 2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int 2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_src_arg_mask(st_dst_reg dst, st_src_reg src) 2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int read_mask = 0, comp; 2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now, given the src swizzle and the written channels, find which 2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * components are actually read 2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (comp = 0; comp < 4; ++comp) { 2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned coord = GET_SWZ(src.swizzle, comp); 2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(coord < 4); 2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst.writemask & (1 << comp) && coord <= SWIZZLE_W) 2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_mask |= 1 << coord; 3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return read_mask; 3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This pass replaces CMP T0, T1 T2 T0 with MOV T0, T2 when the CMP 3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction is the first instruction to write to register T0. There are 3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * several lowering passes done in GLSL IR (e.g. branches and 3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * relative addressing) that create a large number of conditional assignments 3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that ir_to_mesa converts to CMP instructions like the one mentioned above. 3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Here is why this conversion is safe: 3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CMP T0, T1 T2 T0 can be expanded to: 3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * if (T1 < 0.0) 3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV T0, T2; 3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * else 3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV T0, T0; 3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If (T1 < 0.0) evaluates to true then our replacement MOV T0, T2 is the same 3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the original program. If (T1 < 0.0) evaluates to false, executing 3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MOV T0, T0 will store a garbage value in T0 since T0 is uninitialized. 3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Therefore, it doesn't matter that we are replacing MOV T0, T0 with MOV T0, T2 3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * because any instruction that was going to read from T0 after this was going 3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to read a garbage value anyway. 3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::simplify_cmp(void) 3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned *tempWrites; 3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned outputWrites[MAX_PROGRAM_OUTPUTS]; 3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tempWrites = new unsigned[MAX_TEMPS]; 3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tempWrites) { 3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS); 3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(outputWrites, 0, sizeof(outputWrites)); 3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned prevWriteMask = 0; 3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Give up if we encounter relative addressing or flow control. */ 3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.reladdr || 3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_get_opcode_info(inst->op)->is_branch || 3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_BGNSUB || 3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_CONT || 3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_END || 3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_ENDSUB || 3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_RET) { 3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_OUTPUT) { 3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->dst.index < MAX_PROGRAM_OUTPUTS); 3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prevWriteMask = outputWrites[inst->dst.index]; 3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputWrites[inst->dst.index] |= inst->dst.writemask; 3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->dst.file == PROGRAM_TEMPORARY) { 3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->dst.index < MAX_TEMPS); 3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prevWriteMask = tempWrites[inst->dst.index]; 3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tempWrites[inst->dst.index] |= inst->dst.writemask; 3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For a CMP to be considered a conditional write, the destination 3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register and source register two must be the same. */ 3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_CMP 3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && !(inst->dst.writemask & prevWriteMask) 3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && inst->src[2].file == inst->dst.file 3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && inst->src[2].index == inst->dst.index 3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org && inst->dst.writemask == get_src_arg_mask(inst->dst, inst->src[2])) { 3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op = TGSI_OPCODE_MOV; 3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[0] = inst->src[1]; 3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete [] tempWrites; 3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Replaces all references to a temporary register index with another index. */ 3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::rename_temp_register(int index, int new_index) 3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned j; 3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j=0; j < num_inst_src_regs(inst->op); j++) { 3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->src[j].file == PROGRAM_TEMPORARY && 3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[j].index == index) { 3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[j].index = new_index; 3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.index = new_index; 3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_first_temp_read(int index) 3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int depth = 0; /* loop depth */ 3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i = 0, j; 3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j=0; j < num_inst_src_regs(inst->op); j++) { 3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->src[j].file == PROGRAM_TEMPORARY && 3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[j].index == index) { 3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (depth == 0) ? i : loop_start; 3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_BGNLOOP) { 3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(depth++ == 0) 3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop_start = i; 3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (--depth == 0) 3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop_start = -1; 3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(depth >= 0); 3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i++; 3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_first_temp_write(int index) 3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int depth = 0; /* loop depth */ 3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int loop_start = -1; /* index of the first active BGNLOOP (if any) */ 3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i = 0; 3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) { 3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (depth == 0) ? i : loop_start; 3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_BGNLOOP) { 3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(depth++ == 0) 3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop_start = i; 3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->op == TGSI_OPCODE_ENDLOOP) { 3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (--depth == 0) 3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org loop_start = -1; 3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(depth >= 0); 3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i++; 3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return -1; 3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_last_temp_read(int index) 3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int depth = 0; /* loop depth */ 3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int last = -1; /* index of last instruction that reads the temporary */ 3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i = 0, j; 3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j=0; j < num_inst_src_regs(inst->op); j++) { 3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->src[j].file == PROGRAM_TEMPORARY && 3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[j].index == index) { 3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last = (depth == 0) ? i : -2; 3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_BGNLOOP) 3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth++; 3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (inst->op == TGSI_OPCODE_ENDLOOP) 3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (--depth == 0 && last == -2) 3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last = i; 3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(depth >= 0); 3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i++; 3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(last >= -1); 3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return last; 3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::get_last_temp_write(int index) 3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int depth = 0; /* loop depth */ 3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int last = -1; /* index of last instruction that writes to the temporary */ 3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i = 0; 3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) 3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last = (depth == 0) ? i : -2; 3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_BGNLOOP) 3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth++; 3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (inst->op == TGSI_OPCODE_ENDLOOP) 3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (--depth == 0 && last == -2) 3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last = i; 3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(depth >= 0); 3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i++; 3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(last >= -1); 3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return last; 3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * On a basic block basis, tracks available PROGRAM_TEMPORARY register 3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * channels for copy propagation and updates following instructions to 3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * use the original versions. 3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur. As an example, a TXP production before this pass: 3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy; 3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww; 3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], TEMP[1], texture[0], 2D; 3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and after: 3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy; 3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww; 3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * which allows for dead code elimination on TEMP[1]'s writes. 3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::copy_propagate(void) 3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction **acp = rzalloc_array(mem_ctx, 3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *, 3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp * 4); 3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int level = 0; 3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->dst.file != PROGRAM_TEMPORARY 3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || inst->dst.index < this->next_temp); 3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* First, do any copy propagation possible into the src regs. */ 3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < 3; r++) { 3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *first = NULL; 3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool good = true; 3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int acp_base = inst->src[r].index * 4; 3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->src[r].file != PROGRAM_TEMPORARY || 3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[r].reladdr) 3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* See if we can find entries in the ACP consisting of MOVs 3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from the same src register for all the swizzled channels 3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of this src register reference. 3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i = 0; i < 4; i++) { 3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *copy_chan = acp[acp_base + src_chan]; 3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!copy_chan) { 3274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org good = false; 3275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(acp_level[acp_base + src_chan] <= level); 3279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!first) { 3281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first = copy_chan; 3282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 3283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first->src[0].file != copy_chan->src[0].file || 3284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first->src[0].index != copy_chan->src[0].index) { 3285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org good = false; 3286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (good) { 3292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We've now validated that we can copy-propagate to 3293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * replace this src register reference. Do it. 3294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[r].file = first->src[0].file; 3296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[r].index = first->src[0].index; 3297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int swizzle = 0; 3299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i = 0; i < 4; i++) { 3300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int src_chan = GET_SWZ(inst->src[r].swizzle, i); 3301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *copy_inst = acp[acp_base + src_chan]; 3302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle |= (GET_SWZ(copy_inst->src[0].swizzle, src_chan) << 3303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (3 * i)); 3304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->src[r].swizzle = swizzle; 3306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (inst->op) { 3310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_BGNLOOP: 3311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ENDLOOP: 3312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* End of a basic block, clear the ACP entirely. */ 3313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_IF: 3317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++level; 3318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ENDIF: 3321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ELSE: 3322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Clear all channels written inside the block from the ACP, but 3323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * leaving those that were not touched. 3324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < this->next_temp; r++) { 3326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!acp[4 * r + c]) 3328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (acp_level[4 * r + c] >= level) 3331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * r + c] = NULL; 3332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_ENDIF) 3335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --level; 3336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 3339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Continuing the block, clear any written channels from 3340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the ACP. 3341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.reladdr) { 3343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Any temporary might be written, so no copy propagation 3344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * across this instruction. 3345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(acp, 0, sizeof(*acp) * this->next_temp * 4); 3347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->dst.file == PROGRAM_OUTPUT && 3348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.reladdr) { 3349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Any output might be written, so no copy propagation 3350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * from outputs across this instruction. 3351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < this->next_temp; r++) { 3353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!acp[4 * r + c]) 3355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (acp[4 * r + c]->src[0].file == PROGRAM_OUTPUT) 3358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * r + c] = NULL; 3359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->dst.file == PROGRAM_TEMPORARY || 3362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.file == PROGRAM_OUTPUT) { 3363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Clear where it's used as dst. */ 3364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY) { 3365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.writemask & (1 << c)) { 3367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * inst->dst.index + c] = NULL; 3368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Clear where it's used as src. */ 3373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < this->next_temp; r++) { 3374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!acp[4 * r + c]) 3376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int src_chan = GET_SWZ(acp[4 * r + c]->src[0].swizzle, c); 3379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (acp[4 * r + c]->src[0].file == inst->dst.file && 3381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * r + c]->src[0].index == inst->dst.index && 3382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask & (1 << src_chan)) 3383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 3384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * r + c] = NULL; 3385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If this is a copy, add it to the ACP. */ 3393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->op == TGSI_OPCODE_MOV && 3394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.file == PROGRAM_TEMPORARY && 3395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->dst.reladdr && 3396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->saturate && 3397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->src[0].reladdr && 3398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->src[0].negate) { 3399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i = 0; i < 4; i++) { 3400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.writemask & (1 << i)) { 3401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp[4 * inst->dst.index + i] = inst; 3402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org acp_level[4 * inst->dst.index + i] = level; 3403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(acp_level); 3409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(acp); 3410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 3413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Tracks available PROGRAM_TEMPORARY registers for dead code elimination. 3414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur. As an example, a TXP production after copy propagation but 3417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * before this pass: 3418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: MOV TEMP[1], INPUT[4].xyyy; 3420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1: MOV TEMP[1].w, INPUT[4].wwww; 3421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and after this pass: 3424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 0: TXP TEMP[2], INPUT[4].xyyw, texture[0], 2D; 3426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FIXME: assumes that all functions are inlined (no support for BGNSUB/ENDSUB) 3428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FIXME: doesn't eliminate all dead code inside of loops; it steps around them 3429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::eliminate_dead_code(void) 3432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 3434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < this->next_temp; i++) { 3436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int last_read = get_last_temp_read(i); 3437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int j = 0; 3438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i && 3443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org j > last_read) 3444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 3445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.remove(); 3446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete inst; 3447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org j++; 3450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 3455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * On a basic block basis, tracks available PROGRAM_TEMPORARY registers for dead 3456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code elimination. This is less primitive than eliminate_dead_code(), as it 3457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is per-channel and can detect consecutive writes without a read between them 3458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as dead code. However, there is some dead code that can be eliminated by 3459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * eliminate_dead_code() but not this function - for example, this function 3460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cannot eliminate an instruction writing to a register that is never read and 3461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is the only instruction writing to that register. 3462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The glsl_to_tgsi_visitor lazily produces code assuming that this pass 3464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will occur. 3465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint 3467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::eliminate_dead_code_advanced(void) 3468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction **writes = rzalloc_array(mem_ctx, 3470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *, 3471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp * 4); 3472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int *write_level = rzalloc_array(mem_ctx, int, this->next_temp * 4); 3473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int level = 0; 3474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int removed = 0; 3475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(inst->dst.file != PROGRAM_TEMPORARY 3480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || inst->dst.index < this->next_temp); 3481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (inst->op) { 3483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_BGNLOOP: 3484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ENDLOOP: 3485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_CONT: 3486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_BRK: 3487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* End of a basic block, clear the write array entirely. 3488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This keeps us from killing dead code when the writes are 3490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on either side of a loop, even when the register isn't touched 3491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inside the loop. However, glsl_to_tgsi_visitor doesn't seem to emit 3492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * dead code of this type, so it shouldn't make a difference as long as 3493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the dead code elimination pass in the GLSL compiler does its job. 3494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 3496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ENDIF: 3499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ELSE: 3500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Promote the recorded level of all channels written inside the 3501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * preceding if or else block to the level above the if/else block. 3502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < this->next_temp; r++) { 3504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!writes[4 * r + c]) 3506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (write_level[4 * r + c] == level) 3509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org write_level[4 * r + c] = level-1; 3510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(inst->op == TGSI_OPCODE_ENDIF) 3514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org --level; 3515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_IF: 3519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++level; 3520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* fallthrough to default case to mark the condition as read */ 3521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 3523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Continuing the block, clear any channels from the write array that 3524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * are read by this instruction. 3525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < Elements(inst->src); i++) { 3527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->src[i].file == PROGRAM_TEMPORARY && inst->src[i].reladdr){ 3528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Any temporary might be read, so no dead code elimination 3529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * across this instruction. 3530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(writes, 0, sizeof(*writes) * this->next_temp * 4); 3532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (inst->src[i].file == PROGRAM_TEMPORARY) { 3533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Clear where it's used as src. */ 3534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int src_chans = 1 << GET_SWZ(inst->src[i].swizzle, 0); 3535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 1); 3536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 2); 3537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_chans |= 1 << GET_SWZ(inst->src[i].swizzle, 3); 3538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_chans & (1 << c)) { 3541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writes[4 * inst->src[i].index + c] = NULL; 3542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 3547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If this instruction writes to a temporary, add it to the write array. 3550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If there is already an instruction in the write array for one or more 3551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the channels, flag that channel write as dead. 3552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_TEMPORARY && 3554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->dst.reladdr && 3555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !inst->saturate) { 3556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.writemask & (1 << c)) { 3558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (writes[4 * inst->dst.index + c]) { 3559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (write_level[4 * inst->dst.index + c] < level) 3560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 3562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writes[4 * inst->dst.index + c]->dead_mask |= (1 << c); 3563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org writes[4 * inst->dst.index + c] = inst; 3565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org write_level[4 * inst->dst.index + c] = level; 3566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Anything still in the write array at this point is dead code. */ 3572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int r = 0; r < this->next_temp; r++) { 3573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int c = 0; c < 4; c++) { 3574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = writes[4 * r + c]; 3575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst) 3576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dead_mask |= (1 << c); 3577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now actually remove the instructions that are completely dead and update 3581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the writemask of other instructions with dead channels. 3582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, this->instructions) { 3584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!inst->dead_mask || !inst->dst.writemask) 3587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 3588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((inst->dst.writemask & ~inst->dead_mask) == 0) { 3589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org iter.remove(); 3590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete inst; 3591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org removed++; 3592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else 3593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->dst.writemask &= ~(inst->dead_mask); 3594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(write_level); 3597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(writes); 3598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return removed; 3600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Merges temporary registers together where possible to reduce the number of 3603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * registers needed to run a program. 3604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Produces optimal code only after copy propagation and dead code elimination 3606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * have been run. */ 3607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::merge_registers(void) 3609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int *last_reads = rzalloc_array(mem_ctx, int, this->next_temp); 3611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int *first_writes = rzalloc_array(mem_ctx, int, this->next_temp); 3612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i, j; 3613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Read the indices of the last read and first write to each temp register 3615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * into an array so that we don't have to traverse the instruction list as 3616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * much. */ 3617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < this->next_temp; i++) { 3618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last_reads[i] = get_last_temp_read(i); 3619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_writes[i] = get_first_temp_write(i); 3620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Start looking for registers with non-overlapping usages that can be 3623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * merged together. */ 3624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < this->next_temp; i++) { 3625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Don't touch unused registers. */ 3626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (last_reads[i] < 0 || first_writes[i] < 0) continue; 3627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j=0; j < this->next_temp; j++) { 3629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Don't touch unused registers. */ 3630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (last_reads[j] < 0 || first_writes[j] < 0) continue; 3631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We can merge the two registers if the first write to j is after or 3633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in the same instruction as the last read from i. Note that the 3634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register at index i will always be used earlier or at the same time 3635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * as the register at index j. */ 3636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first_writes[i] <= first_writes[j] && 3637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last_reads[i] <= first_writes[j]) 3638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 3639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rename_temp_register(j, i); /* Replace all references to j with i.*/ 3640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Update the first_writes and last_reads arrays with the new 3642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * values for the merged register index, and mark the newly unused 3643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register index as such. */ 3644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last_reads[i] = last_reads[j]; 3645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_writes[j] = -1; 3646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last_reads[j] = -1; 3647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(last_reads); 3652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ralloc_free(first_writes); 3653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Reassign indices to temporary registers by reusing unused indices created 3656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by optimization passes. */ 3657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 3658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgglsl_to_tgsi_visitor::renumber_registers(void) 3659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i = 0; 3661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int new_index = 0; 3662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < this->next_temp; i++) { 3664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (get_first_temp_read(i) < 0) continue; 3665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (i != new_index) 3666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rename_temp_register(i, new_index); 3667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_index++; 3668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org this->next_temp = new_index; 3671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Returns a fragment program which implements the current pixel transfer ops. 3675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on get_pixel_transfer_program in st_atom_pixeltransfer.c. 3676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void 3678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_pixel_transfer_visitor(struct st_fragment_program *fp, 3679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor *original, 3680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int scale_and_bias, int pixel_maps) 3681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 3683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_context *st = st_context(original->ctx); 3684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program *prog = &fp->Base.Base; 3685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program_parameter_list *params = _mesa_new_parameter_list(); 3686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg coord, src0; 3687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst0; 3688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst; 3689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 3691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->ctx = original->ctx; 3692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->prog = prog; 3693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->shader_program = NULL; 3694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->glsl_version = original->glsl_version; 3695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->native_integers = original->native_integers; 3696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->options = original->options; 3697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->next_temp = original->next_temp; 3698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->num_address_regs = original->num_address_regs; 3699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used = prog->SamplersUsed = original->samplers_used; 3700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->indirect_addr_temps = original->indirect_addr_temps; 3701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->indirect_addr_consts = original->indirect_addr_consts; 3702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->num_immediates = original->num_immediates; 3704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 3706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get initial pixel color from the texture. 3707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; 3708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 3710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0 = v->get_temp(glsl_type::vec4_type); 3711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst0 = st_dst_reg(src0); 3712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 3713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->sampler = 0; 3714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_2D_INDEX; 3715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->InputsRead |= FRAG_BIT_TEX0; 3717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->SamplersUsed |= (1 << 0); /* mark sampler 0 as used */ 3718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used |= (1 << 0); 3719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (scale_and_bias) { 3721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const gl_state_index scale_state[STATE_LENGTH] = 3722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { STATE_INTERNAL, STATE_PT_SCALE, 3723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const gl_state_index bias_state[STATE_LENGTH] = 3725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { STATE_INTERNAL, STATE_PT_BIAS, 3726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (gl_state_index) 0, (gl_state_index) 0, (gl_state_index) 0 }; 3727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint scale_p, bias_p; 3728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg scale, bias; 3729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scale_p = _mesa_add_state_reference(params, scale_state); 3731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bias_p = _mesa_add_state_reference(params, bias_state); 3732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MAD colorTemp, colorTemp, scale, bias; */ 3734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scale = st_src_reg(PROGRAM_STATE_VAR, scale_p, GLSL_TYPE_FLOAT); 3735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bias = st_src_reg(PROGRAM_STATE_VAR, bias_p, GLSL_TYPE_FLOAT); 3736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_MAD, dst0, src0, scale, bias); 3737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pixel_maps) { 3740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg temp = v->get_temp(glsl_type::vec4_type); 3741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg temp_dst = st_dst_reg(temp); 3742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(st->pixel_xfer.pixelmap_texture); 3744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* With a little effort, we can do four pixel map look-ups with 3746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * two TEX instructions: 3747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ 3750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_XY; /* write R,G */ 3751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->sampler = 1; 3753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_2D_INDEX; 3754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ 3756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0.swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W); 3757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org temp_dst.writemask = WRITEMASK_ZW; /* write B,A */ 3758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_TEX, temp_dst, src0); 3759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->sampler = 1; 3760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_2D_INDEX; 3761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->SamplersUsed |= (1 << 1); /* mark sampler 1 as used */ 3763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used |= (1 << 1); 3764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MOV colorTemp, temp; */ 3766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_MOV, dst0, temp); 3767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 3770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new visitor. */ 3771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, original->instructions) { 3772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *newinst; 3774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src_regs[3]; 3775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_OUTPUT) 3777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 3778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i=0; i<3; i++) { 3780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_regs[i] = inst->src[i]; 3781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_regs[i].file == PROGRAM_INPUT && 3782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_regs[i].index == FRAG_ATTRIB_COL0) 3783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 3784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_regs[i].file = PROGRAM_TEMPORARY; 3785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_regs[i].index = src0.index; 3786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (src_regs[i].file == PROGRAM_INPUT) 3788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 3789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 3792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newinst->tex_target = inst->tex_target; 3793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make modifications to fragment program info. */ 3796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->Parameters = _mesa_combine_parameter_lists(params, 3797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org original->prog->Parameters); 3798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_free_parameter_list(params); 3799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count_resources(v, prog); 3800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fp->glsl_to_tgsi = v; 3801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Make fragment program for glBitmap: 3805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Sample the texture and kill the fragment if the bit is 0. 3806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This program will be combined with the user's fragment program. 3807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Based on make_bitmap_fragment_program in st_cb_bitmap.c. 3809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" void 3811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_bitmap_visitor(struct st_fragment_program *fp, 3812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor *original, int samplerIndex) 3813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor *v = new glsl_to_tgsi_visitor(); 3815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_context *st = st_context(original->ctx); 3816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program *prog = &fp->Base.Base; 3817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg coord, src0; 3818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_dst_reg dst0; 3819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst; 3820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Copy attributes of the glsl_to_tgsi_visitor in the original shader. */ 3822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->ctx = original->ctx; 3823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->prog = prog; 3824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->shader_program = NULL; 3825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->glsl_version = original->glsl_version; 3826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->native_integers = original->native_integers; 3827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->options = original->options; 3828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->next_temp = original->next_temp; 3829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->num_address_regs = original->num_address_regs; 3830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used = prog->SamplersUsed = original->samplers_used; 3831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->indirect_addr_temps = original->indirect_addr_temps; 3832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->indirect_addr_consts = original->indirect_addr_consts; 3833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&v->immediates, &original->immediates, sizeof(v->immediates)); 3834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->num_immediates = original->num_immediates; 3835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */ 3837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org coord = st_src_reg(PROGRAM_INPUT, FRAG_ATTRIB_TEX0, glsl_type::vec2_type); 3838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0 = v->get_temp(glsl_type::vec4_type); 3839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst0 = st_dst_reg(src0); 3840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_TEX, dst0, coord); 3841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->sampler = samplerIndex; 3842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->tex_target = TEXTURE_2D_INDEX; 3843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->InputsRead |= FRAG_BIT_TEX0; 3845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->SamplersUsed |= (1 << samplerIndex); /* mark sampler as used */ 3846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->samplers_used |= (1 << samplerIndex); 3847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ 3849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0.negate = NEGATE_XYZW; 3850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (st->bitmap.tex_format == PIPE_FORMAT_L8_UNORM) 3851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src0.swizzle = SWIZZLE_XXXX; 3852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = v->emit(NULL, TGSI_OPCODE_KIL, undef_dst, src0); 3853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now copy the instructions from the original glsl_to_tgsi_visitor into the 3855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new visitor. */ 3856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, original->instructions) { 3857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get(); 3858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *newinst; 3859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_src_reg src_regs[3]; 3860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->dst.file == PROGRAM_OUTPUT) 3862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->OutputsWritten |= BITFIELD64_BIT(inst->dst.index); 3863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (int i=0; i<3; i++) { 3865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_regs[i] = inst->src[i]; 3866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_regs[i].file == PROGRAM_INPUT) 3867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->InputsRead |= BITFIELD64_BIT(src_regs[i].index); 3868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newinst = v->emit(NULL, inst->op, inst->dst, src_regs[0], src_regs[1], src_regs[2]); 3871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newinst->tex_target = inst->tex_target; 3872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make modifications to fragment program info. */ 3875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->Parameters = _mesa_clone_parameter_list(original->prog->Parameters); 3876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count_resources(v, prog); 3877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fp->glsl_to_tgsi = v; 3878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* ------------------------- TGSI conversion stuff -------------------------- */ 3881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct label { 3882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned branch_target; 3883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned token; 3884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 3885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Intermediate state used during shader translation. 3888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct st_translate { 3890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg; 3891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst temps[MAX_TEMPS]; 3893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src *constants; 3894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src *immediates; 3895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; 3896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; 3897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst address[1]; 3898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src samplers[PIPE_MAX_SAMPLERS]; 3899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src systemValues[SYSTEM_VALUE_MAX]; 3900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint *inputMapping; 3902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint *outputMapping; 3903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For every instruction that contains a label (eg CALL), keep 3905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * details so that we can go back afterwards and emit the correct 3906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * tgsi instruction number for each label. 3907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct label *labels; 3909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned labels_size; 3910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned labels_count; 3911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Keep a record of the tgsi instruction number that each mesa 3913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instruction starts at, will be used to fix up labels after 3914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * translation. 3915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned *insn; 3917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned insn_size; 3918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned insn_count; 3919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ 3921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean error; 3923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 3924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ 3926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { 3927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_FACE, 3928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_VERTEXID, 3929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_INSTANCEID 3930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 3931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Make note of a branch to a label in the TGSI code. 3934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * After we've emitted all instructions, we'll go over the list 3935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of labels built here and patch the TGSI code with the actual 3936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * location of each label. 3937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned *get_label(struct st_translate *t, unsigned branch_target) 3939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 3941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->labels_count + 1 >= t->labels_size) { 3943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); 3944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->labels = (struct label *)realloc(t->labels, 3945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->labels_size * sizeof(struct label)); 3946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->labels == NULL) { 3947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static unsigned dummy; 3948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->error = TRUE; 3949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &dummy; 3950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i = t->labels_count++; 3954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->labels[i].branch_target = branch_target; 3955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &t->labels[i].token; 3956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called prior to emitting the TGSI code for each instruction. 3960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate additional space for instructions if needed. 3961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Update the insn[] array so the next glsl_to_tgsi_instruction points to 3962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the next TGSI instruction. 3963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void set_insn_start(struct st_translate *t, unsigned start) 3965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->insn_count + 1 >= t->insn_size) { 3967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); 3968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->insn = (unsigned *)realloc(t->insn, t->insn_size * sizeof(t->insn[0])); 3969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->insn == NULL) { 3970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->error = TRUE; 3971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 3972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 3974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->insn[t->insn_count++] = start; 3976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 3977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 3979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi constant/immediate to a TGSI immediate. 3980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 3981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src 3982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_immediate(struct st_translate *t, 3983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_constant_value values[4], 3984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int type, int size) 3985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 3986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg = t->ureg; 3987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 3988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(type) 3989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 3990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FLOAT: 3991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_DECL_immediate(ureg, &values[0].f, size); 3992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_INT: 3993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_DECL_immediate_int(ureg, &values[0].i, size); 3994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_UNSIGNED_INT: 3995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_BOOL: 3996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_DECL_immediate_uint(ureg, &values[0].u, size); 3997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 3998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"should not get here - type must be float, int, uint, or bool"); 3999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src_undef(); 4000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi dst register to a TGSI ureg_dst register. 4005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_dst 4007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdst_register(struct st_translate *t, 4008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file, 4009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint index) 4010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(file) { 4012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNDEFINED: 4013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_dst_undef(); 4014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 4016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ureg_dst_is_undef(t->temps[index])) 4017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->temps[index] = ureg_DECL_local_temporary(t->ureg); 4018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->temps[index]; 4020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_OUTPUT: 4022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->procType == TGSI_PROCESSOR_VERTEX) 4023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < VERT_RESULT_MAX); 4024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (t->procType == TGSI_PROCESSOR_FRAGMENT) 4025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < FRAG_RESULT_MAX); 4026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < GEOM_RESULT_MAX); 4028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(t->outputMapping[index] < Elements(t->outputs)); 4030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->outputs[t->outputMapping[index]]; 4032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ADDRESS: 4034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->address[index]; 4035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"unknown dst register file"); 4038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_dst_undef(); 4039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a glsl_to_tgsi src register to a TGSI ureg_src register. 4044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src 4046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsrc_register(struct st_translate *t, 4047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org gl_register_file file, 4048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint index) 4049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(file) { 4051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNDEFINED: 4052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src_undef(); 4053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_TEMPORARY: 4055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index >= 0); 4056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < (int) Elements(t->temps)); 4057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ureg_dst_is_undef(t->temps[index])) 4058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->temps[index] = ureg_DECL_local_temporary(t->ureg); 4059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src(t->temps[index]); 4060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_NAMED_PARAM: 4062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ENV_PARAM: 4063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_LOCAL_PARAM: 4064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNIFORM: 4065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index >= 0); 4066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->constants[index]; 4067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_STATE_VAR: 4068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_CONSTANT: /* ie, immediate */ 4069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (index < 0) 4070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_DECL_constant(t->ureg, 0); 4071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->constants[index]; 4073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_IMMEDIATE: 4075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->immediates[index]; 4076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_INPUT: 4078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(t->inputMapping[index] < Elements(t->inputs)); 4079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->inputs[t->inputMapping[index]]; 4080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_OUTPUT: 4082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(t->outputMapping[index] < Elements(t->outputs)); 4083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ 4084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ADDRESS: 4086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src(t->address[index]); 4087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_SYSTEM_VALUE: 4089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < (int) Elements(t->systemValues)); 4090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return t->systemValues[index]; 4091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"unknown src register file"); 4094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ureg_src_undef(); 4095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create a TGSI ureg_dst register from an st_dst_reg. 4100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_dst 4102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_dst(struct st_translate *t, 4103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const st_dst_reg *dst_reg, 4104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool saturate, bool clamp_color) 4105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst dst = dst_register(t, 4107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_reg->file, 4108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_reg->index); 4109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = ureg_writemask(dst, dst_reg->writemask); 4111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (saturate) 4113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = ureg_saturate(dst); 4114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (clamp_color && dst_reg->file == PROGRAM_OUTPUT) { 4115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Clamp colors for ARB_color_buffer_float. */ 4116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (t->procType) { 4117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_PROCESSOR_VERTEX: 4118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX if the geometry shader is present, this must be done there 4119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * instead of here. */ 4120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst_reg->index == VERT_RESULT_COL0 || 4121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_reg->index == VERT_RESULT_COL1 || 4122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_reg->index == VERT_RESULT_BFC0 || 4123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst_reg->index == VERT_RESULT_BFC1) { 4124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = ureg_saturate(dst); 4125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_PROCESSOR_FRAGMENT: 4129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst_reg->index >= FRAG_RESULT_COLOR) { 4130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = ureg_saturate(dst); 4131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst_reg->reladdr != NULL) 4137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst = ureg_dst_indirect(dst, ureg_src(t->address[0])); 4138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return dst; 4140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create a TGSI ureg_src register from an st_src_reg. 4144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct ureg_src 4146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_src(struct st_translate *t, const st_src_reg *src_reg) 4147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src src = src_register(t, src_reg->file, src_reg->index); 4149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = ureg_swizzle(src, 4151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src_reg->swizzle, 0) & 0x3, 4152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src_reg->swizzle, 1) & 0x3, 4153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src_reg->swizzle, 2) & 0x3, 4154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GET_SWZ(src_reg->swizzle, 3) & 0x3); 4155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((src_reg->negate & 0xf) == NEGATE_XYZW) 4157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src = ureg_negate(src); 4158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_reg->reladdr != NULL) { 4160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Normally ureg_src_indirect() would be used here, but a stupid compiler 4161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * bug in g++ makes ureg_src_indirect (an inline C function) erroneously 4162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * set the bit for src.Negate. So we have to do the operation manually 4163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * here to work around the compiler's problems. */ 4164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/ 4165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src addr = ureg_src(t->address[0]); 4166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.Indirect = 1; 4167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.IndirectFile = addr.File; 4168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.IndirectIndex = addr.Index; 4169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.IndirectSwizzle = addr.SwizzleX; 4170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (src_reg->file != PROGRAM_INPUT && 4172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src_reg->file != PROGRAM_OUTPUT) { 4173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If src_reg->index was negative, it was set to zero in 4174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * src_register(). Reassign it now. But don't do this 4175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for input/output regs since they get remapped while 4176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * const buffers don't. 4177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src.Index = src_reg->index; 4179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return src; 4183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct tgsi_texture_offset 4186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtranslate_tex_offset(struct st_translate *t, 4187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_texture_offset *in_offset) 4188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_texture_offset offset; 4190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(in_offset->File == PROGRAM_IMMEDIATE); 4192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.File = TGSI_FILE_IMMEDIATE; 4194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.Index = in_offset->Index; 4195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.SwizzleX = in_offset->SwizzleX; 4196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.SwizzleY = in_offset->SwizzleY; 4197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.SwizzleZ = in_offset->SwizzleZ; 4198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset.Padding = 0; 4199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return offset; 4201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcompile_tgsi_instruction(struct st_translate *t, 4205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const glsl_to_tgsi_instruction *inst, 4206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool clamp_dst_color_output) 4207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg = t->ureg; 4209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 4210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst dst[1]; 4211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src src[4]; 4212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET]; 4213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_dst; 4215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_src; 4216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_dst = num_inst_dst_regs(inst->op); 4218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_src = num_inst_src_regs(inst->op); 4219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (num_dst) 4221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[0] = translate_dst(t, 4222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &inst->dst, 4223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->saturate, 4224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clamp_dst_color_output); 4225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < num_src; i++) 4227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src[i] = translate_src(t, &inst->src[i]); 4228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch(inst->op) { 4230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_BGNLOOP: 4231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_CAL: 4232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ELSE: 4233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ENDLOOP: 4234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_IF: 4235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(num_dst == 0); 4236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_label_insn(ureg, 4237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op, 4238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src, num_src, 4239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org get_label(t, 4240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op == TGSI_OPCODE_CAL ? inst->function->sig_id : 0)); 4241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 4242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TEX: 4244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXB: 4245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXD: 4246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXL: 4247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXP: 4248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXQ: 4249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_TXF: 4250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src[num_src++] = t->samplers[inst->sampler]; 4251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < inst->tex_offset_num_offset; i++) { 4252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]); 4253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_tex_insn(ureg, 4255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op, 4256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst, num_dst, 4257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org st_translate_texture_target(inst->tex_target, inst->tex_shadow), 4258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org texoffsets, inst->tex_offset_num_offset, 4259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src, num_src); 4260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 4261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_SCS: 4263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY); 4264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_insn(ureg, inst->op, dst, num_dst, src, num_src); 4265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_insn(ureg, 4269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->op, 4270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst, num_dst, 4271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org src, num_src); 4272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit the TGSI instructions for inverting and adjusting WPOS. 4278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This code is unavoidable because it also depends on whether 4279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). 4280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_wpos_adjustment( struct st_translate *t, 4283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program *program, 4284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean invert, 4285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat adjX, GLfloat adjY[2]) 4286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg = t->ureg; 4288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fragment program uses fragment position input. 4290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Need to replace instances of INPUT[WPOS] with temp T 4291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * where T = INPUT[WPOS] by y is inverted. 4292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const gl_state_index wposTransformState[STATE_LENGTH] 4294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 4295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (gl_state_index)0, (gl_state_index)0, (gl_state_index)0 }; 4296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX: note we are modifying the incoming shader here! Need to 4298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * do this before emitting the constant decls below, or this 4299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * will be missed: 4300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, 4302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wposTransformState); 4303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); 4305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); 4306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 4307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* First, apply the coordinate shift: */ 4309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (adjX || adjY[0] || adjY[1]) { 4310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (adjY[0] != adjY[1]) { 4311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Adjust the y coordinate by adjY[1] or adjY[0] respectively 4312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * depending on whether inversion is actually going to be applied 4313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or not, which is determined by testing against the inversion 4314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * state variable used below, which will be either +1 or -1. 4315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst adj_temp = ureg_DECL_local_temporary(ureg); 4317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_CMP(ureg, adj_temp, 4319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_scalar(wpostrans, invert ? 2 : 0), 4320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f), 4321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f)); 4322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp)); 4323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 4324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_ADD(ureg, wpos_temp, wpos_input, 4325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f)); 4326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wpos_input = ureg_src(wpos_temp); 4328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 4329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MOV wpos_temp, input[wpos] 4330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_MOV( ureg, wpos_temp, wpos_input ); 4332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be 4335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inversion/identity, or the other way around if we're drawing to an FBO. 4336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (invert) { 4338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy 4339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_MAD( ureg, 4341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 4342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wpos_input, 4343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_scalar(wpostrans, 0), 4344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_scalar(wpostrans, 1)); 4345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 4346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww 4347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_MAD( ureg, 4349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 4350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wpos_input, 4351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_scalar(wpostrans, 2), 4352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_scalar(wpostrans, 3)); 4353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Use wpos_temp as position input from here on: 4356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 4358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Emit fragment position/ooordinate code. 4363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_wpos(struct st_context *st, 4366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_translate *t, 4367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program *program, 4368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg) 4369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_fragment_program *fp = 4371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (const struct gl_fragment_program *) program; 4372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_screen *pscreen = st->pipe->screen; 4373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat adjX = 0.0f; 4374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat adjY[2] = { 0.0f, 0.0f }; 4375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean invert = FALSE; 4376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Query the pixel center conventions supported by the pipe driver and set 4378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * adjX, adjY to help out if it cannot handle the requested one internally. 4379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The bias of the y-coordinate depends on whether y-inversion takes place 4381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are 4382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * drawing to an FBO (causes additional inversion), and whether the the pipe 4383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * driver origin and the requested origin differ (the latter condition is 4384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * stored in the 'invert' variable). 4385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * For height = 100 (i = integer, h = half-integer, l = lower, u = upper): 4387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * center shift only: 4389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * i -> h: +0.5 4390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * h -> i: -0.5 4391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inversion only: 4393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99 4394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5 4395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0 4396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5 4397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inversion and center shift: 4399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5 4400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99 4401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5 4402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 4403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fp->OriginUpperLeft) { 4405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fragment shader wants origin in upper-left */ 4406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { 4407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports upper-left origin */ 4408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { 4410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports lower-left origin, need to invert Y */ 4411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org invert = TRUE; 4413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 4416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 4418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fragment shader wants origin in lower-left */ 4419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) 4420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports lower-left origin */ 4421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 4422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) 4423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports upper-left origin, need to invert Y */ 4424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org invert = TRUE; 4425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 4427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (fp->PixelCenterInteger) { 4430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fragment shader wants pixel center integer */ 4431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports pixel center integer */ 4433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjY[1] = 1.0f; 4434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 4435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports pixel center half integer, need to bias X,Y */ 4438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjX = -0.5f; 4439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjY[0] = -0.5f; 4440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjY[1] = 0.5f; 4441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 4444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 4446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fragment shader wants pixel center half integer */ 4447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 4448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports pixel center half integer */ 4449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 4451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* the driver supports pixel center integer, need to bias X,Y */ 4452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org adjX = adjY[0] = adjY[1] = 0.5f; 4453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 4454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 4457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we invert after adjustment so that we avoid the MOV to temporary, 4460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and reuse the adjustment ADD instead */ 4461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_wpos_adjustment(t, program, invert, adjX, adjY); 4462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. 4466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TGSI uses +1 for front, -1 for back. 4467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function converts the TGSI value to the GL value. Simply clamping/ 4468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * saturating the value to [0,1] does the job. 4469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_face_var(struct st_translate *t) 4472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg = t->ureg; 4474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst face_temp = ureg_DECL_temporary(ureg); 4475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; 4476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MOV_SAT face_temp, input[face] */ 4478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org face_temp = ureg_saturate(face_temp); 4479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_MOV(ureg, face_temp, face_input); 4480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Use face_temp as face input from here on: */ 4482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); 4483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 4486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_edgeflags(struct st_translate *t) 4487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg = t->ureg; 4489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; 4490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; 4491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_MOV(ureg, edge_dst, edge_src); 4493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Translate intermediate IR (glsl_to_tgsi_instruction) to TGSI format. 4497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param program the program to translate 4498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param numInputs number of input registers used 4499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputMapping maps Mesa fragment program inputs to TGSI generic 4500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * input indexes 4501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputSemanticName the TGSI_SEMANTIC flag for each input 4502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param inputSemanticIndex the semantic index (ex: which texcoord) for 4503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * each input 4504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input 4505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param numOutputs number of output registers used 4506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputMapping maps Mesa fragment program outputs to TGSI 4507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generic outputs 4508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputSemanticName the TGSI_SEMANTIC flag for each output 4509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param outputSemanticIndex the semantic index (ex: which texcoord) for 4510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * each output 4511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY 4513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" enum pipe_error 4515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_translate_program( 4516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_context *ctx, 4517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint procType, 4518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_program *ureg, 4519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor *program, 4520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_program *proginfo, 4521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint numInputs, 4522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint inputMapping[], 4523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ubyte inputSemanticName[], 4524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ubyte inputSemanticIndex[], 4525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint interpMode[], 4526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLboolean is_centroid[], 4527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint numOutputs, 4528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint outputMapping[], 4529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ubyte outputSemanticName[], 4530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const ubyte outputSemanticIndex[], 4531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean passthrough_edgeflags, 4532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean clamp_color) 4533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_translate *t; 4535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 4536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_error ret = PIPE_OK; 4537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(numInputs <= Elements(t->inputs)); 4539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(numOutputs <= Elements(t->outputs)); 4540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t = CALLOC_STRUCT(st_translate); 4542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!t) { 4543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = PIPE_ERROR_OUT_OF_MEMORY; 4544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto out; 4545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(t, 0, sizeof *t); 4548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->procType = procType; 4550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputMapping = inputMapping; 4551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputMapping = outputMapping; 4552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->ureg = ureg; 4553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->shader_program) { 4555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < program->shader_program->NumUserUniformStorage; i++) { 4556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_uniform_storage *const storage = 4557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &program->shader_program->UniformStorage[i]; 4558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_uniform_detach_all_driver_storage(storage); 4560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 4564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Declare input attributes. 4565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (procType == TGSI_PROCESSOR_FRAGMENT) { 4567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numInputs; i++) { 4568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputs[i] = ureg_DECL_fs_input_cyl_centroid(ureg, 4569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inputSemanticName[i], 4570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inputSemanticIndex[i], 4571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org interpMode[i], 0, 4572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_centroid[i]); 4573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (proginfo->InputsRead & FRAG_BIT_WPOS) { 4576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Must do this after setting up t->inputs, and before 4577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * emitting constant references, below: 4578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_wpos(st_context(ctx), t, proginfo, ureg); 4580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (proginfo->InputsRead & FRAG_BIT_FACE) 4583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_face_var(t); 4584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 4586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Declare output attributes. 4587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numOutputs; i++) { 4589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (outputSemanticName[i]) { 4590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_POSITION: 4591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_DECL_output(ureg, 4592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_POSITION, /* Z/Depth */ 4593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticIndex[i]); 4594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Z); 4595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_STENCIL: 4597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_DECL_output(ureg, 4598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_STENCIL, /* Stencil */ 4599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticIndex[i]); 4600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_Y); 4601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_COLOR: 4603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_DECL_output(ureg, 4604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_SEMANTIC_COLOR, 4605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticIndex[i]); 4606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"fragment shader outputs must be POSITION/STENCIL/COLOR"); 4609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = PIPE_ERROR_BAD_INPUT; 4610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto out; 4611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (procType == TGSI_PROCESSOR_GEOMETRY) { 4615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numInputs; i++) { 4616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputs[i] = ureg_DECL_gs_input(ureg, 4617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i, 4618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inputSemanticName[i], 4619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inputSemanticIndex[i]); 4620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numOutputs; i++) { 4623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_DECL_output(ureg, 4624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticName[i], 4625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticIndex[i]); 4626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 4629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(procType == TGSI_PROCESSOR_VERTEX); 4630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numInputs; i++) { 4632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->inputs[i] = ureg_DECL_vs_input(ureg, i); 4633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < numOutputs; i++) { 4636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->outputs[i] = ureg_DECL_output(ureg, 4637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticName[i], 4638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputSemanticIndex[i]); 4639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (passthrough_edgeflags) 4641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_edgeflags(t); 4642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Declare address register. 4645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->num_address_regs > 0) { 4647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(program->num_address_regs == 1); 4648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->address[0] = ureg_DECL_address(ureg); 4649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Declare misc input registers 4652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 4654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLbitfield sysInputs = proginfo->SystemValuesRead; 4655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned numSys = 0; 4656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; sysInputs; i++) { 4657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sysInputs & (1 << i)) { 4658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned semName = mesa_sysval_to_semantic[i]; 4659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); 4660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (semName == TGSI_SEMANTIC_INSTANCEID || 4661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org semName == TGSI_SEMANTIC_VERTEXID) { 4662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* From Gallium perspective, these system values are always 4663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * integer, and require native integer support. However, if 4664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * native integer is supported on the vertex stage but not the 4665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pixel stage (e.g, i915g + draw), Mesa will generate IR that 4666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * assumes these system values are floats. To resolve the 4667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * inconsistency, we insert a U2F. 4668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_context *st = st_context(ctx); 4670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_screen *pscreen = st->pipe->screen; 4671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(procType == TGSI_PROCESSOR_VERTEX); 4672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS)); 4673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ctx->Const.NativeIntegers) { 4674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg); 4675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]); 4676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->systemValues[i] = ureg_scalar(ureg_src(temp), 0); 4677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org numSys++; 4680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sysInputs &= ~(1 << i); 4681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->indirect_addr_temps) { 4686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If temps are accessed with indirect addressing, declare temporaries 4687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in sequential order. Else, we declare them on demand elsewhere. 4688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * (Note: the number of temporaries is equal to program->next_temp) 4689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < (unsigned)program->next_temp; i++) { 4691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ 4692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->temps[i] = ureg_DECL_local_temporary(t->ureg); 4693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit constants and uniforms. TGSI uses a single index space for these, 4697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so we put all the translated regs in t->constants. 4698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (proginfo->Parameters) { 4700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->constants = (struct ureg_src *)CALLOC(proginfo->Parameters->NumParameters * sizeof(t->constants[0])); 4701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->constants == NULL) { 4702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = PIPE_ERROR_OUT_OF_MEMORY; 4703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto out; 4704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < proginfo->Parameters->NumParameters; i++) { 4707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (proginfo->Parameters->Parameters[i].Type) { 4708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_ENV_PARAM: 4709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_LOCAL_PARAM: 4710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_STATE_VAR: 4711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_NAMED_PARAM: 4712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_UNIFORM: 4713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->constants[i] = ureg_DECL_constant(ureg, i); 4714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit immediates for PROGRAM_CONSTANT only when there's no indirect 4717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * addressing of the const buffer. 4718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FIXME: Be smarter and recognize param arrays: 4719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * indirect addressing is only valid within the referenced 4720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array. 4721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PROGRAM_CONSTANT: 4723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->indirect_addr_consts) 4724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->constants[i] = ureg_DECL_constant(ureg, i); 4725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 4726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->constants[i] = emit_immediate(t, 4727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org proginfo->Parameters->ParameterValues[i], 4728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org proginfo->Parameters->Parameters[i].DataType, 4729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4); 4730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit immediate values. 4738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->immediates = (struct ureg_src *)CALLOC(program->num_immediates * sizeof(struct ureg_src)); 4740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->immediates == NULL) { 4741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = PIPE_ERROR_OUT_OF_MEMORY; 4742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto out; 4743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i = 0; 4745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, program->immediates) { 4746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org immediate_storage *imm = (immediate_storage *)iter.get(); 4747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i < program->num_immediates); 4748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size); 4749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(i == program->num_immediates); 4751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* texture samplers */ 4753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 4754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->samplers_used & (1 << i)) { 4755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->samplers[i] = ureg_DECL_sampler(ureg, i); 4756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit each instruction in turn: 4760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, program->instructions) { 4762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org set_insn_start(t, ureg_get_instruction_number(ureg)); 4763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(), 4764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org clamp_color); 4765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fix up all emitted labels: 4768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < t->labels_count; i++) { 4770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ureg_fixup_label(ureg, t->labels[i].token, 4771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org t->insn[t->labels[i].branch_target]); 4772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->shader_program) { 4775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This has to be done last. Any operation the can cause 4776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * prog->ParameterValues to get reallocated (e.g., anything that adds a 4777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * program constant) has to happen before creating this linkage. 4778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 4780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (program->shader_program->_LinkedShaders[i] == NULL) 4781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 4782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_associate_uniform_storage(ctx, program->shader_program, 4784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org program->shader_program->_LinkedShaders[i]->Program->Parameters); 4785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgout: 4789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t) { 4790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(t->insn); 4791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(t->labels); 4792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(t->constants); 4793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(t->immediates); 4794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (t->error) { 4796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s: translate error flag set\n", __FUNCTION__); 4797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(t); 4800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ret; 4803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* ----------------------------- End TGSI code ------------------------------ */ 4805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 4807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert a shader's GLSL IR into a Mesa gl_program, although without 4808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * generating Mesa IR. 4809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_program * 4811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgget_mesa_program(struct gl_context *ctx, 4812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_program *shader_program, 4813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader *shader) 4814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_visitor* v; 4816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program *prog; 4817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLenum target; 4818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *target_string; 4819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool progress; 4820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_compiler_options *options = 4821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader->Type)]; 4822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (shader->Type) { 4824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_VERTEX_SHADER: 4825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target = GL_VERTEX_PROGRAM_ARB; 4826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_string = "vertex"; 4827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRAGMENT_SHADER: 4829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target = GL_FRAGMENT_PROGRAM_ARB; 4830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_string = "fragment"; 4831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_GEOMETRY_SHADER: 4833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target = GL_GEOMETRY_PROGRAM_NV; 4834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_string = "geometry"; 4835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"should not be reached"); 4838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org validate_ir_tree(shader->ir); 4842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 4844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!prog) 4845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->Parameters = _mesa_new_parameter_list(); 4847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v = new glsl_to_tgsi_visitor(); 4848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->ctx = ctx; 4849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->prog = prog; 4850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->shader_program = shader_program; 4851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->options = options; 4852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->glsl_version = ctx->Const.GLSLVersion; 4853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->native_integers = ctx->Const.NativeIntegers; 4854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_generate_parameters_list_for_uniforms(shader_program, shader, 4856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->Parameters); 4857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Remove reads from output registers. */ 4859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lower_output_reads(shader->ir); 4860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit intermediate IR for main(). */ 4862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_exec_list(shader->ir, v); 4863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Now emit bodies for any functions that were used. */ 4865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { 4866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = GL_FALSE; 4867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach_iter(exec_list_iterator, iter, v->function_signatures) { 4869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org function_entry *entry = (function_entry *)iter.get(); 4870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!entry->bgn_inst) { 4872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->current_function = entry; 4873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->bgn_inst = v->emit(NULL, TGSI_OPCODE_BGNSUB); 4875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->bgn_inst->function = entry; 4876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org visit_exec_list(&entry->sig->body, v); 4878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *last; 4880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org last = (glsl_to_tgsi_instruction *)v->instructions.get_tail(); 4881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (last->op != TGSI_OPCODE_RET) 4882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->emit(NULL, TGSI_OPCODE_RET); 4883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org glsl_to_tgsi_instruction *end; 4885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end = v->emit(NULL, TGSI_OPCODE_ENDSUB); 4886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org end->function = entry; 4887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = GL_TRUE; 4889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (progress); 4892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 4894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Print out some information (for debugging purposes) used by the 4895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * optimization passes. */ 4896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < v->next_temp; i++) { 4897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int fr = v->get_first_temp_read(i); 4898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int fw = v->get_first_temp_write(i); 4899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int lr = v->get_last_temp_read(i); 4900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int lw = v->get_last_temp_write(i); 4901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("Temp %d: FR=%3d FW=%3d LR=%3d LW=%3d\n", i, fr, fw, lr, lw); 4903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(fw <= fr); 4904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 4906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Perform optimizations on the instructions in the glsl_to_tgsi_visitor. */ 4908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->simplify_cmp(); 4909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->copy_propagate(); 4910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (v->eliminate_dead_code_advanced()); 4911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FIXME: These passes to optimize temporary registers don't work when there 4913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is indirect addressing of the temporary register space. We need proper 4914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * array support so that we don't have to give up these passes in every 4915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * shader that uses arrays. 4916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!v->indirect_addr_temps) { 4918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->eliminate_dead_code(); 4919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->merge_registers(); 4920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->renumber_registers(); 4921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Write the END instruction. */ 4924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org v->emit(NULL, TGSI_OPCODE_END); 4925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Shader.Flags & GLSL_DUMP) { 4927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("\n"); 4928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("GLSL IR for linked %s program %d:\n", target_string, 4929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader_program->Name); 4930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_print_ir(shader->ir, NULL); 4931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("\n"); 4932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("\n"); 4933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fflush(stdout); 4934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->Instructions = NULL; 4937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prog->NumInstructions = 0; 4938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER); 4940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count_resources(v, prog); 4941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_program(ctx, &shader->Program, prog); 4943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This has to be done last. Any operation the can cause 4945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * prog->ParameterValues to get reallocated (e.g., anything that adds a 4946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * program constant) has to happen before creating this linkage. 4947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 4948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters); 4949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!shader_program->LinkStatus) { 4950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_vertex_program *stvp; 4954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_fragment_program *stfp; 4955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct st_geometry_program *stgp; 4956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (shader->Type) { 4958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_VERTEX_SHADER: 4959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stvp = (struct st_vertex_program *)prog; 4960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stvp->glsl_to_tgsi = v; 4961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_FRAGMENT_SHADER: 4963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stfp = (struct st_fragment_program *)prog; 4964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stfp->glsl_to_tgsi = v; 4965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_GEOMETRY_SHADER: 4967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stgp = (struct st_geometry_program *)prog; 4968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stgp->glsl_to_tgsi = v; 4969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 4970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 4971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!"should not be reached"); 4972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 4973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return prog; 4976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" { 4979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_shader * 4981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_new_shader(struct gl_context *ctx, GLuint name, GLuint type) 4982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader *shader; 4984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || 4985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type == GL_GEOMETRY_SHADER_ARB); 4986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader = rzalloc(NULL, struct gl_shader); 4987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shader) { 4988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader->Type = type; 4989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shader->Name = name; 4990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_init_shader(ctx, shader); 4991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 4992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shader; 4993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 4994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 4995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct gl_shader_program * 4996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_new_shader_program(struct gl_context *ctx, GLuint name) 4997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 4998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_shader_program *shProg; 4999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shProg = rzalloc(NULL, struct gl_shader_program); 5000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (shProg) { 5001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org shProg->Name = name; 5002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_init_shader_program(ctx, shProg); 5003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return shProg; 5005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 5006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 5008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Link a shader. 5009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called via ctx->Driver.LinkShader() 5010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This actually involves converting GLSL IR into an intermediate TGSI-like IR 5011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * with code lowering and other optimizations. 5012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 5013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean 5014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) 5015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 5016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(prog->LinkStatus); 5017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 5019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (prog->_LinkedShaders[i] == NULL) 5020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 5021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool progress; 5023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org exec_list *ir = prog->_LinkedShaders[i]->ir; 5024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct gl_shader_compiler_options *options = 5025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(prog->_LinkedShaders[i]->Type)]; 5026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do { 5028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP | 5029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org EXP_TO_EXP2 | LOG_TO_LOG2; 5030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (options->EmitNoPow) 5031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org what_to_lower |= POW_TO_EXP2; 5032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ctx->Const.NativeIntegers) 5033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org what_to_lower |= INT_DIV_TO_MUL_RCP; 5034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = false; 5036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Lowering */ 5038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_mat_op_to_vec(ir); 5039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lower_instructions(ir, what_to_lower); 5040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress; 5042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = do_common_optimization(ir, true, true, 5044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options->MaxUnrollIterations) 5045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || progress; 5046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = lower_quadop_vector(ir, false) || progress; 5048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (options->MaxIfDepth == 0) 5050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = lower_discard(ir) || progress; 5051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = lower_if_to_cond_assign(ir, options->MaxIfDepth) || progress; 5053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (options->EmitNoNoise) 5055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = lower_noise(ir) || progress; 5056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* If there are forms of indirect addressing that the driver 5058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cannot handle, perform the lowering pass. 5059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 5060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (options->EmitNoIndirectInput || options->EmitNoIndirectOutput 5061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || options->EmitNoIndirectTemp || options->EmitNoIndirectUniform) 5062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = 5063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lower_variable_index_to_cond_assign(ir, 5064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options->EmitNoIndirectInput, 5065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options->EmitNoIndirectOutput, 5066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options->EmitNoIndirectTemp, 5067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org options->EmitNoIndirectUniform) 5068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org || progress; 5069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org progress = do_vec_index_to_cond_assign(ir) || progress; 5071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } while (progress); 5072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org validate_ir_tree(ir); 5074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 5077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_program *linked_prog; 5078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (prog->_LinkedShaders[i] == NULL) 5080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 5081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 5083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (linked_prog) { 5085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static const GLenum targets[] = { 5086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_VERTEX_PROGRAM_ARB, 5087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_FRAGMENT_PROGRAM_ARB, 5088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_GEOMETRY_PROGRAM_NV 5089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org }; 5090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linked_prog); 5093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ctx->Driver.ProgramStringNotify(ctx, targets[i], linked_prog)) { 5094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_program(ctx, &prog->_LinkedShaders[i]->Program, 5095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NULL); 5096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_program(ctx, &linked_prog, NULL); 5097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 5098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_reference_program(ctx, &linked_prog, NULL); 5102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 5105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 5106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 5108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgst_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi, 5109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint outputMapping[], 5110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_stream_output_info *so) 5111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 5112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 5113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_transform_feedback_info *info = 5114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &glsl_to_tgsi->shader_program->LinkedTransformFeedback; 5115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < info->NumOutputs; i++) { 5117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->output[i].register_index = 5118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org outputMapping[info->Outputs[i].OutputRegister]; 5119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->output[i].start_component = info->Outputs[i].ComponentOffset; 5120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->output[i].num_components = info->Outputs[i].NumComponents; 5121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->output[i].output_buffer = info->Outputs[i].OutputBuffer; 5122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->output[i].dst_offset = info->Outputs[i].DstOffset; 5123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 5126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->stride[i] = info->BufferStride[i]; 5127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 5128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org so->num_outputs = info->NumOutputs; 5129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 5130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 5131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} /* extern "C" */ 5132