ir_to_mesa.cpp revision 0a46497a4ee3325fab47929cb17cfe2525e1fc33
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/* 2bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 3bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation 584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a 784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"), 884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation 984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the 1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions: 1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next 1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the 1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software. 1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE. 2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/** 2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp 2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * 2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible, 3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result 3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 330161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h> 34261bbc011d11ab9e390cd5fe9f5151821eefaffaIan Romanick#include "main/compiler.h" 3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h" 3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h" 3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h" 3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h" 3984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h" 40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h" 41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h" 42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h" 43364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h" 4484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 45aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" { 460a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h" 47658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt#include "main/shaderapi.h" 48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h" 49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h" 50fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h" 51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h" 52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h" 53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h" 54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h" 55afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h" 56afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h" 57aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt} 5884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size); 609c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/** 62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with 63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields. 64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 65554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg { 669c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg(int file, int index, const glsl_type *type) 679c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = file; 699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->index = index; 709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt if (type && (type->is_scalar() || type->is_vector() || type->is_matrix())) 719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = swizzle_for_size(type->vector_elements); 729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt else 739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->swizzle = SWIZZLE_XYZW; 749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->negate = 0; 759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->reladdr = NULL; 769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg() 799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt { 809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->file = PROGRAM_UNDEFINED; 8148c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->index = 0; 8248c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->swizzle = 0; 8348c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->negate = 0; 8448c289fb552a3d363b505514b6ea22467f00e318Vinson Lee this->reladdr = NULL; 859c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt } 869c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt 87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 89582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */ 90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int negate; /**< NEGATE_XYZW mask from mesa */ 91f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 92f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg; 94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg { 96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; /**< PROGRAM_* from Mesa */ 97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */ 98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int writemask; /**< Bitfield of WRITEMASK_[XYZW] */ 99854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLuint cond_mask:4; 100f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /** Register index should be offset by the integer in this reg. */ 101f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reladdr; 102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg; 103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef; 105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node { 107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 108554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op; 109554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst_reg; 110554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src_reg[3]; 111554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** Pointer to the ir source this tree came from for debugging */ 112554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_instruction *ir; 113854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt GLboolean cond_update; 114d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int sampler; /**< sampler index */ 115d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt int tex_target; /**< One of TEXTURE_*_INDEX */ 116b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt GLboolean tex_shadow; 1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */ 119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 121b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node { 122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 123b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage(ir_variable *var, int file, int index) 124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt : file(file), index(index), var(var) 125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt { 126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /* empty */ 127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt } 128554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 129554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int file; 130554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int index; 131554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_variable *var; /* variable that maps to this, if any */ 132554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 133554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node { 1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic: 1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig; 1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * identifier of this function signature used by the program. 1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * At the point that Mesa instructions for function calls are 1427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * generated, we don't know the address of the first instruction of 1437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * the function body. So we make the BranchTarget that is called a 1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * small integer and rewrite them during set_branchtargets(). 1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int sig_id; 1477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Pointer to first instruction of the function body. 1507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set during function body emits after main() is processed. 1527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *bgn_inst; 1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** 1567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Index of the first instruction of the function body in actual 1577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Mesa IR. 1587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * 1597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt * Set after convertion from ir_to_mesa_instruction to prog_instruction. 1607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt */ 1617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int inst; 1627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** Storage for the return value. */ 1647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg return_reg; 1657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}; 1667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor { 168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic: 169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_visitor(); 170fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt ~ir_to_mesa_visitor(); 171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *current_function; 1737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 174364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLcontext *ctx; 175364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 176aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt struct gl_shader_program *shader_program; 177364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt int next_temp; 179a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 180b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *find_variable_storage(ir_variable *var); 181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 1827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *get_function_signature(ir_function_signature *sig); 1837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt ir_to_mesa_src_reg get_temp(const glsl_type *type); 185f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt void reladdr_to_temp(ir_instruction *ir, 186f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr); 187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg src_reg_for_float(float val); 189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** 191554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * \name Visit methods 192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * 193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * As typical for the visitor pattern, there must be one \c visit method for 194554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * each concrete subclass of \c ir_instruction. Virtual base classes within 195554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * the hierarchy should not have \c visit methods. 196554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */ 197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@{*/ 198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_variable *); 199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop *); 200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_loop_jump *); 201554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function_signature *); 202554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_function *); 203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_expression *); 204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_swizzle *); 205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_variable *); 206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_array *); 207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_dereference_record *); 208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_assignment *); 209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_constant *); 210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_call *); 211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_return *); 21216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke virtual void visit(ir_discard *); 213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_texture *); 214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt virtual void visit(ir_if *); 215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /*@}*/ 216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt struct ir_to_mesa_src_reg result; 218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 219b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt /** List of variable_storage */ 220b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt exec_list variables; 221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /** List of function_entry */ 2237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list function_signatures; 2247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int next_signature_id; 2257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 226554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt /** List of ir_to_mesa_instruction */ 227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt exec_list instructions; 228554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 229021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir, 230021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op); 231021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 232554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir, 233554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 234554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 236554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 237554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir, 238554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 239554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1); 242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir, 244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0, 247554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src1, 248554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src2); 249554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 250554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt void ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 251554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt enum prog_opcode op, 252554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_dst_reg dst, 253554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt ir_to_mesa_src_reg src0); 2540ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt 255904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt void ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 256904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 257904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 258904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0, 259904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1); 260904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 2613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt GLboolean try_emit_mad(ir_expression *ir, 2623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int mul_operand); 2633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 264aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt int get_sampler_uniform_value(ir_dereference *deref); 265d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 266364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt void *mem_ctx; 267554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt}; 268554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt 2699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL); 27084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 271c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = { 272f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL, 273c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}; 274c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2750161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = { 276f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL 2770161515c395c44233529c8d51f823b60050bc7baEric Anholt}; 2780161515c395c44233529c8d51f823b60050bc7baEric Anholt 2790161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size) 2800161515c395c44233529c8d51f823b60050bc7baEric Anholt{ 2810161515c395c44233529c8d51f823b60050bc7baEric Anholt int size_swizzles[4] = { 2820161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), 2830161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y), 2840161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z), 2850161515c395c44233529c8d51f823b60050bc7baEric Anholt MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), 2860161515c395c44233529c8d51f823b60050bc7baEric Anholt }; 2870161515c395c44233529c8d51f823b60050bc7baEric Anholt 2880161515c395c44233529c8d51f823b60050bc7baEric Anholt return size_swizzles[size - 1]; 2890161515c395c44233529c8d51f823b60050bc7baEric Anholt} 2900161515c395c44233529c8d51f823b60050bc7baEric Anholt 29184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 2920161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir, 2930161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 2940161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 2950161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 2960161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1, 2970161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src2) 29884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 299364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction(); 300f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt int num_reladdr = 0; 301f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 302f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt /* If we have to do relative addressing, we want to load the ARL 303f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * reg directly for one of the regs, and preload the other reladdr 304f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt * sources into temps. 305f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt */ 306f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += dst.reladdr != NULL; 307f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src0.reladdr != NULL; 308f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src1.reladdr != NULL; 309f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr += src2.reladdr != NULL; 310f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 311f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src2, &num_reladdr); 312f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src1, &num_reladdr); 313f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt reladdr_to_temp(ir, &src0, &num_reladdr); 314f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 315f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (dst.reladdr) { 316f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, 317f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *dst.reladdr); 318f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 319f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt num_reladdr--; 320f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 321f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt assert(num_reladdr == 0); 32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->op = op; 32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->dst_reg = dst; 32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[0] = src0; 32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[1] = src1; 32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt inst->src_reg[2] = src2; 328c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt inst->ir = ir; 32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function = NULL; 3317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 3320161515c395c44233529c8d51f823b60050bc7baEric Anholt this->instructions.push_tail(inst); 33384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return inst; 33584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 33684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 33784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 33884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3390161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir, 3400161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3410161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3420161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0, 3430161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src1) 34484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3450161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef); 34684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 34784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction * 3490161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir, 3500161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 3510161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 3520161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src0) 353bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{ 3545a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(dst.writemask != 0); 3550161515c395c44233529c8d51f823b60050bc7baEric Anholt return ir_to_mesa_emit_op3(ir, op, dst, 3560161515c395c44233529c8d51f823b60050bc7baEric Anholt src0, ir_to_mesa_undef, ir_to_mesa_undef); 357bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 358bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 359021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction * 360021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir, 361021222c6a872ca2eef770ebadb8754f659775204Eric Anholt enum prog_opcode op) 362021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{ 363021222c6a872ca2eef770ebadb8754f659775204Eric Anholt return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst, 364021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 365021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef, 366021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_undef); 367021222c6a872ca2eef770ebadb8754f659775204Eric Anholt} 368021222c6a872ca2eef770ebadb8754f659775204Eric Anholt 3690161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg 3700161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg) 37184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 3720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst_reg; 37384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 3740161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.file = reg.file; 3750161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.index = reg.index; 3760161515c395c44233529c8d51f823b60050bc7baEric Anholt dst_reg.writemask = WRITEMASK_XYZW; 377854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt dst_reg.cond_mask = COND_TR; 378f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt dst_reg.reladdr = reg.reladdr; 3790161515c395c44233529c8d51f823b60050bc7baEric Anholt 3800161515c395c44233529c8d51f823b60050bc7baEric Anholt return dst_reg; 381bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt} 382bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt 3832d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg 3842d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg) 3852d1789e667c4180777829f96856daf91326721b9Eric Anholt{ 3869c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt return ir_to_mesa_src_reg(reg.file, reg.index, NULL); 3872d1789e667c4180777829f96856daf91326721b9Eric Anholt} 3882d1789e667c4180777829f96856daf91326721b9Eric Anholt 38912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/** 39012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels. 39112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * 39212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp. The src X 39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels. So to do a vec4 39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used 39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels. 39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid 398904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir, 3990161515c395c44233529c8d51f823b60050bc7baEric Anholt enum prog_opcode op, 4000161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_dst_reg dst, 401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src0, 402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg orig_src1) 40312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{ 40412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt int i, j; 405315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt int done_mask = ~dst.writemask; 40612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt /* Mesa RCP is a scalar operation splatting results to all channels, 40812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * like ARB_fp/vp. So emit as many RCPs as necessary to cover our 40912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * dst channels. 41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */ 41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (i = 0; i < 4; i++) { 412582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt GLuint this_mask = (1 << i); 41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt ir_to_mesa_instruction *inst; 414904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0 = orig_src0; 415904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src1 = orig_src1; 41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt if (done_mask & this_mask) 41812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt continue; 41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 420904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src0_swiz = GET_SWZ(src0.swizzle, i); 421904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GLuint src1_swiz = GET_SWZ(src1.swizzle, i); 42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt for (j = i + 1; j < 4; j++) { 423904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt if (!(done_mask & (1 << j)) && 424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src0.swizzle, j) == src0_swiz && 425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt GET_SWZ(src1.swizzle, j) == src1_swiz) { 42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt this_mask |= (1 << j); 42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 429904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz, 430904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0_swiz, src0_swiz); 431904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz, 432904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1_swiz, src1_swiz); 43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt inst = ir_to_mesa_emit_op2(ir, op, 4350161515c395c44233529c8d51f823b60050bc7baEric Anholt dst, 436904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src0, 437904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt src1); 43812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt inst->dst_reg.writemask = this_mask; 43912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt done_mask |= this_mask; 44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt } 44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt} 44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt 443904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid 444904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir, 445904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt enum prog_opcode op, 446904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_dst_reg dst, 447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_src_reg src0) 448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{ 44959a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt ir_to_mesa_src_reg undef = ir_to_mesa_undef; 450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt undef.swizzle = SWIZZLE_XXXX; 452904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef); 454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt} 455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt 4560161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg 4570161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val) 458b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 4599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL); 4601d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 461582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 462582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt &val, 1, &src_reg.swizzle); 4631d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4640161515c395c44233529c8d51f823b60050bc7baEric Anholt return src_reg; 4651d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt} 4661d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt 4672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int 4682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type) 4692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 4702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 4712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int size; 4722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 4732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt switch (type->base_type) { 4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_UINT: 4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_INT: 4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_FLOAT: 4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_BOOL: 478a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt if (type->is_matrix()) { 4799968f1b23c475c99139f0209c7a049ed00df01afEric Anholt return type->matrix_columns; 480a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } else { 481a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt /* Regardless of size of vector, it gets a vec4. This is bad 482a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * packing for things like floats, but otherwise arrays become a 483a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * mess. Hopefully a later pass over the code can pack scalars 484a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt * down if appropriate. 485a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt */ 486a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return 1; 487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt } 4882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_ARRAY: 4892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return type_size(type->fields.array) * type->length; 4902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt case GLSL_TYPE_STRUCT: 4912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size = 0; 4922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < type->length; i++) { 4932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt size += type_size(type->fields.structure[i].type); 4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt return size; 4968d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt case GLSL_TYPE_SAMPLER: 4970924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Samplers take up one slot in UNIFORMS[], but they're baked in 4980924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * at link time. 4998d61a23b1a1d0d4b21f0fab64f6d863a8ee3d7f1Eric Anholt */ 5000924ba0c3496160a134d37cec800f902ae805b9cEric Anholt return 1; 5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt default: 5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt assert(0); 50319acfa42ed47edb63f5ec3de8051a3102e62e96bJosé Fonseca return 0; 5042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 5052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 5062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 507d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/** 508d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to 509d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results. (not SSA -- variable assignments will reuse 510d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage). Actual register allocation for the Mesa VM occurs in a 511d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later. 512d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */ 513d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg 514d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type) 515d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{ 516d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt ir_to_mesa_src_reg src_reg; 517d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int swizzle[4]; 518d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt int i; 519d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 520d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.file = PROGRAM_TEMPORARY; 521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt src_reg.index = next_temp; 522f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt next_temp += type_size(type); 524d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 52520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (type->is_array() || type->is_record()) { 52620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = SWIZZLE_NOOP; 52720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } else { 52820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < type->vector_elements; i++) 52920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = i; 53020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (; i < 4; i++) 53120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[i] = type->vector_elements - 1; 53220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], 53320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt swizzle[2], swizzle[3]); 53420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 535ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt src_reg.negate = 0; 536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt return src_reg; 538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt} 539d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt 540b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage * 541a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var) 54284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 543a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt 544b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 54584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 546b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt foreach_iter(exec_list_iterator, iter, this->variables) { 547b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = (variable_storage *)iter.get(); 54884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 5490161515c395c44233529c8d51f823b60050bc7baEric Anholt if (entry->var == var) 550a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return entry; 55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 55284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 553a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt return NULL; 554a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt} 55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 55784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir) 55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 5594a962170d7cf4243d6ae156fca20a6167388925dEric Anholt if (strcmp(ir->name, "gl_FragCoord") == 0) { 5604a962170d7cf4243d6ae156fca20a6167388925dEric Anholt struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; 5614a962170d7cf4243d6ae156fca20a6167388925dEric Anholt 5624a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->OriginUpperLeft = ir->origin_upper_left; 5634a962170d7cf4243d6ae156fca20a6167388925dEric Anholt fp->PixelCenterInteger = ir->pixel_center_integer; 5644a962170d7cf4243d6ae156fca20a6167388925dEric Anholt } 56584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir) 56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 57064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->from); 57164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->to); 57264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->increment); 57364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt assert(!ir->counter); 57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 575021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP); 57664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt visit_exec_list(&ir->body_instructions, this); 577021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP); 57884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 57984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 58084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 58184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir) 58284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (ir->mode) { 58464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_break: 585021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_BRK); 58664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 58764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case ir_loop_jump::jump_continue: 588021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(NULL, OPCODE_CONT); 58964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 59064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir) 59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(0); 59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (void)ir; 59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir) 60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* Ignore function bodies other than main() -- we shouldn't see calls to 60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * them since they should all be inlined before we get to ir_to_mesa. 60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (strcmp(ir->name, "main") == 0) { 60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const ir_function_signature *sig; 60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exec_list empty; 61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sig = ir->matching_signature(&empty); 61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(sig); 61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, sig->body) { 61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 61784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 61884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->accept(this); 61984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 62084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 62184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 62284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6233f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean 6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand) 6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{ 6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt int nonmul_operand = 1 - mul_operand; 6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_src_reg a, b, c; 6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_expression *expr = ir->operands[mul_operand]->as_expression(); 6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (!expr || expr->operation != ir_binop_mul) 6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return false; 6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[0]->accept(this); 6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt a = this->result; 6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt expr->operands[1]->accept(this); 6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt b = this->result; 6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir->operands[nonmul_operand]->accept(this); 6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt c = this->result; 6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6403f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt this->result = get_temp(ir->type); 6413f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_emit_op3(ir, OPCODE_MAD, 6423f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt ir_to_mesa_dst_reg_from_src(this->result), a, b, c); 6433f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 6443f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return true; 6453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt} 6463f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 64784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir, 649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg *reg, int *num_reladdr) 650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{ 651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (!reg->reladdr) 652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt return; 653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr); 655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt if (*num_reladdr != 1) { 657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, 660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt ir_to_mesa_dst_reg_from_src(temp), *reg); 661f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt *reg = temp; 662f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt } 663f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 664f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt (*num_reladdr)--; 665f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt} 666f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 667f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid 66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir) 66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt unsigned int operand; 671f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt struct ir_to_mesa_src_reg op[2]; 6720161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg result_src; 6730161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg result_dst; 67484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1); 67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1); 67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1); 67784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c) 6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt */ 6803f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (ir->operation == ir_binop_add) { 6813f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 1)) 6823f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6833f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt if (try_emit_mad(ir, 0)) 6843f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt return; 6853f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt } 6863f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt 68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (operand = 0; operand < ir->get_num_operands(); operand++) { 6880161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(this); 6900161515c395c44233529c8d51f823b60050bc7baEric Anholt if (this->result.file == PROGRAM_UNDEFINED) { 69184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_print_visitor v; 69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt printf("Failed to get tree for expression operand:\n"); 69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->operands[operand]->accept(&v); 69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt exit(1); 69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt op[operand] = this->result; 6978364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 6984ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt /* Matrix expression operands should have been broken down to vector 6994ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt * operations already. 7004ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt */ 7014ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt assert(!ir->operands[operand]->type->is_matrix()); 70284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 70384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 7040161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.file = PROGRAM_UNDEFINED; 7050161515c395c44233529c8d51f823b60050bc7baEric Anholt 7060161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Storage for our result. Ideally for an assignment we'd be using 7070161515c395c44233529c8d51f823b60050bc7baEric Anholt * the actual storage for the result here, instead. 7080161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 7098364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt result_src = get_temp(ir->type); 7100161515c395c44233529c8d51f823b60050bc7baEric Anholt /* convenience for the emit functions below. */ 7110161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 7129cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt /* Limit writes to the channels that will be used by result_src later. 7139cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * This does limit this temp's use as a temporary for multi-instruction 7149cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt * sequences. 7159cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt */ 7169cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt result_dst.writemask = (1 << ir->type->vector_elements) - 1; 71784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 71884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (ir->operation) { 7191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_logic_not: 720f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, 721f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt op[0], src_reg_for_float(0.0)); 7221d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 723c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt case ir_unop_neg: 7240161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 7250161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 726c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt break; 727524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt case ir_unop_abs: 728524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]); 729524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt break; 7303acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt case ir_unop_sign: 7313acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]); 7323acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt break; 7338761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt case ir_unop_rcp: 7348761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]); 7358761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt break; 736524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt 7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_exp2: 7380161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]); 7398c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 740bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt case ir_unop_exp: 7418c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log: 742bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt assert(!"not reached: should be handled by ir_explog_to_explog2"); 7438c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7448c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt case ir_unop_log2: 7450161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]); 7468c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt break; 7473c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_sin: 7480161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]); 7493c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 7503c5979565facebc82000a611b991d2977b8e9bbfEric Anholt case ir_unop_cos: 7510161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]); 7523c5979565facebc82000a611b991d2977b8e9bbfEric Anholt break; 753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdx: 755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]); 756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 757ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt case ir_unop_dFdy: 758ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]); 759ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt break; 760ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt 76184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_add: 7627b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]); 76384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 76484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_sub: 7657b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]); 76684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 7679b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt 76884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_mul: 7694ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]); 77084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 77184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_div: 7729a0e421983edc31371440c08687fa2bb2207924dEric Anholt assert(!"not reached: should be handled by ir_div_to_mul_rcp"); 773411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_binop_mod: 774411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt assert(!"ir_binop_mod should have been converted to b * fract(a/b)"); 775411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt break; 77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 77738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_less: 778f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]); 77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_greater: 781f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]); 78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_lequal: 784f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]); 78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_gequal: 787f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]); 78838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 78938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_equal: 7906992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "==" operator producing a scalar boolean. */ 7916992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 7926992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 7936992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 7946992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 7956992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); 7966992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp); 7976992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, 7986992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt result_dst, result_src, src_reg_for_float(0.0)); 7996992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 8006992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]); 8016992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 80238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 80338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt case ir_binop_nequal: 8046992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt /* "!=" operator producing a scalar boolean. */ 8056992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt if (ir->operands[0]->type->is_vector() || 8066992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir->operands[1]->type->is_vector()) { 8076992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type); 8086992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8096992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_dst_reg_from_src(temp), op[0], op[1]); 8106992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, temp, temp); 8116992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8126992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt result_dst, result_src, src_reg_for_float(0.0)); 8136992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } else { 8146992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 8156992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt } 8166992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt break; 8175e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 8185e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt case ir_unop_any: 8195e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt switch (ir->operands[0]->type->vector_elements) { 8205e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt case 4: 8215e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, result_dst, op[0], op[0]); 8225e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 8235e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt case 3: 8245e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP3, result_dst, op[0], op[0]); 8255e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 8265e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt case 2: 8275e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP2, result_dst, op[0], op[0]); 8285e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 8295e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt default: 8305e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt assert(!"unreached: ir_unop_any of non-bvec"); 8315e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 8325e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt } 8335e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8345e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt result_dst, result_src, src_reg_for_float(0.0)); 8355e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt break; 8365e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt 8376992c3c3739dad249e8c396057d5cbeedcdf91deEric Anholt case ir_binop_logic_xor: 838f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]); 83938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt break; 84038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt 8414380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_or: 8420161515c395c44233529c8d51f823b60050bc7baEric Anholt /* This could be a saturated add and skip the SNE. */ 8430161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_ADD, 8440161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8450161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8460161515c395c44233529c8d51f823b60050bc7baEric Anholt 8470161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, 8480161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8490161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src, src_reg_for_float(0.0)); 8504380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8514380099c98119611ceee684669d00be26195c7d7Eric Anholt 8524380099c98119611ceee684669d00be26195c7d7Eric Anholt case ir_binop_logic_and: 8534380099c98119611ceee684669d00be26195c7d7Eric Anholt /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */ 8540161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 8550161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8560161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 8574380099c98119611ceee684669d00be26195c7d7Eric Anholt break; 8584380099c98119611ceee684669d00be26195c7d7Eric Anholt 85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_binop_dot: 86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (ir->operands[0]->type == vec4_type) { 86184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec4_type); 8620161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP4, 8630161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8640161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec3_type) { 86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec3_type); 8670161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP3, 8680161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8690161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else if (ir->operands[0]->type == vec2_type) { 87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt assert(ir->operands[1]->type == vec2_type); 8720161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_DP2, 8730161515c395c44233529c8d51f823b60050bc7baEric Anholt result_dst, 8740161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0], op[1]); 87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 87684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 8779be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 8789be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt case ir_binop_cross: 8799be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]); 8809be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt break; 8819be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt 88284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case ir_unop_sqrt: 8830161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 8848f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src); 8858f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt /* For incoming channels < 0, set the result to 0. */ 8868f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst, 8878f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt op[0], src_reg_for_float(0.0), result_src); 88884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 889878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt case ir_unop_rsq: 8900161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]); 891878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt break; 89250ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt case ir_unop_i2f: 893d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2f: 894d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt case ir_unop_b2i: 895423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt /* Mesa IR lacks types, ints are stored as truncated floats. */ 8960161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src = op[0]; 89750ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt break; 898423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt case ir_unop_f2i: 8990161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 900423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt break; 9011d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt case ir_unop_f2b: 902411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt case ir_unop_i2b: 9030161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, 90466afcb560771b6ba6ad668156e9f442e86b9a7a2Eric Anholt op[0], src_reg_for_float(0.0)); 9051d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt break; 906c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_trunc: 9070161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]); 908c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 909c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_ceil: 9100161515c395c44233529c8d51f823b60050bc7baEric Anholt op[0].negate = ~op[0].negate; 9110161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 9120161515c395c44233529c8d51f823b60050bc7baEric Anholt result_src.negate = ~result_src.negate; 913c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 914c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt case ir_unop_floor: 9150161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]); 916c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt break; 917d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt case ir_unop_fract: 918d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]); 919d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt break; 920d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt 921c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_min: 9220161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]); 923c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 924c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt case ir_binop_max: 9250161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]); 926c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt break; 927904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt case ir_binop_pow: 928904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]); 929904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt break; 930e64a4aaacbc682f24180dff3627b84861844476dEric Anholt 931e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_bit_not: 932e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_unop_u2f: 933e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_lshift: 934e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_rshift: 935e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_and: 936e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_xor: 937e64a4aaacbc682f24180dff3627b84861844476dEric Anholt case ir_binop_bit_or: 938e64a4aaacbc682f24180dff3627b84861844476dEric Anholt assert(!"GLSL 1.30 features unsupported"); 939e64a4aaacbc682f24180dff3627b84861844476dEric Anholt break; 94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 941b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt 9420161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = result_src; 94384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 94684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 94784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir) 94884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 9490161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 95084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int i; 95184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int swizzle[4]; 95284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 953b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt /* Note that this is only swizzles in expressions, not those on the left 954b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * hand side of an assignment, which do write masking. See ir_assignment 955b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt * for that. 956b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt */ 95784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 95884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->val->accept(this); 9594006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt src_reg = this->result; 9604006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt assert(src_reg.file != PROGRAM_UNDEFINED); 96184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 96284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt for (i = 0; i < 4; i++) { 96384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt if (i < ir->type->vector_elements) { 96484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt switch (i) { 96584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 0: 966698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x); 96784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 96884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 1: 969698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y); 97084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 97184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 2: 972698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z); 97384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 97484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt case 3: 975698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w); 97684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt break; 97784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 97884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } else { 97984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last 98084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * channel out. 98184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */ 982698b84444343189357ad252856d3c5493e47e4faEric Anholt swizzle[i] = swizzle[ir->type->vector_elements - 1]; 98384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 98484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 98584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9860161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], 9870161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[1], 9880161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[2], 9890161515c395c44233529c8d51f823b60050bc7baEric Anholt swizzle[3]); 99084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 9910161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 99284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 99384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 994dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic const struct { 995dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *name; 996dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *field; 997dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int tokens[STATE_LENGTH]; 998dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int swizzle; 999dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt bool array_indexed; 1000dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} statevars[] = { 1001dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "near", 1002325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX, false}, 1003dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "far", 1004325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY, false}, 1005dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_DepthRange", "diff", 1006325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ, false}, 1007dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1008dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ClipPlane", NULL, 1009dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true} 1010dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt, 1011dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "size", 1012325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_SIZE}, SWIZZLE_XXXX, false}, 1013dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "sizeMin", 1014325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_SIZE}, SWIZZLE_YYYY, false}, 1015dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "sizeMax", 1016325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_SIZE}, SWIZZLE_ZZZZ, false}, 1017dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "fadeThresholdSize", 1018325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_SIZE}, SWIZZLE_WWWW, false}, 1019dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceConstantAttenuation", 1020325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX, false}, 1021dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceLinearAttenuation", 1022325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY, false}, 1023dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Point", "distanceQuadraticAttenuation", 1024325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ, false}, 1025dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1026dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "emission", 1027325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW, false}, 1028dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "ambient", 1029325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW, false}, 1030dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "diffuse", 1031325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, false}, 1032dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "specular", 1033325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW, false}, 1034dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontMaterial", "shininess", 1035325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX, false}, 1036dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1037dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "emission", 1038325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW, false}, 1039dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "ambient", 1040325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW, false}, 1041dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "diffuse", 1042325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, false}, 1043dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "specular", 1044325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW, false}, 1045dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackMaterial", "shininess", 1046325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX, false}, 1047dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1048dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "ambient", 1049dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1050dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "diffuse", 1051dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1052dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "specular", 1053dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1054dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "position", 1055dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true}, 1056dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "halfVector", 1057dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true}, 1058dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotDirection", 1059dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true}, 1060dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotCosCutoff", 1061dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true}, 1062dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotCutoff", 1063dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true}, 1064dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "spotExponent", 1065dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true}, 1066dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "constantAttenuation", 1067dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true}, 1068dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "linearAttenuation", 1069dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true}, 1070dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_LightSource", "quadraticAttenuation", 1071dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true}, 1072dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1073c3e3793c325e36366165a5d1403a8c406ff200dbLuca Barbieri {"gl_LightModel", "ambient", 1074325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW, false}, 1075dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1076c108a7927d1dad9e0f641a0ec5a7387fb2626156Luca Barbieri {"gl_FrontLightModelProduct", "sceneColor", 1077325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW, false}, 1078c108a7927d1dad9e0f641a0ec5a7387fb2626156Luca Barbieri {"gl_BackLightModelProduct", "sceneColor", 1079325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW, false}, 1080dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1081dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "ambient", 1082dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1083dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "diffuse", 1084dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1085dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_FrontLightProduct", "specular", 1086dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1087dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1088dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "ambient", 1089dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true}, 1090dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "diffuse", 1091dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true}, 1092dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_BackLightProduct", "specular", 1093dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true}, 1094dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1095d6cc7191daa249463b20e2965dc1006288539b1eKenneth Graunke {"gl_TextureEnvColor", NULL, 1096dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true}, 1097dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1098dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneS", NULL, 1099dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true}, 1100dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneT", NULL, 1101dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true}, 1102dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneR", NULL, 1103dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true}, 1104dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_EyePlaneQ", NULL, 1105dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true}, 1106dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1107dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneS", NULL, 1108dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true}, 1109dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneT", NULL, 1110dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true}, 1111dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneR", NULL, 1112dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true}, 1113dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_ObjectPlaneQ", NULL, 1114dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true}, 1115dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1116dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "color", 1117325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_FOG_COLOR}, SWIZZLE_XYZW, false}, 1118dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "density", 1119325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_FOG_PARAMS}, SWIZZLE_XXXX, false}, 1120dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "start", 1121325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_FOG_PARAMS}, SWIZZLE_YYYY, false}, 1122dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "end", 1123325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ, false}, 1124dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt {"gl_Fog", "scale", 1125325aa1b3cd3fa2dcfc936d2024a4493c06f3b3f4José Fonseca {STATE_FOG_PARAMS}, SWIZZLE_WWWW, false}, 1126dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt}; 1127dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1128dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic ir_to_mesa_src_reg 1129dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtget_builtin_uniform_reg(struct gl_program *prog, 1130dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt const char *name, int array_index, const char *field) 1131dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt{ 1132dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt unsigned int i; 1133dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_to_mesa_src_reg src_reg; 1134dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt int tokens[STATE_LENGTH]; 1135dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1136dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt for (i = 0; i < Elements(statevars); i++) { 1137dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (strcmp(statevars[i].name, name) != 0) 1138dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt continue; 1139dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (!field && statevars[i].field) { 1140dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(!"FINISHME: whole-structure state var dereference"); 1141dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1142fc76d7276393a4617f9898214bc397bb65634b02Luca Barbieri if (field && (!statevars[i].field || strcmp(statevars[i].field, field) != 0)) 1143dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt continue; 1144dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt break; 1145dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1146dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1147dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (i == Elements(statevars)) { 1148dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt printf("builtin uniform %s%s%s not found\n", 1149dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt name, 1150dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt field ? "." : "", 1151dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt field ? field : ""); 1152dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt abort(); 1153dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1154dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1155dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt memcpy(&tokens, statevars[i].tokens, sizeof(tokens)); 1156dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (statevars[i].array_indexed) 1157dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt tokens[1] = array_index; 1158dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1159dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.file = PROGRAM_STATE_VAR; 1160dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.index = _mesa_add_state_reference(prog->Parameters, 1161dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt (gl_state_index *)tokens); 1162dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.swizzle = statevars[i].swizzle; 1163dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.negate = 0; 1164dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt src_reg.reladdr = false; 1165dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1166dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt return src_reg; 1167dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} 1168dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int 117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens) 117176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{ 117276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 117376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int i; 117476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt /* Add a ref for each column. It looks like the reason we do 117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * it this way is that _mesa_add_state_reference doesn't work 117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * for things that aren't vec4s, so the tokens[2]/tokens[3] 117876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt * range has to be equal. 117976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt */ 118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < 4; i++) { 118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[2] = i; 118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[3] = i; 118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = _mesa_add_state_reference(prog->Parameters, 118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt (gl_state_index *)tokens); 118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + i == pos); 118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 119076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 119176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return base_pos; 119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt} 119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1194b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage * 119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var, 119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_rvalue *array_index) 1197bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{ 1198bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* 1199bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * NOTE: The ARB_vertex_program extension specified that matrices get 1200bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * loaded in registers in row-major order. With GLSL, we want column- 1201bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * major order. So, we need to transpose all matrices here... 1202bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1203bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt static const struct { 1204bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt const char *name; 1205bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int matrix; 1206bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int modifier; 1207bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } matrices[] = { 1208bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, 1209bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, 1210bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, 1211bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1212bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1213bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, 1214bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, 1215bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, 1216bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, 1217bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1218bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, 1219bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, 1220bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, 1221bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, 1222bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1223bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, 1224bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, 1225bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, 1226bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, 1227bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1228bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, 1229bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1230bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt }; 1231bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt unsigned int i; 1232b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry; 1233bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1234bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt /* C++ gets angry when we try to use an int as a gl_state_index, so we use 1235bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * ints for gl_state_index. Make sure they're compatible. 1236bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt */ 1237bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt assert(sizeof(gl_state_index) == sizeof(int)); 1238bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1239bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt for (i = 0; i < Elements(matrices); i++) { 1240bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (strcmp(var->name, matrices[i].name) == 0) { 1241bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt int tokens[STATE_LENGTH]; 124276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int base_pos = -1; 1243bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1244bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[0] = matrices[i].matrix; 1245bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt tokens[4] = matrices[i].modifier; 124676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (matrices[i].matrix == STATE_TEXTURE_MATRIX) { 124776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_constant *index = array_index->constant_expression_value(); 124876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 124976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = index->value.i[0]; 125076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 125176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 125276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt for (i = 0; i < var->type->length; i++) { 125376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = i; 125476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt int pos = add_matrix_ref(prog, tokens); 125576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (base_pos == -1) 125676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = pos; 125776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt else 125876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(base_pos + (int)i * 4 == pos); 125976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 126076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 126176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 126276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt tokens[1] = 0; /* unused array index */ 126376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt base_pos = add_matrix_ref(prog, tokens); 1264bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1265bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1266b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(var, 1267b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_STATE_VAR, 1268b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt base_pos); 1269bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1270bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return entry; 1271bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1272bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt } 1273bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 1274bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt return NULL; 1275bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt} 1276bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 127784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 127884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir) 127984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1280b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *entry = find_variable_storage(ir->var); 128184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 12828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 12838364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt switch (ir->var->mode) { 12848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_uniform: 128576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var, 128676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt NULL); 1287bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt if (entry) 1288bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt break; 1289bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt 12900924ba0c3496160a134d37cec800f902ae805b9cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, 12910924ba0c3496160a134d37cec800f902ae805b9cEric Anholt ir->var->location); 1292b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 12938364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 12948364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_in: 12958364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_out: 12968364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_inout: 1297a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt /* The linker assigns locations for varyings and attributes, 1298a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * including deprecated builtins (like gl_Color), user-assign 1299a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * generic attributes (glBindVertexLocation), and 1300a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * user-defined varyings. 1301a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * 1302a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt * FINISHME: We would hit this path for function arguments. Fix! 1303f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt */ 1304f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt assert(ir->var->location != -1); 1305a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt if (ir->var->mode == ir_var_in || 1306a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt ir->var->mode == ir_var_inout) { 1307b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1308b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_INPUT, 1309b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1310edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt 1311edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt if (this->prog->Target == GL_VERTEX_PROGRAM_ARB && 1312edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->location >= VERT_ATTRIB_GENERIC0) { 1313edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt _mesa_add_attribute(prog->Attributes, 1314edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->name, 1315658e25987fbec3b826f500baa6d4d936b9552b13Eric Anholt _mesa_sizeof_glsl_type(ir->var->type->gl_type), 1316edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt ir->var->type->gl_type, 1317c64da87611823b4b53e93188f861f748a69936a3Eric Anholt ir->var->location - VERT_ATTRIB_GENERIC0); 1318edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt } 1319f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } else { 1320b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, 1321b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt PROGRAM_OUTPUT, 1322b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt ir->var->location); 1323f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt } 1324f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt 13258364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 13268364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt case ir_var_auto: 13277e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick case ir_var_temporary: 1328b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY, 1329b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1330b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(entry); 1331224f712950494730c76b48864f2ca19acde1c8cfEric Anholt 13328364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt next_temp += type_size(ir->var->type); 13338364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt break; 133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 13358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt 13368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt if (!entry) { 13378364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt printf("Failed to make storage for %s\n", ir->var->name); 13388364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt exit(1); 1339224f712950494730c76b48864f2ca19acde1c8cfEric Anholt } 134084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 134184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 13429c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type); 134384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 134484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 134584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 134684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir) 134784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 1348dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_variable *var = ir->variable_referenced(); 1349ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir_constant *index; 13500161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 135176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_dereference_variable *deref_var = ir->array->as_dereference_variable(); 13528258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt int element_size = type_size(ir->type); 1353ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt 1354ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt index = ir->array_index->constant_expression_value(); 13554e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 135676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (deref_var && strncmp(deref_var->var->name, 135776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt "gl_TextureMatrix", 135876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt strlen("gl_TextureMatrix")) == 0) { 1359b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt struct variable_storage *entry; 136076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 136176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var, 136276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index); 136376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt assert(entry); 136476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 13659c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type); 136676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 136776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt if (index) { 1368f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = NULL; 136976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } else { 137076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type); 137176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 137276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir->array_index->accept(this); 137376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 137476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 13758258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt this->result, src_reg_for_float(element_size)); 137676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1377f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 1378f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 137976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 138076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 138176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt this->result = src_reg; 138276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt return; 138376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt } 138476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt 1385264ba1ab88f273dc92add8018f24edcdd67fa5e5Eric Anholt if (var && 1386264ba1ab88f273dc92add8018f24edcdd67fa5e5Eric Anholt strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform && 1387dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt !var->type->is_matrix()) { 1388dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_dereference_record *record = NULL; 1389dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (ir->array->ir_type == ir_type_dereference_record) 1390dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt record = (ir_dereference_record *)ir->array; 1391dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1392dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(index || !"FINISHME: variable-indexed builtin uniform access"); 1393dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1394dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt this->result = get_builtin_uniform_reg(prog, 1395dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt var->name, 1396dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt index->value.i[0], 1397dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt record ? record->field : NULL); 1398dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 1399dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1400ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt ir->array->accept(this); 14010161515c395c44233529c8d51f823b60050bc7baEric Anholt src_reg = this->result; 14024e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt 14034d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (index) { 14044d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.index += index->value.i[0] * element_size; 14054e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } else { 14064d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg array_base = this->result; 14074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt /* Variable index array dereference. It eats the "vec4" of the 14084d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * base of the array and an index that offsets the Mesa register 14094d5da50b94115d055ba8d0ff8717054582665384Eric Anholt * index. 14104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt */ 14114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir->array_index->accept(this); 14128258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 14134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_src_reg index_reg; 14148258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt 14154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt if (element_size == 1) { 14164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = this->result; 14174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt } else { 14184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt index_reg = get_temp(glsl_type::float_type); 1419f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt 14204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, 14214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt ir_to_mesa_dst_reg_from_src(index_reg), 14224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt this->result, src_reg_for_float(element_size)); 1423bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt } 14244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt 14254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg); 14264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg)); 14274e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt } 142884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 142984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt /* If the type is smaller than a vec4, replicate the last channel out. */ 143085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt if (ir->type->is_scalar() || ir->type->is_vector()) 143185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = swizzle_for_size(ir->type->vector_elements); 143285e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt else 143385e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt src_reg.swizzle = SWIZZLE_NOOP; 143484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14350161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result = src_reg; 143684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 143784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 14382c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid 14392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir) 14402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{ 14412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt unsigned int i; 14420161515c395c44233529c8d51f823b60050bc7baEric Anholt const glsl_type *struct_type = ir->record->type; 14432c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt int offset = 0; 1444dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir_variable *var = ir->record->variable_referenced(); 1445dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1446dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) { 1447dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt assert(var); 1448dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 1449dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt this->result = get_builtin_uniform_reg(prog, 1450dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt var->name, 1451dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt 0, 1452dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt ir->field); 1453dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt return; 1454dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt } 14552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 14560161515c395c44233529c8d51f823b60050bc7baEric Anholt ir->record->accept(this); 14572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 14582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt for (i = 0; i < struct_type->length; i++) { 14590161515c395c44233529c8d51f823b60050bc7baEric Anholt if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0) 14602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt break; 14612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt offset += type_size(struct_type->fields.structure[i].type); 14622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt } 146385e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt this->result.swizzle = swizzle_for_size(ir->type->vector_elements); 14640161515c395c44233529c8d51f823b60050bc7baEric Anholt this->result.index += offset; 14652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt} 14662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt 14672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/** 14682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage 14692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the 14702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler. 14712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */ 14720161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg 1473fc63e37b971b641dfdff000ba353c4810414c20eIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v) 1474b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{ 14755a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* The LHS must be a dereference. If the LHS is a variable indexed array 14765a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * access of a vector, it must be separated into a series conditional moves 14775a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * before reaching this point (see ir_vec_index_to_cond_assign). 14785a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 14795a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->as_dereference()); 1480ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt ir_dereference_array *deref_array = ir->as_dereference_array(); 1481ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt if (deref_array) { 1482ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt assert(!deref_array->array->type->is_vector()); 1483ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt } 1484ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt 14850161515c395c44233529c8d51f823b60050bc7baEric Anholt /* Use the rvalue deref handler for the most part. We'll ignore 14860161515c395c44233529c8d51f823b60050bc7baEric Anholt * swizzles in it and write swizzles using writemask, though. 14870161515c395c44233529c8d51f823b60050bc7baEric Anholt */ 14882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt ir->accept(v); 14895a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick return ir_to_mesa_dst_reg_from_src(v->result); 1490cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt} 1491cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir) 149484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 14950161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_dst_reg l; 14960161515c395c44233529c8d51f823b60050bc7baEric Anholt struct ir_to_mesa_src_reg r; 14977d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt int i; 149884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 149984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->rhs->accept(this); 150084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt r = this->result; 1501cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 1502fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick l = get_assignment_lhs(ir->lhs, this); 1503cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt 15045a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This should really set to the correct maximal writemask for each 15055a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: component written (in the loops below). This case can only 15065a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: occur for matrices, arrays, and structures. 15075a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 15085a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick if (ir->write_mask == 0) { 15095a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector()); 15105a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 15115a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else if (ir->lhs->type->is_scalar()) { 15125a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick /* FINISHME: This hack makes writing to gl_FragData, which lives in the 15135a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick * FINISHME: W component of fragment shader output zero, work correctly. 15145a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick */ 15155a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = WRITEMASK_XYZW; 15165a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } else { 15175a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick assert(ir->lhs->type->is_vector()); 15185a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick l.writemask = ir->write_mask; 15195a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick } 15205a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick 15210161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(l.file != PROGRAM_UNDEFINED); 15220161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(r.file != PROGRAM_UNDEFINED); 152384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1524346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt if (ir->condition) { 15252d1789e667c4180777829f96856daf91326721b9Eric Anholt ir_to_mesa_src_reg condition; 15262d1789e667c4180777829f96856daf91326721b9Eric Anholt 15272d1789e667c4180777829f96856daf91326721b9Eric Anholt ir->condition->accept(this); 15282d1789e667c4180777829f96856daf91326721b9Eric Anholt condition = this->result; 15292d1789e667c4180777829f96856daf91326721b9Eric Anholt 15302d1789e667c4180777829f96856daf91326721b9Eric Anholt /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves, 15312d1789e667c4180777829f96856daf91326721b9Eric Anholt * and the condition we produced is 0.0 or 1.0. By flipping the 15322d1789e667c4180777829f96856daf91326721b9Eric Anholt * sign, we can choose which value OPCODE_CMP produces without 15332d1789e667c4180777829f96856daf91326721b9Eric Anholt * an extra computing the condition. 15342d1789e667c4180777829f96856daf91326721b9Eric Anholt */ 15352d1789e667c4180777829f96856daf91326721b9Eric Anholt condition.negate = ~condition.negate; 15367d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 15377d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op3(ir, OPCODE_CMP, l, 15387d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt condition, r, ir_to_mesa_src_reg_from_dst(l)); 15397d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 15407d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 15417d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 15422d1789e667c4180777829f96856daf91326721b9Eric Anholt } else { 15437d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt for (i = 0; i < type_size(ir->lhs->type); i++) { 15447d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 15457d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt l.index++; 15467d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt r.index++; 15477d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt } 1548346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt } 154984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 155084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 155184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 155284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 155384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir) 155484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 15550161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_src_reg src_reg; 15560a46497a4ee3325fab47929cb17cfe2525e1fc33Vinson Lee GLfloat stack_vals[4] = { 0 }; 15570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt GLfloat *values = stack_vals; 15580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt unsigned int i; 155984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 15605b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt /* Unfortunately, 4 floats is all we can get into 15615b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * _mesa_add_unnamed_constant. So, make a temp to store an 15625b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * aggregate constant and move each constant value into it. If we 15635b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt * get lucky, copy propagation will eliminate the extra moves. 15645b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt */ 15655b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15665b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt if (ir->type->base_type == GLSL_TYPE_STRUCT) { 15675b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 15685b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 15695b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15705b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt foreach_iter(exec_list_iterator, iter, ir->components) { 15715b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_constant *field_value = (ir_constant *)iter.get(); 15725b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt int size = type_size(field_value->type); 15735b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15745b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt assert(size > 0); 15755b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15765b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt field_value->accept(this); 15775b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg = this->result; 15785b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15795b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt for (i = 0; i < (unsigned int)size; i++) { 15805b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 15815b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 15825b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt src_reg.index++; 15835b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt temp.index++; 15845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 15855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 15865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt this->result = temp_base; 15875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt return; 15885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt } 15895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt 159020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt if (ir->type->is_array()) { 159120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_src_reg temp_base = get_temp(ir->type); 159220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base); 159320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt int size = type_size(ir->type->fields.array); 159420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 159520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt assert(size > 0); 159620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 159720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (i = 0; i < ir->type->length; i++) { 159820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir->array_elements[i]->accept(this); 159920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg = this->result; 160020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt for (int j = 0; j < size; j++) { 160120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg); 160220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 160320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt src_reg.index++; 160420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt temp.index++; 160520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 160620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 160720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt this->result = temp_base; 160820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt return; 160920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt } 161020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt 1611ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt if (ir->type->is_matrix()) { 1612c91809e1e4a4fa8884e6588159368ea32431ee0eEric Anholt ir_to_mesa_src_reg mat = get_temp(ir->type); 1613ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat); 1614ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1615ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt for (i = 0; i < ir->type->matrix_columns; i++) { 1616ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt assert(ir->type->base_type == GLSL_TYPE_FLOAT); 1617ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt values = &ir->value.f[i * ir->type->vector_elements]; 1618ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 16199c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL); 1620ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters, 16219c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 16229c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 16239c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &src_reg.swizzle); 1624ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg); 1625ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1626ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt mat_column.index++; 1627ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt } 1628ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt 1629ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt this->result = mat; 1630ebef04011736ea8e13692fed87623d425c4d1b08Eric Anholt return; 1631582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt } 16320bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 16330bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt src_reg.file = PROGRAM_CONSTANT; 16340bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt switch (ir->type->base_type) { 16350bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_FLOAT: 16360bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values = &ir->value.f[0]; 16370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 16380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_UINT: 16390bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 16400bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.u[i]; 16410bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 16420bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 16430bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_INT: 16440bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 16450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.i[i]; 16460bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 16470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 16480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt case GLSL_TYPE_BOOL: 16490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt for (i = 0; i < ir->type->vector_elements; i++) { 16500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt values[i] = ir->value.b[i]; 16510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 16520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt break; 16530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt default: 16540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt assert(!"Non-float/uint/int/bool constant"); 16550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt } 16560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt 16579c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type); 16589c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters, 16599c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt values, 16609c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir->type->vector_elements, 16619c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt &this->result.swizzle); 166284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 166384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 16647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry * 16657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig) 16667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{ 16677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry; 16687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, this->function_signatures) { 16707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = (function_entry *)iter.get(); 16717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig == sig) 16737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 16747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 16757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry = talloc(mem_ctx, function_entry); 16777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig = sig; 16787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->sig_id = this->next_signature_id++; 16797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = NULL; 16807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Allocate storage for all the parameters. */ 16827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, sig->parameters) { 16837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)iter.get(); 1684b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage; 16857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt storage = find_variable_storage(param); 16877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!storage); 16887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1689b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY, 1690b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->next_temp); 1691b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt this->variables.push_tail(storage); 16927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 16937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->next_temp += type_size(param->type); 16947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 16957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 1696576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt if (!sig->return_type->is_void()) { 16977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = get_temp(sig->return_type); 16987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } else { 16997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->return_reg = ir_to_mesa_undef; 17007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->function_signatures.push_tail(entry); 17037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt return entry; 17047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt} 170584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 170684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 170784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir) 170884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 17097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_instruction *call_inst; 17107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_function_signature *sig = ir->get_callee(); 17117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = get_function_signature(sig); 17127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 17137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process in parameters. */ 17157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt exec_list_iterator sig_iter = sig->parameters.iterator(); 17167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 17177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 17187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 17197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_in || 17217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1722b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 17237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 17247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 17267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 17277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 17297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.file = storage->file; 17307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index = storage->index; 17317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.reladdr = NULL; 17327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.writemask = WRITEMASK_XYZW; 17337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.cond_mask = COND_TR; 17347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 17367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 17377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 17387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 17397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 17437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 17457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit call instruction */ 17477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL, 17487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 17497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt call_inst->function = entry; 17507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process out parameters. */ 17527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter = sig->parameters.iterator(); 17537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, *ir) { 17547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 17557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_variable *param = (ir_variable *)sig_iter.get(); 17567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (param->mode == ir_var_out || 17587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param->mode == ir_var_inout) { 1759b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt variable_storage *storage = find_variable_storage(param); 17607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(storage); 17617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r; 17637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.file = storage->file; 17647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index = storage->index; 17657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.reladdr = NULL; 17667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.swizzle = SWIZZLE_NOOP; 17677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.negate = 0; 17687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt param_rval->accept(this); 17707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result); 17717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(param->type); i++) { 17737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 17747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 17757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 17767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt sig_iter.next(); 17807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 17817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt assert(!sig_iter.has_next()); 17827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 17837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Process return value. */ 17847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt this->result = entry->return_reg; 178584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 178684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 1787aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtclass get_sampler_name : public ir_hierarchical_visitor 1788aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt{ 1789aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtpublic: 1790aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt get_sampler_name(ir_to_mesa_visitor *mesa, ir_dereference *last) 1791aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt { 1792aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->mem_ctx = mesa->mem_ctx; 1793aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->mesa = mesa; 1794aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->name = NULL; 1795aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->offset = 0; 1796aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->last = last; 1797aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1798aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1799aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt virtual ir_visitor_status visit(ir_dereference_variable *ir) 1800aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt { 1801aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->name = ir->var->name; 1802aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt return visit_continue; 1803aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1804aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1805aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt virtual ir_visitor_status visit_leave(ir_dereference_record *ir) 1806aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt { 1807aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->name = talloc_asprintf(mem_ctx, "%s.%s", name, ir->field); 1808aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt return visit_continue; 1809aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1810aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1811aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt virtual ir_visitor_status visit_leave(ir_dereference_array *ir) 1812aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt { 1813aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt ir_constant *index = ir->array_index->as_constant(); 1814aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt int i; 1815aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1816aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index) { 1817aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt i = index->value.i[0]; 1818aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } else { 1819aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* GLSL 1.10 and 1.20 allowed variable sampler array indices, 1820aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * while GLSL 1.30 requires that the array indices be 1821aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * constant integer expressions. We don't expect any driver 1822aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * to actually work with a really variable array index, so 1823aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * all that would work would be an unrolled loop counter that ends 1824aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * up being constant above. 1825aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 1826aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt mesa->shader_program->InfoLog = 1827aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt talloc_asprintf_append(mesa->shader_program->InfoLog, 1828aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "warning: Variable sampler array index " 1829aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "unsupported.\nThis feature of the language " 1830aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "was removed in GLSL 1.20 and is unlikely " 1831aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "to be supported for 1.10 in Mesa.\n"); 1832aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt i = 0; 1833aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1834aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (ir != last) { 1835aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->name = talloc_asprintf(mem_ctx, "%s[%d]", name, i); 1836aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } else { 1837aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt offset = i; 1838aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1839aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt return visit_continue; 1840aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1841aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1842aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt ir_to_mesa_visitor *mesa; 1843aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt const char *name; 1844aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt void *mem_ctx; 1845aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt int offset; 1846aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt ir_dereference *last; 1847aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt}; 1848aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1849aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtint 1850aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholtir_to_mesa_visitor::get_sampler_uniform_value(ir_dereference *sampler) 1851aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt{ 1852aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt get_sampler_name getname(this, sampler); 1853aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1854aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt sampler->accept(&getname); 1855aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1856aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, 1857aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt getname.name); 1858aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1859aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index < 0) { 1860aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->shader_program->InfoLog = 1861aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt talloc_asprintf_append(this->shader_program->InfoLog, 1862aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "failed to find sampler named %s.\n", 1863aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt getname.name); 1864aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt this->shader_program->LinkStatus = GL_FALSE; 1865aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt return 0; 1866aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 1867aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1868aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt index += getname.offset; 1869aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 1870aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt return this->prog->Parameters->ParameterValues[index][0]; 1871aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt} 187284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 187384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 187484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir) 187584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 18769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt ir_to_mesa_src_reg result_src, coord, lod_info, projector; 1877d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_dst_reg result_dst, coord_dst; 1878d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir_to_mesa_instruction *inst = NULL; 1879d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt prog_opcode opcode = OPCODE_NOP; 188084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 188184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir->coordinate->accept(this); 1882d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1883d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Put our coords in a temp. We'll need to modify them for shadow, 1884d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projection, or LOD, so the only case we'd use it as is is if 1885d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * we're doing plain old texturing. Mesa IR optimization should 1886d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * handle cleaning up our mess in that case. 1887d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1888d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord = get_temp(glsl_type::vec4_type); 1889d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst = ir_to_mesa_dst_reg_from_src(coord); 1890d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, 1891d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt this->result); 1892d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1893de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt if (ir->projector) { 1894de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt ir->projector->accept(this); 1895de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt projector = this->result; 1896de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt } 1897de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt 1898d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt /* Storage for our result. Ideally for an assignment we'd be using 1899d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt * the actual storage for the result here, instead. 1900d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt */ 1901d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_src = get_temp(glsl_type::vec4_type); 1902d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt result_dst = ir_to_mesa_dst_reg_from_src(result_src); 1903d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1904d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt switch (ir->op) { 1905d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_tex: 1906d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TEX; 1907d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1908d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txb: 1909d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXB; 1910d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.bias->accept(this); 1911d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1912d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1913d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txl: 1914d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXL; 1915d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt ir->lod_info.lod->accept(this); 1916d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt lod_info = this->result; 1917d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1918d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txd: 1919d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case ir_txf: 1920d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt assert(!"GLSL 1.30 features unsupported"); 1921d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1922d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 1923d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1924d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (ir->projector) { 1925d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TEX) { 1926d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Slot the projector in as the last component of the coord. */ 1927d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1928d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector); 1929d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1930d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt opcode = OPCODE_TXP; 1931d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } else { 1932d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_src_reg coord_w = coord; 1933d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_w.swizzle = SWIZZLE_WWWW; 1934d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1935d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* For the other TEX opcodes there's no projective version 1936d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * since the last slot is taken up by lod info. Do the 1937d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt * projective divide now. 1938d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt */ 1939d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1940d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector); 1941d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1942d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZ; 1943d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w); 1944d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1945d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1946d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord.swizzle = SWIZZLE_XYZW; 1947d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1948d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1949d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1950b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) { 1951b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt /* Slot the shadow value in as the second to last component of the 1952b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt * coord. 1953b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt */ 1954b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir->shadow_comparitor->accept(this); 1955b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_Z; 1956b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result); 1957b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1958b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt } 1959b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1960d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) { 1961d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt /* Mesa IR stores lod or lod bias in the last channel of the coords. */ 1962d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_W; 1963d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info); 1964d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt coord_dst.writemask = WRITEMASK_XYZW; 1965d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt } 1966d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1967d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord); 1968d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt 1969b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt if (ir->shadow_comparitor) 1970b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt inst->tex_shadow = GL_TRUE; 1971b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt 1972aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt inst->sampler = get_sampler_uniform_value(ir->sampler); 1973c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt 1974aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt const glsl_type *sampler_type = ir->sampler->type; 1975d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 1976c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt switch (sampler_type->sampler_dimensionality) { 1977d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_1D: 1978c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 19790a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX; 1980d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1981d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_2D: 1982c234d0b25f622a7bdd3c40bc72fdbd59d8494c7cEric Anholt inst->tex_target = (sampler_type->sampler_array) 19830a86d766ef0d98abd3373609a637bf137203e994Ian Romanick ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX; 1984d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1985d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_3D: 1986d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_3D_INDEX; 1987d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 1988d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt case GLSL_SAMPLER_DIM_CUBE: 1989d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt inst->tex_target = TEXTURE_CUBE_INDEX; 1990d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt break; 19910bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick case GLSL_SAMPLER_DIM_RECT: 19920bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick inst->tex_target = TEXTURE_RECT_INDEX; 19930bf63733e54b47daf9f50c32a1fca4039c82def2Ian Romanick break; 199468772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick case GLSL_SAMPLER_DIM_BUF: 199568772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"FINISHME: Implement ARB_texture_buffer_object"); 199668772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick break; 1997d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt default: 199868772031e6242aa78864dc9c7c1a607aec5ee7b9Ian Romanick assert(!"Should not get here."); 1999d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2000d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2001d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt this->result = result_src; 200284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 200384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 200484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 200584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir) 200684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 20077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (ir->get_value()) { 20087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_dst_reg l; 20097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt int i; 20107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 201135220fc5981045331b4f048f0fc2e1371a0673edEric Anholt assert(current_function); 201235220fc5981045331b4f048f0fc2e1371a0673edEric Anholt 20137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir->get_value()->accept(this); 20147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_src_reg r = this->result; 201584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 20167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l = ir_to_mesa_dst_reg_from_src(current_function->return_reg); 20177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt for (i = 0; i < type_size(current_function->sig->return_type); i++) { 20197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r); 20207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt l.index++; 20217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt r.index++; 20227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 20247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 20257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt ir_to_mesa_emit_op0(ir, OPCODE_RET); 202684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 202784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 202816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid 202916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir) 203016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{ 20315e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt assert(ir->condition == NULL); /* FINISHME */ 203216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke 2033021222c6a872ca2eef770ebadb8754f659775204Eric Anholt ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV); 203416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke} 203584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 203684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid 203784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir) 203884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 2039854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL; 2040cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_instruction *prev_inst; 2041cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2042cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2043c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2044c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir->condition->accept(this); 20450161515c395c44233529c8d51f823b60050bc7baEric Anholt assert(this->result.file != PROGRAM_UNDEFINED); 2046c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2047854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if (ctx->Shader.EmitCondCodes) { 2048854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail(); 2049cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt 2050cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt /* See if we actually generated any instruction for generating 2051cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * the condition. If not, then cook up a move to a temp so we 2052cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt * have something to set cond_update on. 2053cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt */ 2054cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt if (cond_inst == prev_inst) { 2055cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type); 2056cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV, 2057cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt ir_to_mesa_dst_reg_from_src(temp), 2058cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt result); 2059cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt } 2060854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt cond_inst->cond_update = GL_TRUE; 2061854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt 2062021222c6a872ca2eef770ebadb8754f659775204Eric Anholt if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF); 2063854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst->dst_reg.cond_mask = COND_NE; 2064854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } else { 2065854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, 2066854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt OPCODE_IF, ir_to_mesa_undef_dst, 2067854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt this->result); 2068854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt } 2069c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2070c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt this->instructions.push_tail(if_inst); 2071c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt visit_exec_list(&ir->then_instructions, this); 2073c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2074c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if (!ir->else_instructions.is_empty()) { 2075021222c6a872ca2eef770ebadb8754f659775204Eric Anholt else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE); 20760a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt visit_exec_list(&ir->else_instructions, this); 2077c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2078c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 20790161515c395c44233529c8d51f823b60050bc7baEric Anholt if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF, 20800161515c395c44233529c8d51f823b60050bc7baEric Anholt ir_to_mesa_undef_dst, ir_to_mesa_undef); 208184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 208284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2083ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor() 2084ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{ 20850161515c395c44233529c8d51f823b60050bc7baEric Anholt result.file = PROGRAM_UNDEFINED; 2086ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt next_temp = 1; 20877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt next_signature_id = 1; 20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt current_function = NULL; 2089abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt mem_ctx = talloc_new(NULL); 2090ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt} 2091ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt 2092fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor() 2093fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{ 2094abc6d7e0b4b04c75129d24c3cb6f021b92cd46f6Eric Anholt talloc_free(mem_ctx); 2095fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt} 2096fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt 209784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register 209884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg) 209984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 210084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_src_register mesa_reg; 210184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 210284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.File = reg.file; 2103aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt assert(reg.index < (1 << INST_INDEX_BITS) - 1); 210484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_reg.Index = reg.index; 210534195832669f0eb7c4a80997cc524f8d10319307Eric Anholt mesa_reg.Swizzle = reg.swizzle; 2106f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_reg.RelAddr = reg.reladdr != NULL; 2107ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt mesa_reg.Negate = reg.negate; 2108285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt mesa_reg.Abs = 0; 2109b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt mesa_reg.HasIndex2 = GL_FALSE; 2110405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.RelAddr2 = 0; 2111405546882a010885d342b0b40392de0da289374eVinson Lee mesa_reg.Index2 = 0; 211284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 211384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt return mesa_reg; 211484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt} 211584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 2116c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 21177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v, 21187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt struct prog_instruction *mesa_instructions, 2119c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2120c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2121e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke int if_count = 0, loop_count = 0; 212264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int *if_stack, *loop_stack; 212364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int if_stack_pos = 0, loop_stack_pos = 0; 212464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt int i, j; 2125c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2126c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 212764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt switch (mesa_instructions[i].Opcode) { 212864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_IF: 2129c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_count++; 213064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 213164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 213264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_count++; 213364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 213464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BRK: 213564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_CONT: 213664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = -1; 213764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 213864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt default: 213964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 214064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 2141c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2142c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 21433ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt if_stack = talloc_zero_array(v->mem_ctx, int, if_count); 21443ef83d270b2c24867a0d020b81bdc6c54cb1c9b0Eric Anholt loop_stack = talloc_zero_array(v->mem_ctx, int, loop_count); 2145c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2146c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2147c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt switch (mesa_instructions[i].Opcode) { 2148c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_IF: 214964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos] = i; 2150c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos++; 2151c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2152c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ELSE: 215364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 215464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if_stack[if_stack_pos - 1] = i; 2155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2156c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt case OPCODE_ENDIF: 215764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i; 2158c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt if_stack_pos--; 2159c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 216064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_BGNLOOP: 216164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack[loop_stack_pos] = i; 216264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos++; 216364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt break; 216464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt case OPCODE_ENDLOOP: 216564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt loop_stack_pos--; 216664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* Rewrite any breaks/conts at this nesting level (haven't 216764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * already had a BranchTarget assigned) to point to the end 216864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt * of the loop. 216964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt */ 217064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt for (j = loop_stack[loop_stack_pos]; j < i; j++) { 217164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].Opcode == OPCODE_BRK || 217264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].Opcode == OPCODE_CONT) { 217364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (mesa_instructions[j].BranchTarget == -1) { 217464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[j].BranchTarget = i; 217564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 217664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 217764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt } 217864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt /* The loop ends point at each other. */ 217964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos]; 218064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i; 21817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 21827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt case OPCODE_CAL: 21837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v->function_signatures) { 21847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 21857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 21867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (entry->sig_id == mesa_instructions[i].BranchTarget) { 21877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_instructions[i].BranchTarget = entry->inst; 21887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 21897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 21917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt break; 2192c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt default: 2193c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt break; 2194c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2195c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2196c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2197c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2198c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void 2199c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions, 2200c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation, 2201c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int num_instructions) 2202c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{ 2203c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *last_ir = NULL; 2204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2205748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int indent = 0; 2206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt for (i = 0; i < num_instructions; i++) { 2208c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt struct prog_instruction *mesa_inst = mesa_instructions + i; 2209c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction *ir = mesa_instruction_annotation[i]; 2210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2211748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, "%3d: ", i); 2212748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 221364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt if (last_ir != ir && ir) { 2214748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt int j; 2215748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2216748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt for (j = 0; j < indent; j++) { 2217748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); 2218748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt } 2219748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt ir->print(); 2220c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt printf("\n"); 2221c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt last_ir = ir; 2222748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt 2223748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt fprintf(stdout, " "); /* line number spacing. */ 2224c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2225c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2226748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent, 2227748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt PROG_PRINT_DEBUG, NULL); 2228c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt } 2229c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt} 2230c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2231ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void 2232ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog) 2233ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{ 2234d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt unsigned int i; 2235d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed = 0; 2237ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 2238ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt for (i = 0; i < prog->NumInstructions; i++) { 2239ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt struct prog_instruction *inst = &prog->Instructions[i]; 2240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2241d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (_mesa_is_tex_instruction(inst->Opcode)) { 2242d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplerTargets[inst->TexSrcUnit] = 2243d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt (gl_texture_index)inst->TexSrcTarget; 2244d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->SamplersUsed |= 1 << inst->TexSrcUnit; 2245d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt if (inst->TexShadow) { 2246d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt prog->ShadowSamplers |= 1 << inst->TexSrcUnit; 2247d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2248d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt } 2249ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt } 2250d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt 2251d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt _mesa_update_shader_textures_used(prog); 2252ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt} 2253ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt 22540924ba0c3496160a134d37cec800f902ae805b9cEric Anholt/* Add the uniforms to the parameters. The linker chose locations 22550924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * in our parameters lists (which weren't created yet), which the 22560924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * uniforms code will use to poke values into our parameters list 22570924ba0c3496160a134d37cec800f902ae805b9cEric Anholt * when uniforms are updated. 225885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */ 225985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void 22600924ba0c3496160a134d37cec800f902ae805b9cEric Anholtadd_uniforms_to_parameters_list(struct gl_shader_program *shader_program, 22610924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_shader *shader, 22620924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_program *prog) 226385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{ 226485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt unsigned int i; 2265aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt unsigned int next_sampler = 0; 226685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 22670924ba0c3496160a134d37cec800f902ae805b9cEric Anholt for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) { 22680924ba0c3496160a134d37cec800f902ae805b9cEric Anholt struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i; 22690924ba0c3496160a134d37cec800f902ae805b9cEric Anholt const glsl_type *type = uniform->Type; 22700924ba0c3496160a134d37cec800f902ae805b9cEric Anholt unsigned int size; 22710924ba0c3496160a134d37cec800f902ae805b9cEric Anholt int parameter_index = -1; 22720924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 22730924ba0c3496160a134d37cec800f902ae805b9cEric Anholt switch (shader->Type) { 22740924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_VERTEX_SHADER: 22750924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->VertPos; 22760924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 22770924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_FRAGMENT_SHADER: 22780924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->FragPos; 22790924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 22800924ba0c3496160a134d37cec800f902ae805b9cEric Anholt case GL_GEOMETRY_SHADER: 22810924ba0c3496160a134d37cec800f902ae805b9cEric Anholt parameter_index = uniform->GeomPos; 22820924ba0c3496160a134d37cec800f902ae805b9cEric Anholt break; 22830924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 22840924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 22850924ba0c3496160a134d37cec800f902ae805b9cEric Anholt /* Only add uniforms used in our target. */ 22860924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (parameter_index == -1) 22870924ba0c3496160a134d37cec800f902ae805b9cEric Anholt continue; 22880924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 22890924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_vector() || 22900924ba0c3496160a134d37cec800f902ae805b9cEric Anholt type->is_scalar()) { 22910924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type->vector_elements; 22920924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } else { 22930924ba0c3496160a134d37cec800f902ae805b9cEric Anholt size = type_size(type) * 4; 22940924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 22950924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2296aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt gl_register_file file; 22970924ba0c3496160a134d37cec800f902ae805b9cEric Anholt if (type->is_sampler() || 22980924ba0c3496160a134d37cec800f902ae805b9cEric Anholt (type->is_array() && type->fields.array->is_sampler())) { 2299aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_SAMPLER; 2300aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } else { 2301aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt file = PROGRAM_UNIFORM; 2302aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 230385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 2304aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1, 2305aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name); 23060924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 2307aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index < 0) { 2308aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt index = _mesa_add_parameter(prog->Parameters, file, 2309aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt uniform->Name, size, type->gl_type, 2310aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt NULL, NULL, 0x0); 2311aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2312aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* Sampler uniform values are stored in prog->SamplerUnits, 2313aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * and the entry in that array is selected by this index we 2314aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * store in ParameterValues[]. 2315aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2316aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (file == PROGRAM_SAMPLER) { 2317aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt for (unsigned int j = 0; j < size / 4; j++) 2318aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt prog->Parameters->ParameterValues[index + j][0] = next_sampler++; 2319aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt } 2320aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt 2321aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt /* The location chosen in the Parameters list here (returned 2322aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt * from _mesa_add_uniform) has to match what the linker chose. 2323aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt */ 2324aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt if (index != parameter_index) { 2325aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt shader_program->InfoLog = 2326aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt talloc_asprintf_append(shader_program->InfoLog, 2327aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "Allocation of uniform `%s' to target " 2328aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt "failed (%d vs %d)\n", uniform->Name, 2329aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt index, parameter_index); 2330aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt shader_program->LinkStatus = false; 23310924ba0c3496160a134d37cec800f902ae805b9cEric Anholt } 233285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 233385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt } 233485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt} 233585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt 23362f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 23372f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtset_uniform_initializer(GLcontext *ctx, void *mem_ctx, 23382f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program, 23392f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *name, const glsl_type *type, 23402f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *val) 23412f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 23422f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_record()) { 23432f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *field_constant; 23442f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23452f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)val->components.get_head(); 23462f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23472f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < type->length; i++) { 23482f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *field_type = type->fields.structure[i].type; 23492f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name, 23502f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt type->fields.structure[i].name); 23512f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, field_name, 23522f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_type, field_constant); 23532f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt field_constant = (ir_constant *)field_constant->next; 23542f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23552f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt return; 23562f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23572f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23582f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int loc = _mesa_get_uniform_location(ctx, shader_program, name); 23592f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23602f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (loc == -1) { 23612f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt shader_program->InfoLog = 23622f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt talloc_asprintf_append(shader_program->InfoLog, 23632f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt "Couldn't find uniform for " 23642f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt "initializer %s\n", name); 23652f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt shader_program->LinkStatus = false; 23662f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt abort(); 23672f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23682f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23692f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) { 23702f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_constant *element; 23712f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt const glsl_type *element_type; 23722f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (type->is_array()) { 23732f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val->array_elements[i]; 23742f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type->fields.array; 23752f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 23762f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element = val; 23772f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = type; 23782f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23792f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23802f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *values; 23812f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23822f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->base_type == GLSL_TYPE_BOOL) { 23832f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt int *conv = talloc_array(mem_ctx, int, element_type->components()); 23842f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int j = 0; j < element_type->components(); j++) { 23852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt conv[j] = element->value.b[j]; 23862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23872f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = (void *)conv; 23882f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type = glsl_type::get_instance(GLSL_TYPE_INT, 23892f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 23902f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 1); 23912f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 23922f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values = &element->value; 23932f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 23942f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 23952f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (element_type->is_matrix()) { 23962f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform_matrix(ctx, shader_program, 23972f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->matrix_columns, 23982f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt element_type->vector_elements, 23992f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc, 1, GL_FALSE, (GLfloat *)values); 24002f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += element_type->matrix_columns; 24012f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } else { 24022f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns, 24032f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt values, element_type->gl_type); 24042f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt loc += type_size(element_type); 24052f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 24062f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 24072f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 24082f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24092f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtstatic void 24102f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholtset_uniform_initializers(GLcontext *ctx, 24112f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader_program *shader_program) 24122f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt{ 24132f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt void *mem_ctx = NULL; 24142f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24152f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) { 24162f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt struct gl_shader *shader = shader_program->_LinkedShaders[i]; 24172f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt foreach_iter(exec_list_iterator, iter, *shader->ir) { 24182f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_instruction *ir = (ir_instruction *)iter.get(); 24192f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt ir_variable *var = ir->as_variable(); 24202f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24212f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!var || var->mode != ir_var_uniform || !var->constant_value) 24222f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt continue; 24232f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24242f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt if (!mem_ctx) 24252f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt mem_ctx = talloc_new(NULL); 24262f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24272f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializer(ctx, mem_ctx, shader_program, var->name, 24282f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt var->type, var->constant_value); 24292f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 24302f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt } 24312f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 24322f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt talloc_free(mem_ctx); 24332f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt} 24342f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 2435364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program * 243695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program, 243795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt struct gl_shader *shader) 243884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{ 243984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_visitor v; 244084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt struct prog_instruction *mesa_instructions, *mesa_inst; 2441c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt ir_instruction **mesa_instruction_annotation; 2442c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt int i; 2443364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt struct gl_program *prog; 2444364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt GLenum target; 2445c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt const char *target_string; 24467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt GLboolean progress; 2447364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2448364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt switch (shader->Type) { 2449c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_VERTEX_SHADER: 2450c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_VERTEX_PROGRAM_ARB; 2451c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "vertex"; 2452c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2453c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt case GL_FRAGMENT_SHADER: 2454c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target = GL_FRAGMENT_PROGRAM_ARB; 2455c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt target_string = "fragment"; 2456c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2457c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt default: 2458c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt assert(!"should not be reached"); 2459c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt break; 2460364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 246184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 24621124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt validate_ir_tree(shader->ir); 24631124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt 2464859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name); 2465364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!prog) 2466364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return NULL; 2467364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Parameters = _mesa_new_parameter_list(); 2468364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2469364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Attributes = _mesa_new_parameter_list(); 2470364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.ctx = ctx; 2471364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt v.prog = prog; 2472aa452e20bff9aea2ecb994c9f7b413b0726a04f3Eric Anholt v.shader_program = shader_program; 2473364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 24740924ba0c3496160a134d37cec800f902ae805b9cEric Anholt add_uniforms_to_parameters_list(shader_program, shader, prog); 24750924ba0c3496160a134d37cec800f902ae805b9cEric Anholt 24767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Emit Mesa IR for main(). */ 247716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt visit_exec_list(shader->ir, &v); 2478021222c6a872ca2eef770ebadb8754f659775204Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_END); 247984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 24807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt /* Now emit bodies for any functions that were used. */ 24817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt do { 24827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_FALSE; 24837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt foreach_iter(exec_list_iterator, iter, v.function_signatures) { 24857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt function_entry *entry = (function_entry *)iter.get(); 24867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt if (!entry->bgn_inst) { 24887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt v.current_function = entry; 24897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB); 24917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt entry->bgn_inst->function = entry; 24927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 24937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt visit_exec_list(&entry->sig->body, &v); 24947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2495806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt ir_to_mesa_instruction *last; 2496806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt last = (ir_to_mesa_instruction *)v.instructions.get_tail(); 2497806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt if (last->op != OPCODE_RET) 2498806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt v.ir_to_mesa_emit_op0(NULL, OPCODE_RET); 2499806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt 250040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt ir_to_mesa_instruction *end; 250140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB); 250240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt end->function = entry; 250340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt 25047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt progress = GL_TRUE; 25057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 25067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } 25077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt } while (progress); 25087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 2509364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumTemporaries = v.next_temp; 2510364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 251184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt int num_instructions = 0; 251284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 251384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt num_instructions++; 251484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 251584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 251684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_instructions = 251784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt (struct prog_instruction *)calloc(num_instructions, 251884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt sizeof(*mesa_instructions)); 2519850c659044d081c53713800cacf8d518fae6cd70Eric Anholt mesa_instruction_annotation = talloc_array(v.mem_ctx, ir_instruction *, 2520364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 252184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt 252284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst = mesa_instructions; 2523c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i = 0; 252484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt foreach_iter(exec_list_iterator, iter, v.instructions) { 252584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); 2526b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt 252784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->Opcode = inst->op; 2528854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->CondUpdate = inst->cond_update; 252984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.File = inst->dst_reg.file; 253084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->DstReg.Index = inst->dst_reg.index; 2531854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask; 253212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask; 2533f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL; 253484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]); 253584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]); 253684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); 2537d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcUnit = inst->sampler; 2538d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt mesa_inst->TexSrcTarget = inst->tex_target; 2539b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt mesa_inst->TexShadow = inst->tex_shadow; 2540c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt mesa_instruction_annotation[i] = inst->ir; 2541aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt 25425755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák /* Set IndirectRegisterFiles. */ 25435755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->DstReg.RelAddr) 25445755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->DstReg.File; 25455755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 25465755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák for (unsigned src = 0; src < 3; src++) 25475755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák if (mesa_inst->SrcReg[src].RelAddr) 25485755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák prog->IndirectRegisterFiles |= 1 << mesa_inst->SrcReg[src].File; 25495755d1d6a7ff68c7d690d67c4cd64ef8e01ec2edMarek Olšák 255095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) { 255195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->InfoLog = 255295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt talloc_asprintf_append(shader_program->InfoLog, 255395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt "Couldn't flatten if statement\n"); 255495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt shader_program->LinkStatus = false; 255595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt } 255695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt 255740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt switch (mesa_inst->Opcode) { 255840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_BGNSUB: 25597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt inst->function->inst = i; 256040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 256140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 256240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ENDSUB: 256340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt mesa_inst->Comment = strdup(inst->function->sig->function_name()); 256440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 256540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_CAL: 25667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */ 256740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 256840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt case OPCODE_ARL: 2569d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt prog->NumAddressRegs = 1; 257040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 257140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt default: 257240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt break; 257340f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt } 25747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt 257584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt mesa_inst++; 2576c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt i++; 257784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt } 2578c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 25797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt set_branchtargets(&v, mesa_instructions, num_instructions); 2580925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 2581c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2582455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2583455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("GLSL IR for linked %s program %d:\n", target_string, 2584455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2585455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt _mesa_print_ir(shader->ir, NULL); 2586455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2587455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("\n"); 2588455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt printf("Mesa IR for linked %s program %d:\n", target_string, 2589455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt shader_program->Name); 2590364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt print_program(mesa_instructions, mesa_instruction_annotation, 2591364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt num_instructions); 2592364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2593364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2594364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Instructions = mesa_instructions; 2595364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->NumInstructions = num_instructions; 2596364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2597925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt do_set_program_inouts(shader->ir, prog); 2598925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt count_resources(prog); 2599925b49ff310bf0b307add7c34627cddf87e6a554Eric Anholt 260016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_reference_program(ctx, &shader->Program, prog); 2601364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 260228faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) { 260328faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt _mesa_optimize_program(ctx, prog); 260428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt } 260528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt 2606364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt return prog; 2607364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2608364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 260916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" { 2610d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 2611d19eecef54384c163af27a470496ed885a5a271bEric Anholt_mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader) 2612d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 2613d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(shader->CompileStatus); 2614fc63e37b971b641dfdff000ba353c4810414c20eIan Romanick (void) ctx; 2615d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2616d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 2617d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 2618d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2619d19eecef54384c163af27a470496ed885a5a271bEric AnholtGLboolean 2620d19eecef54384c163af27a470496ed885a5a271bEric Anholt_mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog) 2621d19eecef54384c163af27a470496ed885a5a271bEric Anholt{ 2622d19eecef54384c163af27a470496ed885a5a271bEric Anholt assert(prog->LinkStatus); 2623d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2624d19eecef54384c163af27a470496ed885a5a271bEric Anholt for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { 2625d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool progress; 2626d19eecef54384c163af27a470496ed885a5a271bEric Anholt exec_list *ir = prog->_LinkedShaders[i]->ir; 2627d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2628d19eecef54384c163af27a470496ed885a5a271bEric Anholt do { 2629d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = false; 2630d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2631d19eecef54384c163af27a470496ed885a5a271bEric Anholt /* Lowering */ 2632d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mat_op_to_vec(ir); 2633d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_mod_to_fract(ir); 2634d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_div_to_mul_rcp(ir); 2635d19eecef54384c163af27a470496ed885a5a271bEric Anholt do_explog_to_explog2(ir); 2636d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2637d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_common_optimization(ir, true) || progress; 2638d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2639d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (ctx->Shader.EmitNoIfs) 2640d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_if_to_cond_assign(ir) || progress; 2641d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2642d19eecef54384c163af27a470496ed885a5a271bEric Anholt progress = do_vec_index_to_cond_assign(ir) || progress; 2643d19eecef54384c163af27a470496ed885a5a271bEric Anholt } while (progress); 2644d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2645d19eecef54384c163af27a470496ed885a5a271bEric Anholt validate_ir_tree(ir); 2646d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 2647d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2648d19eecef54384c163af27a470496ed885a5a271bEric Anholt for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { 2649d19eecef54384c163af27a470496ed885a5a271bEric Anholt struct gl_program *linked_prog; 2650d19eecef54384c163af27a470496ed885a5a271bEric Anholt bool ok = true; 2651d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2652d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); 2653d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2654d19eecef54384c163af27a470496ed885a5a271bEric Anholt switch (prog->_LinkedShaders[i]->Type) { 2655d19eecef54384c163af27a470496ed885a5a271bEric Anholt case GL_VERTEX_SHADER: 2656d19eecef54384c163af27a470496ed885a5a271bEric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, 2657d19eecef54384c163af27a470496ed885a5a271bEric Anholt (struct gl_vertex_program *)linked_prog); 2658d19eecef54384c163af27a470496ed885a5a271bEric Anholt ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, 2659d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog); 2660d19eecef54384c163af27a470496ed885a5a271bEric Anholt break; 2661d19eecef54384c163af27a470496ed885a5a271bEric Anholt case GL_FRAGMENT_SHADER: 2662d19eecef54384c163af27a470496ed885a5a271bEric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, 2663d19eecef54384c163af27a470496ed885a5a271bEric Anholt (struct gl_fragment_program *)linked_prog); 2664d19eecef54384c163af27a470496ed885a5a271bEric Anholt ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, 2665d19eecef54384c163af27a470496ed885a5a271bEric Anholt linked_prog); 2666d19eecef54384c163af27a470496ed885a5a271bEric Anholt break; 2667d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 2668d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (!ok) { 2669d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_FALSE; 2670d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 26713cd233eb5714137dccb6218ad78005511bcc02bdEric Anholt _mesa_reference_program(ctx, &linked_prog, NULL); 2672d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 2673d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2674d19eecef54384c163af27a470496ed885a5a271bEric Anholt return GL_TRUE; 2675d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 267616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt 267716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid 267816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader) 2679364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 26802462a536ea5c98867296905e3da127eba7c7bdffIan Romanick struct _mesa_glsl_parse_state *state = 26812462a536ea5c98867296905e3da127eba7c7bdffIan Romanick new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 26825e18b051c039564d1998818d08caf1bff3983630Ian Romanick 2683153eca98064252be4daad9cc27746f37c245b627Ian Romanick const char *source = shader->Source; 268406143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick state->error = preprocess(state, &source, &state->info_log, 268506143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick &ctx->Extensions); 2686153eca98064252be4daad9cc27746f37c245b627Ian Romanick 26871b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 26881b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("GLSL source for shader %d:\n", shader->Name); 26891b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt printf("%s\n", shader->Source); 26901b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt } 26911b708d8f4dd1a853de8537e81e6d5bf8c9f2aed1Eric Anholt 2692153eca98064252be4daad9cc27746f37c245b627Ian Romanick if (!state->error) { 2693153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_ctor(state, source); 2694153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_parse(state); 2695153eca98064252be4daad9cc27746f37c245b627Ian Romanick _mesa_glsl_lexer_dtor(state); 2696153eca98064252be4daad9cc27746f37c245b627Ian Romanick } 2697364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 26984a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt talloc_free(shader->ir); 269916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 2700364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (!state->error && !state->translation_unit.is_empty()) 270116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 2702364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 270316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 2704ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2705ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 27062f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt /* Do some optimization at compile time to reduce shader IR size 27072f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt * and reduce later work if the same shader is linked multiple times 27082f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt */ 27092f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt while (do_common_optimization(shader->ir, false)) 27102f4fe151681a6f6afe1d452eece6cf4144f44e49Eric Anholt ; 2711ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt 2712ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt validate_ir_tree(shader->ir); 2713364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2714364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2715364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->symbols = state->symbols; 2716364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2717364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->CompileStatus = !state->error; 2718364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt shader->InfoLog = state->info_log; 271925f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 2720d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 2721d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 2722d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 2723c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt 2724b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt if (ctx->Shader.Flags & GLSL_LOG) { 2725b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt _mesa_write_shader_to_file(shader); 2726b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt } 2727b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt 27280df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 27290df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->CompileStatus) { 27300df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL IR for shader %d:\n", shader->Name); 27310df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt _mesa_print_ir(shader->ir, NULL); 27320df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("\n\n"); 27330df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } else { 27340df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d failed to compile.\n", shader->Name); 27350df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 27360df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (shader->InfoLog && shader->InfoLog[0] != 0) { 27370df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader %d info log:\n", shader->Name); 27380df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", shader->InfoLog); 27390df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 2740455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt } 2741455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt 2742116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 27434a6a4316846ead3ec12759c96ecc4b61491aad65Eric Anholt reparent_ir(shader->ir, shader->ir); 2744116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 2745364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt talloc_free(state); 2746d19eecef54384c163af27a470496ed885a5a271bEric Anholt 2747d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (shader->CompileStatus) { 2748d19eecef54384c163af27a470496ed885a5a271bEric Anholt if (!ctx->Driver.CompileShader(ctx, shader)) 2749d19eecef54384c163af27a470496ed885a5a271bEric Anholt shader->CompileStatus = GL_FALSE; 2750d19eecef54384c163af27a470496ed885a5a271bEric Anholt } 2751d19eecef54384c163af27a470496ed885a5a271bEric Anholt} 2752364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2753364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid 2754364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog) 2755364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{ 2756364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt unsigned int i; 2757849e18153cd91d812f694b806a84008498860bc3Eric Anholt 2758364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_clear_shader_program_data(ctx, prog); 2759364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2760849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_TRUE; 2761364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2762364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt for (i = 0; i < prog->NumShaders; i++) { 2763849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (!prog->Shaders[i]->CompileStatus) { 2764849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->InfoLog = 2765849e18153cd91d812f694b806a84008498860bc3Eric Anholt talloc_asprintf_append(prog->InfoLog, 2766364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt "linking with uncompiled shader"); 2767849e18153cd91d812f694b806a84008498860bc3Eric Anholt prog->LinkStatus = GL_FALSE; 2768364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2769364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2770364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2771364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt prog->Varying = _mesa_new_parameter_list(); 2772364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL); 2773364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL); 2774364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2775849e18153cd91d812f694b806a84008498860bc3Eric Anholt if (prog->LinkStatus) { 27765d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, prog); 2777849e18153cd91d812f694b806a84008498860bc3Eric Anholt } 2778364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2779364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt if (prog->LinkStatus) { 27800df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (!ctx->Driver.LinkShader(ctx, prog)) { 2781d19eecef54384c163af27a470496ed885a5a271bEric Anholt prog->LinkStatus = GL_FALSE; 2782af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 2783af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt } 2784af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt 27852f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt set_uniform_initializers(ctx, prog); 27862f5bf20e44d509fa3afbe2cfbb9bb65347daea6aEric Anholt 2787af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (ctx->Shader.Flags & GLSL_DUMP) { 2788af2ef53a2701426d32382e861d8f238a449e9cd9Eric Anholt if (!prog->LinkStatus) { 27890df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d failed to link\n", prog->Name); 27900df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 27910df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt 27920df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt if (prog->InfoLog && prog->InfoLog[0] != 0) { 27930df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("GLSL shader program %d info log:\n", prog->Name); 27940df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt printf("%s\n", prog->InfoLog); 27950df61bdb669d03d9c25e49d5698f193deca3cf6dEric Anholt } 2796364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt } 2797364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} 2798364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt 2799364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */ 2800